Tutorial: How to read data from IMU

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.

IMU_test1

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.

IMU

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.

17 thoughts on “Tutorial: How to read data from IMU

  1. Hove

    Hi 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!

    Reply
    1. solenerotech Post author

      Hi 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.

      Reply
      1. Hove

        Interested 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!

  2. Mahim

    Hi..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.

    Reply
    1. solenerotech Post author

      Hi 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?

      Reply
      1. Mahim

        I 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

      2. solenerotech Post author

        Hi 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.

  3. Mahim

    About 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.

    Reply
    1. solenerotech Post author

      Hi 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.

      Reply
      1. M

        Thank 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

      2. solenerotech Post author

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

      3. Mahim

        Another 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??/

  4. M

    Thank 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

    Reply
    1. solenerotech Post author

      Hi,
      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

      Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s