Go Down

Topic: Guide to gyro and accelerometer with Arduino including Kalman filtering (Read 331909 times) previous topic - next topic

Okay good you got it working then ;)
Maybe it would be a good idea to open to fill in an issue: https://github.com/jrowberg/i2cdevlib/issues, so he can see there is an issue.

Can u suggest me with these data, that I initially received with my GY-521 module of MPU6050 IMU...
I'm not able to distinguish, whether why there's so much of drift...
The connections made are:
vcc=5v
GND=GND
SDA=SDA  //dedicated to arduino
SCL=SCL  //dedicated to arduino

These are the values, which I'm getting...

InvenSense MPU-6050
June 2012
WHO_AM_I : 68, error = 0
PWR_MGMT_2 : 0, error = 0

MPU-6050
Read accel, temp and gyro, error = 0
accel x,y,z: 1804, 1256, 15184
temperature: 27.329 degrees Celsius
gyro x,y,z : -4933, 3934, 490,

MPU-6050
Read accel, temp and gyro, error = 0
accel x,y,z: 5580, 1760, 14720
temperature: 27.047 degrees Celsius
gyro x,y,z : -4620, 3913, 428,

MPU-6050
Read accel, temp and gyro, error = 0
accel x,y,z: 3392, -84, 16828
temperature: 26.576 degrees Celsius
gyro x,y,z : -4559, 4073, 308,

MPU-6050
Read accel, temp and gyro, error = 0
accel x,y,z: 5672, 352, 10612
temperature: 26.765 degrees Celsius
gyro x,y,z : -4640, 3980, 364,

MPU-6050
Read accel, temp and gyro, error = 0
accel x,y,z: 4392, 1068, 13724
temperature: 27.000 degrees Celsius
gyro x,y,z : -4496, 3749, 380,
(for more, see the attachment...)

Please, suggest me ASAP!

@mit2sumit
Please connect AD0 to GND as well.
And please try to run my example code: https://github.com/TKJElectronics/Example-Sketch-for-IMU-including-Kalman-filter/tree/master/IMU6DOF/MPU6050, so I'm able to help you out.

Thanks for this info....
but, its too late and unuseful....
as, i got my sensor worked with the program u mentioned, and even completed my project...
though it was not much successful....

I still wonder, whether, why was those variations....even with connecting AD0 to gnd....
and later when i uploaded this code: https://github.com/TKJElectronics/Example-Sketch-for-IMU-including-Kalman-filter/tree/master/IMU6DOF/MPU6050 , by myself it worked.
I even mapped the value with the range of -20 to 20, so that the horizontal stationary value gives...0 output...

however, thanks for response,

Okay. I can't say what is wrong with the other code, but I know mine works.

romit26

Hey Lauszus,
What value would you give for sensitivity in the code if in the datasheet, the value is given in LSB/(o/s)?

Kashif


Hey Lauszus,
What value would you give for sensitivity in the code if in the datasheet, the value is given in LSB/(o/s)?


Use the same value as-is.
For example if the datasheet states "14.375 LSB/(ยบ/s)" then the sensitivity will be "14.375"


@romit26
As Kashif said. Simply just divide by that value. Take a look at the following code: https://github.com/TKJElectronics/Example-Sketch-for-IMU-including-Kalman-filter/blob/master/IMU6DOF/MPU6050/MPU6050.ino. But it's even necessary to do this with the accelerometer, as you can just pass in the values directly into atan2 - see: https://github.com/TKJElectronics/Example-Sketch-for-IMU-including-Kalman-filter/blob/master/IMU6DOF/MPU6050/MPU6050.ino#L89-L90.

Rhett

I'm new to the whole arduino programming scene so please pardon my ignorance if this is a dumb question.

I've got and Arduino Uno and a MPU6050 GY-521 that I'm trying to use for a project I'm working on.

I've gotten several different sketches to "work" so far including the one from here:

http://playground.arduino.cc/Main/MPU-6050

And 2 of Jeff Rowberg's ones from here:

https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/MPU6050

I have trouble tryin to figure out how to use the raw data from the playground code and I've noticed quite a bit of drift with the Rowberg "teapot sketch" so I'm trying to figure out how to use yours.

I keep getting these errors though when verifying your code from here:
https://github.com/TKJElectronics/Example-Sketch-for-IMU-including-Kalman-filter/blob/master/IMU6DOF/MPU6050/MPU6050.ino

sketch_oct20a.ino: In function 'void setup()':
sketch_oct20a:45: error: 'i2cWrite' was not declared in this scope
sketch_oct20a:46: error: 'i2cWrite' was not declared in this scope
sketch_oct20a:48: error: 'i2cRead' was not declared in this scope
sketch_oct20a:57: error: 'i2cRead' was not declared in this scope
sketch_oct20a.ino: In function 'void loop()':
sketch_oct20a:78: error: 'i2cRead' was not declared in this scope


I've placed the Kalman.h file in my library. Is there something I'm doing wrong? and why does your code seem so much shorter and simpler than the others?

@Rhett
You need to download the I2C.ino file as well: https://github.com/TKJElectronics/Example-Sketch-for-IMU-including-Kalman-filter/blob/master/IMU6DOF/MPU6050/I2C.ino. Simply just download the entiry repository - go to the front page: https://github.com/TKJElectronics/Example-Sketch-for-IMU-including-Kalman-filter and then notice the button labeled: "Download ZIP" and will download all you need.

Quote

and why does your code seem so much shorter and simpler than the others?

Because my is just a minimal code, but it should be plenty for most users. The code on the playground got all the different registers defined - I simply just hardcode them.

The code here: https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/MPU6050 is quite different as it uses the built-in DMP - you can read more about it here: http://www.i2cdevlib.com/devices/mpu6050#source.


ectar

Hi guys, please advise how to calculate Z angle within listed code below:

I've tried to play with

arcsin(2(q0q2-q1q3))

but what is q0q1q2q3 within the current given code snippet?



Code: [Select]
// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation
// is used in I2Cdev.h
#include "Wire.h"

// I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files
// for both classes must be in the include path of your project
#include "I2Cdev.h"
#include "MPU6050.h"

// class default I2C address is 0x68
// specific I2C addresses may be passed as a parameter here
// AD0 low = 0x68 (default for InvenSense evaluation board)
// AD0 high = 0x69
MPU6050 accelgyro;

int16_t ax, ay, az;
int16_t gx, gy, gz;

bool blinkState = false;

unsigned long timer;

double zeroValue[5] = {950, -400, 13500, -100, -500};

/* All the angles start at 180 degrees */
double gyroXangle = 180;
double gyroYangle = 180;

double compAngleX = 180;
double compAngleY = 180;


void setup() {

   // join I2C bus (I2Cdev library doesn't do this automatically)
   Wire.begin();
   Serial.begin(115200);

   // initialize device
   Serial.println("Initializing I2C devices...");
   accelgyro.initialize();

   // verify connection
   Serial.println("Testing device connections...");
   Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");


  timer = micros();
}

void loop() {
   // read raw accel/gyro measurements from device
   //accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);

   accelgyro.getRotation(&gx, &gy, &gz);
   
   double gyroXrate = -((gx-zeroValue[3])/131); //Change the sensitivity after your sensor
   gyroXangle += gyroXrate*((double)(micros()-timer)/1000000); // Without any filter
   
   double gyroYrate = ((gy-zeroValue[4])/131);
   gyroYangle += gyroYrate*((double)(micros()-timer)/1000000); // Without any filter
   
   
   ///////////////////////////
   //The acc X and Y angle///
   //////////////////////////
   accelgyro.getAcceleration(&ax, &ay, &az);
   
   double accXval = ax-zeroValue[0];
   double accZval = ay-zeroValue[2];    
   double accXangle = (atan2(accXval,accZval)+PI)*RAD_TO_DEG;
   
   double accYval = ay-zeroValue[1];
   accZval = ay-zeroValue[2];    
   double accYangle = (atan2(accYval,accZval)+PI)*RAD_TO_DEG;
   
   //////////////////////////
   //////////////////////////
   
   compAngleX = (0.93*(compAngleX+(gyroXrate*(double)(micros()-timer)/1000000)))+(0.07*accXangle);
   compAngleY = (0.93*(compAngleY+(gyroYrate*(double)(micros()-timer)/1000000)))+(0.07*accYangle);

   timer = micros();
   
   
 Serial.print(compAngleX);Serial.print("\t");  
 Serial.print(compAngleY); Serial.print("\t");
 //Serial.print(timer); Serial.print("\t");
 Serial.print("\n");
   
  delay(10);


   
}


Is called quaternions. You can find more information about it here: http://www.x-io.co.uk/quaternions/. Wikipedia is a good resource as well: http://en.wikipedia.org/wiki/Quaternion.

michinyon

What application are you trying to implement ? 

The segway type scheme is a one dimensional implementation.

General flight control is a three dimensional implementation.    Quaternions is the best way to go for this.

You program seems to be a two dimensional implementation,   what is that ?     I am not sure how quaternions would be useful there.

ectar


You program seems to be a two dimensional implementation,   what is that ?     I am not sure how quaternions would be useful there.

This is piece of code from original post, this is not my program, I've tried it, and yes, it works for 2D, and I using it for 2D stabilization. I want to have 3D stabilization, so I want to handle z axis as well, just want to add Z axis to listed code.
Lets forget about arcsin(2(q0q2-q1q3)) , this was something I did not know what I was talking about....

Question is simple: So what would be formula to convert Z values from accelerometer output to get angle, similar to
Code: [Select]
double accYangle = (atan2(accYval,accZval)+PI)*RAD_TO_DEG;
...in this particular piece of code??


It is not possible to calculate the rotation along the z-axis (yaw) using the accelerometer. More information can be found at the following comment on my blog: http://blog.tkjelectronics.dk/2012/09/a-practical-approach-to-kalman-filter-and-how-to-implement-it/comment-page-3/#comment-431999.

Instead you should use the code that you used snippets of, which I believe is this one: https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/MPU6050, right?

But to get a precise yaw estimate you should use a magnetometer as well.

Go Up