Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 10 of 10

Thread: Audio library with a digital I2C accelerometer

  1. #1
    Junior Member
    Join Date
    Jan 2019
    Posts
    12

    Audio library with a digital I2C accelerometer

    Hi all,

    I am developing a small vibration measurement system for my Master's degree project and I am a little bit stuck here.

    I need to configure the Teensy3.2 to work as a microphone in order to be recognized by an Android mobile phone (Serial comunication is not an option due to the low speed), and perform in the Android device the FFT.

    If I change the USB type to "Audio", the Serial port prints information fast enough to take that info and process it into Matlab to get the FFT representation and the RMS speed. I have tested it with a calibrator at 159HZ a driller at 50Hz and a fan at 33 Hz and works well in frequency domain and providing me the Speed RMS values, for a low cost system. This make me think that, for this small purposes, the ADXL345 + Teensy 3.2 is what I need for this project.

    In order to send the accelerometer values trough USB as fast as I can, I started changing the USB type to "AUDIO" as I said previously, but I was not able to recognize that port neither in matlab or android (this makes me to take values after 1 second manually), so I started messing around with the Audio library WITHOUT the Audio shield.

    At this point, I has been able to send the Z axis value to Audacity, as if Teensy was a microphone, but I don't think that I have achieved the best results because the frequency appears to be 172 Hz instead of 159Hz.

    My question is: Is it possible, in any way an withoud adding the audio shield, configure the Audio library to read the ADXL345 accelerometer, which is an I2C device and not an analog one, and send axis values to the PC/ANDROID device?

    Thanks!

  2. #2
    Senior Member
    Join Date
    Feb 2017
    Posts
    272
    The Audio library samples at ~44.1 KS/s. According to the datasheet, the ADXL345 has a maximum sample rate of 3.2 KS/s. And to even achieve that you need SPI not I2C. Doesn’t really seem like a fit.

  3. #3
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    5,531
    Serial uses the full USB bandwidth. If the Android Phone supports it...PC drivers have no Problem with it. Using Audio is a strange Idea..

  4. #4
    Junior Member
    Join Date
    Jan 2019
    Posts
    12
    Thank you all for your answers.

    The point is that if I use serial communication, The serial port seems to freeze if I don't add a delay after read the ADXL345 registers but, if I do that, the sampling rate decreases a lot (Does anyone know how to solve this?).

    I come up with the Audio library because if I change the USB type to Audio, I can get the values form the ADXL345 fast enough to store them and then process them in matlab. But, in order to do it, I have to take the values manually from the serial plot.

    Thanks!

  5. #5
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    5,531
    The problem is in line 814.

  6. #6
    Junior Member
    Join Date
    Jan 2019
    Posts
    12
    Sorry? Are you talking about the Audio library?

  7. #7
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    5,531
    We can't help if we don't see your code.. line 814 was a guess

    Try to use buffers, the faster I2C_t3 library and a high I2C speed.

  8. #8
    Junior Member
    Join Date
    Jan 2019
    Posts
    12
    Hahaha! Thanks for your suggestions, my actual code, which takes the data and sends it is the following one:

    Code:
    #include <Wire.h>
    #include "arduinoFFT.h"
    arduinoFFT FFT = arduinoFFT();
    
    const int DEVICE_ADDRESS = (0x53); 
    byte _buff[6];
    
    char POWER_CTL = 0x2D;
    char DATA_FORMAT = 0x31;
    char DATA_RATE = 0X2C;
    char DATAX0 = 0x32;   //X-Axis Data 0
    char DATAX1 = 0x33;   //X-Axis Data 1
    char DATAY0 = 0x34;   //Y-Axis Data 0
    char DATAY1 = 0x35;   //Y-Axis Data 1
    char DATAZ0 = 0x36;   //Z-Axis Data 0
    char DATAZ1 = 0x37;   //Z-Axis Data 1
    uint8_t numBytesToRead = 6;
    
    //**********G force compensation**************//
    
    double alphaX = 0.95; 
    double alphaY = 0.95;
    double alphaZ = 0.99;
    double gx,gy,gz;
    double acc_z_final;
    double acc_y_final;
    double acc_x_final;
    
    void writeTo(int device, byte address, byte val) {
      Wire.beginTransmission(device);
      Wire.write(address);
      Wire.write(val);
      Wire.endTransmission(); 
    }
    
    //Funcion auxiliar de lectura
    void readFrom(int device, byte address, int num, byte _buff[]) {
      Wire.beginTransmission(device);
      Wire.write(address);
      Wire.endTransmission();
     
      Wire.beginTransmission(device);
      Wire.requestFrom(device, num);
     
      int i = 0;
      while(Wire.available())
      { 
        _buff[i] = Wire.read();
        i++;
      }
      Wire.endTransmission();
    }
    
    void setup()
    {
      Serial.begin(115200);
    
      //descomentar estas dos lineas para teensy. comentar para arduino
      analogReadAveraging(32);
      analogReadResolution(10);
      
      Wire.begin();  
      writeTo(DEVICE_ADDRESS, DATA_FORMAT, 0x02); 
      writeTo(DEVICE_ADDRESS, POWER_CTL, 0x08);  
      writeTo(DEVICE_ADDRESS, DATA_RATE, 0x0D); 
    
    void loop() {
    
      time_since_last_reset = millis();
      while((millis() - time_since_last_reset) < interval_one){
     uint8_t numBytesToRead = 6;
             readFrom(DEVICE_ADDRESS, DATAX0, numBytesToRead, _buff);
              //Leer los valores del registro y convertir a int (Cada eje tiene 10 bits, en 2 Bytes LSB)
            int16_t x = (((int)_buff[1]) << 8) | _buff[0];
                    
            int16_t y = (((int)_buff[3]) << 8) | _buff[2];
           
            int16_t z = (((int)_buff[5]) << 8) | _buff[4];
            //delay(1);
            //Serial.println(z);
    
            gx = alphaX * gx + (1 - alphaX)*x;
            gy = alphaY * gy + (1 - alphaY)*y;
            gz = alphaZ * gz + (1 - alphaZ)*z;
    //
            //acc_z_final = (z - gz) * 0.0039 *9.81; //FULL_RES
            acc_z_final = (z - gz) * 0.0156 *9.81;  //8G normal res
    //        acc_x_final = (x - gx) * 0.0039* 9.81;  //FULL_RES
            acc_x_final = (x - gx) * 0.0156* 9.81;    //8G normal res
    //        acc_y_final = (y - gy) * 0.0039 *9.81;
            acc_y_final = (y - gy) * 0.0156 *9.81;    //8G normal res
    //
            Serial.print(acc_x_final);
            Serial.print("\t");
            Serial.print(acc_y_final);
            Serial.print("\t");
            Serial.println(acc_z_final);
            }
    
    
      
    }
    }
    Also, I would like to ask if this "noise" is normal for this sensor when is not measuring anything.

    Click image for larger version. 

Name:	Captura.jpg 
Views:	10 
Size:	42.7 KB 
ID:	15727

    Anyway, I would be very interested in how to use buffers to send data As fast As I can.
    I have the teensy configured as Audio output and the clock is at 96Mhz.

    Thanks!

  9. #9
    Senior Member
    Join Date
    Feb 2017
    Posts
    272
    So, what data transfer rate are you getting now and what is limiting it?

    Did you trying getting the data out of the ADXL345 as fast as you possibly can without worrying about trying to transfer it anywhere? What kind of sample rate did you achieve?

  10. #10
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    5,531
    You know using double is very slow?
    Then, you're sending them as ascii ..

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •