Instructables

Use an Accelerometer and Gyroscope with Arduino

Picture of Use an Accelerometer and Gyroscope with Arduino
I recently bought a combination 3 axis accelerometer and 2 axis gyroscope from Sparkfun and I wanted to post some of the code I used to get it up and running.  I'm planning on using it in an Arduino based MIDI controller that I'll be posting soon (video below, code at very bottom of page), I want to use the analog controls from the tilt and rotational movement to control the outgoing MIDI.  Accelerometers and gyroscopes are also used frequently on robots for balancing and other types of feedback.


First a bit of basic information:
Gyroscopes measure rotational movement in degrees per second.  They will not directly tell you information about tilt, only movement about an axis.  Accelerometers measure acceleration, you can easily use this information to calculate the tilt of an object by subtracting the current accelerometer data from a value that you know to be zero tilt.

For this project I used the 5 Degrees of Freedom IDG500/ADXL335 board from Sparkfun.  I like this board because it outputs the accelerometer and gyroscope data as 5 analog voltages which can easily be read using five of the Arduino's analog input pins.  Some accelerometers and gyroscopes output data digitally by encoding it in a pulse-width modulated (PWM) signal.  If you are short on analog input pins on your Arduino, it may be a good idea to use one of these digital chips, but the analog chips are nice because they require minimal effort to get working.

Parts list:
IMU Analog Combo Board - 5 Degrees of Freedom IDG500/ADXL335 Sparkfun SEN-11072
Arduino Uno Sparkfun DEV-11021
male header pins Sparkfun PRT-00116
22 gauge wire
breadboard

Steps:

Solder header pins to the accelerometer/gyro board.  On a breadboard connect Arduino 5V to "RAW" pin, Arduino ground to ground, then connect the pin labeled X-Acc to A0, Y-Acc to A1, and Z-Acc to A2

The code below will display the X,Y, and Z acceleration fro your board int he serial monitor (ctrl/command + shift + M).  I tried to center the values around a zero point by introducing the variable "zero" in my code and then subtracting all my incoming data from this number.  This way when the board is held parallel to the ground, the X and Y acceleration both read 0.  When the board is tipped to positive X it will display a positive number, and when it is tipped to negative X it will display a negative number (same goes for Y).  This accelerometer code allows you to determine the orientation of your board in 3D space.

Sometimes you may want to use a gyroscope to get rotational information about your board that cannot be calculated with an accelerometer.  On a breadboard connect the pin labeled Vref to A0, yRate to A1, xRate to A2, y4.5 to A3, and x4.5 to A4.
You may be wondering about the difference between the X/YRate and X/Y4.5 outputs.  Gyroscopes measure degrees per second, this gyroscope outputs a voltage based on the degrees of movement per second so we can say that it is outputting volts per degrees per second (V/°/s).  From the datasheet of the gyroscope we can see that the X/YRate is outputting data with 2.0mV/°/s sensitivity and the X/Y4.5 is outputting data with about 4.5 times the sensitivity, or 9.1mV/°/s.
Upload the following code to display the output from each of these (fig 6).


I wanted to zero this code as I did with the accelerometer code above. I was expecting the outputs from the x and y gyro to equal the output from Vref while the device is held stationary, but as you can see in fig 6, this is not the case (if anyone has an explanation for this I'd love to hear it!). Since Vref was not a god reference for me to zero my output to, I used some preset values based on the data from fig 6, you can find them in my print statements in the code below. I also removed the monitoring of Vref since it appeared to be stable no matter how much I moved the device, this also saved me an analog input pin on the Arduino.


The results from this code are shown in figure 7.  Rotation around the x and y axes will change the values of xRate, x4.5, yRate, and y4.5.
I used this accelerometer/gyro in a Arduino-based MIDI controller I've been working on. Below is the code for the two applications I demoed in the video at the top of this instructable.  I connected all three axes of the accelerometer and the two 4.5gyro outputs for this project.

single pixel moving around, triggering MIDI (only uses x and y accelerometer):


four pixels bouncing (only uses x accelerometer, uses x gyro to clear pixels):

scoma catorce2 months ago

Hi, very nice project!!

I`m trying to build it to use it with contemporany dance...but I`m really new on this and having troubles...

Also, i`m not using the same ACC/GYRO you`re using. I`m using the "GY-61 - Analog acceleration sensor module- ADXL335"

Could help me? Im trying to send the midi info but can`t make it work. Mine doesn`t have X, Y, Z Acc...(it did work with the test code)

Thanks for posting here your project, very inspiring!!

GY-61-900x700.jpg
cartiman3 months ago

Thank you for sharing your project.

Is there a download link (project file) ?

amandaghassaei (author)  cartiman3 months ago

there is a download pdf option for pro users, otherwise you can try printing out the page, or copying the code into a text editor.

OK. Thanks

xalpage6 months ago

Hello. Very nice and impressive project!

I would like to ask you a question about accelerators.

Suppose
everything is connected (accelerometer to arduino). I just turned on
the system but did not move at all the accelerometer. In that case do i
have a reading? Can I calculate initial unknown tilt without moving the
accelerometer?

This is important to me because i am thinking to
make a controller for adjusting a hospital bed in predifined tilts. So
in case of power down not to have to move the patient just to find out
in which position the bed is.

Could you help me out?

amandaghassaei (author)  xalpage6 months ago

yes, the accelerometer reads the acceleration due to gravity, so you will get a tilt reading if you do not move the device. Gyroscopes, by contrast, must be moved to generate a reading.

You made my day a lot better.
Thank you for the reply it's been awesomely helpful!!
amandaghassaei (author)  xalpage6 months ago

no problem! post a pic of your project when you're done, sounds cool!

etherbardo1 year ago
Hello Amanda,

Awesome project! I've been hacking at this to make it compatible with a MPU-6050 combo acc/gyro chip over i2c. I've got it working but sometimes there is a lag on startup (or it doesn't start at all) and if you let it sit without activity it can freeze up. Sometimes it will come back to life spontaneously. I'm new to interrupts, ports and the like on Arduino, so if anyone sees anything that would tighten up this code I'd love to hear it! I hope this will also make the project more accessible for those who don't have the discontinued chip in the example.

I've also been hacking at this to try and work with a 4x8 grid. I think I have the shift registers daisy chained properly, but the code to get this working has eluded me so far. If there is an easy solution, please post!

You will need the i2cdev library to make this work. Download here: https://github.com/jrowberg/i2cdevlib

The library supports other devices as well, so if you're not using the MPU-6050 you might find what you are using there.

You can see my revised sketch here: https://gist.github.com/4422201

Cheers!
amandaghassaei (author)  etherbardo6 months ago

been a long time since i looked back at this project, sounds great! have you made any more progress?

That's so cool! Reminds me of the old Lights Out game by tiger toys.