Audio library with a digital I2C accelerometer

Status
Not open for further replies.

alexan

Member
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!
 
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.
 
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..
 
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!
 
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.
 
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.

Captura.jpg

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!
 
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?
 
Status
Not open for further replies.
Back
Top