Pages

Showing posts with label Accelerometer. Show all posts
Showing posts with label Accelerometer. Show all posts

Sunday, 20 July 2014

Getting Roll, Pitch and Yaw from MPU-6050

Part 3 in our quest for Accelerometer and gyroscope values. In the previous entry we got the acceleration values in the form of G's and also the linear velocity in terms of degrees/s however these values aren't much use to us. Wouldn't it be better if we had roll,pitch and yaw and also angular position instead? Well that's what I am going to try to achieve in this post.

Roll, Pitch and Yaw

enter image description here
For those that don't know what these are look at the diagram above, it shows that the roll is the rotation about the Y axis, the pitch is the rotation about the X axis and the yaw is the rotation about the Z axis.

How do we convert gravity into these values?

Well I am not going to go into the theory of how these values convert to roll and pitch because some nice mathematicians over on stackoverflow have done that for us.
The formulas to convert the acceleration values to pitch and roll are as follows.
Roll = atan2(Y, Z) * 180/PI;
Pitch = atan2(X, sqrt(Y*Y + Z*Z)) * 180/PI;
 We use atan2 as it works over 4 quadrants, if we used atan then we would have problems with angles over 90 degrees. Don't worry about Yaw for now as we can't determine that using just the accelerometer, this is intuitive if you think about how Yaw is rotation about the Z axis. We will just read a constant 1G in the Z axis no matter how the accelerometer is rotated, We will need to augment our acceleration values with the Gyroscope ones to get the full picture which we will do in a later entry.

I have rewritten the PSoC code to respond to an interrupt on the UART. Whenever the PSoC receives the character 'a' it will respond with the acceleration values in comma seperated form of X,Y,Z.

So if you send 'a' it will give you back something like "0.1, 0.2, 1"  < these are all abitrary but something around 0 for X, 0 for Y and 1 for Z is expected if the MPU6050 is on a flat surface.

The new PSoC code can be found on my Github under "GettingG'sWithInterrupt" I have left the conversion to Roll and Pitch in the code but kept it commented out as I will be doing the conversion from LabVIEW but just uncomment it if you want the conversion on the PSoC.

Visualising our values

Now this part is up to you are the PSoC code will work on any platform/language aslong as you poll it with the character 'a' at 9600 Baud. I personally used LabVIEW to do the polling as it has some nice inbuilt dials and bar graphs as can be seen in the screenshot below.


 I have uploaded a Windows exe on my Github under /Examples/LabVIEW/Dials/EXE//MPU6050dials.exe of the Labview progam, please note you will have to install the LabVIEW runtime engine to run the EXE

I have also added the vi if you want to have a go at changing it.

Instructions for use
Change COM port to whatever your device is connected to, click write then read, you should see the text box fill up with values and you should see the LED blinking on the PSoC pioneer. If not you probably have a problem with your serial port connections.

In the next entry I will look at getting the Gyroscope values off the PSoC onto LabVIEW dials and then move onto combining the values and filtering them to get accurate non noisy values. You will notice at the minute the values jump around a lot, we need to get rid of this.


Friday, 18 July 2014

Processing data from MPU-6050

In the previous entry we got the MPU-6050 talking to the PSoC 4 over I2C and had it giving us raw values on a serial screen. Now let us take it further and see if we can turn those values into angles and such.

Finding out the offsets

First of all we need to work out the offset errors and remove them from our data. Offsets are caused by a number of factors such as mechanical assembly, mounting, package damage and temperature fluctuations. So we need to work out what the offsets of our chip are and then remove them before processing the data.

I am getting all of my methods and theory from this application note from Freescale.

So what we need to do is to place the sensor level on a table (use a spirit level or something to make sure it is actually level), then we need to:

  1. Measure the average acceleration/angle in the X, Y and Z axis over 10-20 samples
  2. These values should be 0G in the X and Y axis and will be 1G in the Z axis 
  3. Anything over 0G in the X and Y and 1G in Z will be our offsets
So after keeping the device level and leaving a large (0.5 second) delay in between each sample (to let temperature stabilise) my average values are as shown below.

Test finished, offset values are shown below

AXoff:435, AYoff:-352, AZoff:15236 || GXoff:74, GYoff:131, GZoff:-126,

Don't worry if yours were different we are going to incorporate the calibration into our future code so that the device can auto zero regularly.

So from now on when we measure we will need to remove those offsets from our values before we process them.

The offset testing program is available on my Github under "CalibrateOffsets"

Getting some G's

Now we know what our offsets are but we don't know what they mean in the form of angles and G's so lets do some scaling and conversion to get the real values.

Understanding the scaling

As Jeff Rowberg said in his own i2cdevlib forums 
"The accelerometer and gyroscope measurements are explained in the MPU-6050 datasheet in the GYRO_CONFIG and ACCEL_CONFIG register descriptions (sections 4.4 and 4.5 on pages 14 and 15). The scale of each depends on the sensitivity settings chosen, which can be one of +/- 2, 4, 8, or 16g for the accelerometer and one of +/- 250, 500, 1000, or 2000 deg/sec for the gyroscope. The accelerometer produces data in units of acceleration (distance over time2), and the gyroscope produces data in units of rotational velocity (rotation distance over time). The output scale for any setting is [-32768, +32767] for each of the six axes. The default setting in the I2Cdevlib class is +/- 2g for the accel and +/- 250 deg/sec for the gyro. If the device is perfectly level and not moving, then:
  • X/Y accel axes should read 0
  • Z accel axis should read 1g, which is +16384 at a sensitivity of 2g
  • X/Y/Z gyro axes should read 0
In reality, the accel axes won't read exactly 0 since it is difficult to be perfectly level and there is some noise/error, and the gyros will also not read exactly 0 for the same reason (noise/error)."
 So first of all we need to know the sensitivity of our sensor. The default is +/-2G and +/-250deg/sec but where do we confirm we are running the default settings and how do we change the values.

If you look in mpu6050.c at line 66 you will find the function

Here you can see that we are running at the default selection of 2G for the accelerometer and 250 for the gyro, If you look at the defines in mpu6050.h you can change these to whatever you want.

So we know we are running at a sensitivity of +/-2G and +/- 250deg/s but how do our values correspond to those accelerations/angles.

These are both straight line graphs and we can work out from them that for 1G we will read 16384 and for 1degree/sec we will read 131.07 (Although the .07 will get ignore due to binary) these values were just worked out by drawing the straight line graph with 2G at 32767 and -2G at -32768 and 250/-250 at the same values.

So now we know our sensitivity values (16384 and 131.07) we just need to minus the offsets from our values and then devide by the sensitivity as it explains in the freescale application note. 

These will work fine for the X and Y values but as the Z was recorded at 1G and not 0 we will need to minus off 1G (16384) before we divide by our sensitivity. This is explained in the freescale note.

I have written a project which calculates the values in G's and angles and it can be found on my GitHub under "GetG's"

Thursday, 17 July 2014

Getting started with MPU-6050 IMU

It has been a while but I have been struggling to get this thing working and hopefully my instructions might help someone else out there.

So the MPU-6050 is an IMU unit which has an accelerometer and a gyroscope built into it and communicates over I2C, it also has some complex processor in there too called a DMP which filters and processes all the results but I haven't got that working yet - Maybe as this blog develops I will post about how I got it up and running but let us just concentrate on the basics for now.

I am using the GY-521 breakout board which I bought off eBay for a couple of quid.


Wiring

The board communicates over I2C and it has internal pull up resistors built in so all you have to do is connect the following. Note that the SDA and SCL lines will be specific to your microcontroller I am using a PSoC 4 Pioneer board but I also tested it on an Arduino UNO)

  • VCC - 5V (I have not tested 3.3V)
  • GND - 0V
  • SDA - SDA on your microcontroller (P0[5] on PSoC 4)
  • SCL - SCL on your microcontroller (P0[4] on PSoC 4)

Here it is connected to the PSoC 4

Software

Here is where things get interesting because it is very easy to get communicating and get the raw values out of the sensor but actually understanding those values, filtering them and getting useful data from them is a different story.

Let us just start though by seeing if we can get some values out of the chip.

Reading raw data

Jeff Rowberg has created a nice library for the MPU-6050 on his Github it is an extensive I2C library for many other development boards and is definitely worth checking out. I am going to be using it in our project except as I am using a PSoC and not an Arduino or a MSP430 I will be using an edited version of the i2cdevlib designed to work with the PSoC 4 Pioneer which a kind individual named Hernán Sánchez released on the PSoC forums.

I have altered his project to display the values in a more useful way and also to move a lot of the extraneous code out to another source file, I think this will help you understand more what is happening.

You can find my getting started code on my Github under Examples "Getting Started"

Just connect a serial monitor (PuTTY) to the relevant port and you should see the connection being made and the raw values being printed to the screen.

In the next post I am going to look at turning the values into angles and accelerations but for now, keep watching the skies.