Go Down

Topic: MPU 6050 - Sampling Time (Read 214 times) previous topic - next topic

Dave_7

Feb 21, 2019, 10:55 pm Last Edit: Feb 21, 2019, 10:58 pm by Dave_7
Hi there, I've been looking for a solution for a long time about the following topic, but still even though there are a lot of discussions about it, I haven't found a clear answer. (is the first time I've ever used Arduino)

PROBLEM:

I have two MPU6050 connected to Arduino Due. My goal is only to read the accelerations along the Z axis from them, namely Az_1 and Az_2 and in particular I want the data to be collected with a sampling time of 200 Hz. Therefore what I would like to see in the serial monitor (actually in a txt file, but I managed this problem using the program 'CoolTerm' for the serial communication) are two columns of data, one for Az_1 and one for Az_2, and each measurement correspond to the same time instant.

Therefore, for example, if I perform the data collection for 5 seconds, since the sample time is 200 Hz, I expect to see 1000 samples,(thus each sample equally spaced by 5 milliseconds )

(I'm gonna put these two sensors in a car to measure the z acceleration of the wheel and the z acceleration od the body of the car, and then I'm gonna study these data offline)

QUESTIONS:

1) How can I set the Sampling time for the two accelerometers equal to 200 Hz?
    (I tried to use the register 25 of MPU6050, to set the Sample Rate but actually I'm not able to see in the Monitor the expected number of data)

      1.A) Assuming I set the Sample rate properly by means of the register 25, the reason why I'm not able      to see the expected number of data in the monitor, is due to the Boud rate too slow or should I put some delay in the code?

 
2)Since I'm using two sensors attached to Arduino Due, in order to don't loose data and to collect data corresponding to the same time instant, should I use a FIFO Buffer. ?
 (I'm asking this because I don't know if without a FIFO buffer, while Arduino is reading one data from sensor 1 ,he is missing the the data collected from the sensor 2, so when Arduino is free again he goes to the register of sensor 2 but it takes a value of acceleration corresponding to a different time instant.).

In the Following the code:

Code: [Select]


#include <Wire.h>

long  accelZ, accelZ_2;

float  gForceZ, gForceZ_2;


void setup() {

  Serial.begin(115200);

  Wire.begin();

  setupMPU();
}


void loop() {
  recordAccelRegisters();

  recordAccelRegisters_2();

  printData();

  delay(5);
}

void setupMPU(){
 
Wire.beginTransmission(0b1101000); //This is the I2C address of the MPU (b1101000/b1101001 for AC0 low/high datasheet sec. 9.2) . 0x68
 
 Wire.write(0x6B); //Accessing the register 6B - Power Management (Sec. 4.28)
 
 Wire.write(0b00000000); //Setting SLEEP register to 0. (Required; see Note on p. 9)
 
Wire.endTransmission(); 
 

 
Wire.beginTransmission(0b1101001); // adress of the second sensor attached to the I2C BUS (0x69)
 
 Wire.write(0x6B);
 
 Wire.write(0b00000000);
 
Wire.endTransmission(); 
 

 
 
Wire.beginTransmission(0b1101000); //I2C address of the MPU

  Wire.write(0x1C); //Accessing the register 1C - Accelerometer Configuration (Sec. 4.5)

  Wire.write(0b00001000); //Setting the accel to +/- 4g range

  Wire.endTransmission();

  Wire.beginTransmission(0b1101001); //adress of the second sensor linked to the I2C Bus

  Wire.write(0x1C);

  Wire.write(0b00001000);

  Wire.endTransmission();

   //set register 26 to zero to disable dlpf in order to have the gyro output rate at 8khz

 
Wire.beginTransmission(0b1101000);

  Wire.write(0x1A);

  Wire.write(0b00000000);

  Wire.endTransmission();


  Wire.beginTransmission(0b1101001);

  Wire.write(0x1A);

  Wire.write(0b00000000);

  Wire.endTransmission();

    //set the sampling time (page 11 datashet MPU6050 Register Map)

  Wire.beginTransmission(0b1101000);

  Wire.write(0x19);

  Wire.write(0b101000);  //I've wirtten on the register 25 the Value 40 in binary beccasse the sample rate is obtained by dividing 8000 Hz (gyroscope output rate) by SMPLRT_DIV that in this case o SMPLRT_DIV = 40 in order to havel sample time of 200Hz

 Wire.endTransmission();


  Wire.beginTransmission(0b1101001); %same thing for the second accelerometer

  Wire.write(0x19);

  Wire.write(0b101000);

  Wire.endTransmission();
 
}
 


void recordAccelRegisters() {
  Wire.beginTransmission(0b1101000); //I2C address of the MPU
  Wire.write(0x3F); //Starting register for Accel Readings
  Wire.endTransmission();
  Wire.requestFrom(0b1101000,2); //Request Accel Registers (3B - 40) c'era, 6 prima
  while(Wire.available() < 2);
 
  accelZ = Wire.read()<<8|Wire.read(); //Store last two bytes into accelZ . (reading register 0x3F and 0x4O ____two registers are read and stored in the same variable9
  processAccelData();
}


void recordAccelRegisters_2() {
  Wire.beginTransmission(0b1101001); //I2C address of the MPU
  Wire.write(0x3F); //Starting register for Accel Readings
  Wire.endTransmission();
  Wire.requestFrom(0b1101001,2); //Request Accel Registers (3B - 40) c'era ,6
  while(Wire.available() < 2);
 
  accelZ_2 = Wire.read()<<8|Wire.read(); //Store last two bytes into accelZ
  processAccelData_2();
}

void processAccelData(){
                                  //to convert the measurements in g in the range + , - 4g
gForceZ = accelZ /8192.0;

}


void processAccelData_2(){
                                 
 
  gForceZ_2 = (accelZ_2) /8192.0;
 
}


void printData() {
 
  Serial.println(), Serial.print(gForceZ), Serial.print(','), Serial.println(gForceZ_2);  //il primo valore è dell accelerometro1 quello col cavi giallo e arancio, il seconodo valore è accelerometr2 con cavi bianco e grigio
 
}



































I hope someone of you already addressed this problem, thank you very much in advance for your answers and time.



MorganS

200Hz is a lot of data. In your tests, are you using the native port, which has almost unlimited speed? A regular serial port won't be able to send all the text you expect.

That's a complicated chip to use for just one acceleration axis. I have a similar system using ADXL345 accelerometers. I set their sample rate ahead of time and then just hit "start" simultaneously. (This is easy to do with SPI sensors, impossible with I2C sensors.) But I don't expect the ADXL's to stay in sync for long. My measurement runs are only 30 seconds long. The timing devices inside the ADXL's aren't very accurate.
"The problem is in the code you didn't post."

ard_newbie

#2
Feb 22, 2019, 08:11 am Last Edit: Feb 22, 2019, 08:53 am by ard_newbie
1) How can I set the Sampling time for the two accelerometers equal to 200 Hz?
Use a Timer Counter to trigger accelerometers readings (TC_lib from antodom or search for Timer Counter programming in the DUE sub forum). A Timer Counter calls its interrupt handler every 200 Hz, in the Handler you read and log the 2 accelerometers, you set a Flag to inform the loop() that there is something to print (don't print inside the handler).

Note: The accelerometer output rate is 1kHz. (see MPU6050 datasheet)

2)Since I'm using two sensors attached to Arduino Due, in order to don't loose data and to collect data corresponding to the same time instant, should I use a FIFO Buffer. ?
You won't read the 2 accelerometers at the exact same instant, but one after the other. Select 250000 baud rather than the slow 9600 and using printf() is more convenient than a cascade of Serial.println().

E.g.: printf("gForceZ = %d, gForceZ_2 = %d\n", gForceZ, gForceZ_2);
Note 1: Printf() don't work for floats, only signed or unsigned.
Note 2: Maybe you can print only after the 5 seconds of data collection, in such a case fill a buffer after each reading.
Note 3: In a car, the I2C bus will have to deal with EMI. Adding 120 Ohms resistors in serie on the SDA line, idem for the SCL line, should help.

This thread might help you:

https://forum.arduino.cc/index.php?topic=545257.0

Go Up