In the previous post I described how to setup raspberry pi for connection with the IMU.

Now it is time to see how to read some data from the sensor.

First yuo need sw that manage the i2c interface.there are many examples.You can find one called adafruit_i2c.py on github.

Then it is necessary to have the code specific for the sensor,in my case a MPU6050.

I tryied for some days to build my own code, but I encountered problems related to unconsistent results: even if I did not move the sensor, the returned results were always different. I suspect it was a problem on how I formatted the values.

Finally, Thanks to the great job done by Hove in his blog, I used his code and I’m now able to collect correct data from the sensor.

I did some minor modification and prepare this IMU_test files.

So I started some preliminary tests to verify which is the sensor behaviour.

I fixed the sensor on a bar ,horizontally, than turned the bar by a known angle ( 13 degrees,measured with my smartphone level) then move back to horizontal.

I recorded on a file the sensor data : acceleration along axis (from ACCelerometer) and rotational speed (from GYRO scope). On excel sheet I calculated the angle around x respect the ACC and respect the GYRO:

- rx ACC=DEGREES(ATAN2(accZ+9.8;accY))
- rx(i) GYRO=wx(i) *dt+wx(i-1)

Below you can see the graph.

I underline in the picture the 2 tipical problems on the IMU :

- the Gyro drift (you can see an angle of 1 degree while it reality it was 0)
- the Accelerometer sensibility to noise.

So next development step is to filter/reduce this 2 problems by combining the 2 sensors results.

### Like this:

Like Loading...

*Related*

HoveHi Oscar – that looks like a great set of readings – my accelerometer was so full of noise I abandoned using it for the moment. Does your code use any different settings to mine (i.e the accelerometer range, or DLPF settings which might explain the difference). I’m looking forward to see how you merge the two sets of values too – again I’ve not bothered yet since again because my accelerometer was just swamped by noise!

Cheers!

solenerotechPost authorHi hove. No setting changes respect your code. Take in consideration that those values are stored on a test session: no motor was running.the only differece i can see maybe is related how you calculate the angles from accel. data.

Im now looking to see that happen if i aply a low pass filter and that happen using the kalman filter also.

HoveInterested to hear your Kalman filter results – I looked at it for a few minutes once, but it was too hard for me! I hadn’t for enough to understand what it really did. I’ve got a little more of an idea now, so very interested to know how it works for you.

Good luck!

solenerotechPost authorI’ve not used kaiman filter yet.

MahimHi..I am working on IMU modules for gait analysis. I was going through online articles for angle estimation and came across your article. Thank you!!

But I am stuck at a point and cannot proceed further…. I have obtained angles (Arduino platform) from the GY80 module, using both ADXL345 and Gyroscope L3G4200D. Although the output looks fair enough, the angles of the two sensors are not in sync. I would be grateful if I could get help of any sort.

The formulae I used:

//Accelerometer angles

angle_x= (atan2(xg, sqrt(yg*yg + zg*zg))*57.2957795);

angle_y= (atan2(yg, sqrt(xg*xg + zg*zg))*57.2957795);

angle_z= (atan2(sqrt(xg*xg + yg*yg), zg)*57.2957795);

//Gyroscope angles

angle_gz += gz*((double)(micros()-time1)/1000000);, with time1=micros() placed at the end of setup function and reset at the end of the loop function.

Also let me know if I should paste the complete code.

solenerotechPost authorHi Mahim,

if you put the sensor oriented in a known position ( for example flat on your table), which values yuo can get from gyro and from Accel?

Then if you put it vertically? which values?

MahimI took an average of 20 readings.

When I place the sensor flat (Z axis),

The accelerometer reads:

Raw values X= -10.85, Y=-5.2, Z=255.95

G values X= -0.041, Y=-0.0205, Z=1

Angle X=-1.164, Y=2.2427, Z=2.6945

The Gyro readings are :

Raw values X= 24.05, Y=-16.25, Z=-35.55

Angular velocity (dps) X=0.2105, Y=-0.141, Z=-0.311

Angle X=-0.228, Y=-0.152, Z=-0.362

In the Y axis (placed vertical)

The accelerometer reads:

Raw values X= -0.6, Y=267.5, Z=0.65

G values X= 0, Y=1.0465, Z=0.65

Angle X=89.7235, Y=0.1345, Z=89.866

The Gyro readings are :

Raw values X= 20.35, Y=-14.45, Z=-29.65

Angular velocity (dps) X=0.177, Y=-0.126, Z=-0.2585

Angle X=1.445, Y=-0.118, Z=-0.2695

solenerotechPost authorHi Mahim, the Accel values seems correct.

So you should concentrate on Gyro.

Are you sure than this (double)(micros()-time1)/1000000) return a time in second?

Since the Angle from Gyro is obtained by the integration over time, it is difficult to understand what happen when you move the sensor from flat to rotated.

I can suggest you to store data from Acc and Gyro (Raw and angular value and angle) in a text file,open it in excel and then try to reproduce the calculation on it.

This helped me to understand what was going on.

An additional comment: the value you got with sensor flat (Angle X=-1.164, Y=2.2427, Z=2.6945) , they should be used as calibration value of the sensor, so in your calculation you should subtract them:

angle_x= (atan2(xg, sqrt(yg*yg + zg*zg))*57.2957795)-(-1.164);

and so on

Finally use the complementary filter to obtain the best angles.

MahimThanks a lot for the response!!!

I finally got the angles working and the values seem similar

MahimAbout the calibration part…. I have calibrated gyro values to start from zero each time the code runs. But I am unable to calibrate the Accr values to initialize current value to zero. I am not sure if I have explained it right, but please help me with this.

solenerotechPost authorHi Mahim,

I wouldn’t suggest you to calibrate the sensor at each start.

In order to calibrate it properly you need a reference table where you are sure to place the sensor in a flat position.

regarding the Accel,it is affected to disturbance, so it can have some deviation in the value.

Suggest to use the complementary filter to merge info from acc and gyro in order to get a valuable result.

MThank you! Will add Complementary filter now.

MThank you!

The Complementary filter gives better results.

But the values are correct only when I place it flat and move the sensor in a particular direction (ie., along the X axis).

Since I may require to place the sensor in different orientations, the gyroscope gives better results, whereas the accelerometer points the tilt angle with respect to gravity. Please tell me how to adjust the angle offset such that the accelerometer and gyro values become comparable

solenerotechPost authorThe accelerometer gives a value related to the world (absolute value). The gyro gives a value relative to its own reference system

MahimAnother problem came up. I don’t know how the gyro drift has suddenly increased..(It was minimal before and now the value constantly increases and when i return to zero position, there is an offset of 22 degrees). I don’t remember making any chances to the code. The same happens with another sensor of the same type. Please help, where did I go wrong??/

MThank you!

The Complementary filter gives better results.

But the values are correct only when I place it flat and move the sensor in a particular direction (ie., along the X axis).

Since I may require to place the sensor in different orientations, the gyroscope gives better results, whereas the accelerometer points the tilt angle with respect to gravity. Please tell me how to adjust the angle offset such that the accelerometer and gyro values become comparable

solenerotechPost authorHi,

what you can do is to use the angles from the complementary filter as the base for the integration of the gyro:

new_gyro_angle = old_conp_fil_angle + new_gyro_speed *dt

In this way you keep under control the drift of the gyro.

In my def getAngleGyro(self, dt) I use self.roll (it is the result calculated in the preview cycle by complementary filter):

`def getAngleGyro(self, dt):`

"return the angle calculated on the gyro"

self.roll_g = self.roll + self.r_rate * dt

self.pitch_g = self.pitch + self.p_rate * dt

self.yaw_g = self.yaw + self.y_rate * dt