Basics (updated): Using an accelerometer with an AVR microcontroller
Wednesday, December 30 2009 @ 02:20 AM PST
Contributed by: Windell
Some time ago, we wrote up a tutorial about using an ADXL330 accelerometer with an AVR microcontroller. A couple of years have passed, and so we've returned to update and clean up some loose ends on this project.
The Analog Devices ADXL330 that we originally wrote about (shown above) was one of the original low-cost breakthrough devices-- the ones that first showed up in Wii controllers and other consumer electronics with accelerometers. At the time it cost $11.50 in unit quantity, and we were able to get one pre-soldered to a breakout board at Sparkfun.com for $35.
In the time that has passed, the ADXL335 has come along as a next-generation drop-in replacement for the ADXL330, which now bears the dreaded stain of "not recommended for new designs." (The ADXL335 is less expensive than the 330-- currently $5.42 each, compared to $12.15 for the 330 --but is otherwise mostly equivalent.)
Tiny chips like these are (IMHO) not easy to solder, so it's convenient that this new chip is also available presoldered to a breakout board. We're using the one from Adafruit ($20), but similar pin-compatible boards are also made by Analog devices (model EVAL-ADXL335Z) and Digi-Key (model DKSB1002A). (Sparkfun also has a ADXL335 breakout, but it's pin-compatible to their discontinued ADXL330 board, not to these others.)
Besides bumping up to the current accelerometer chip, we've also cleaned up the project a little bit with one of our ATmegaxx8 breakout boards. Not that there's any magic hidden in that board-- you certainly can still do this project on a breadboard --but at our presentation is a bit neater, and the end product is much more reliable.
Let's start at the beginning. We're using an ATmega168, a popular AVR microcontroller*, which we will power at 3 V, from 2 AA cells. (3 V is a good choice to make both the chip and accelerometer happy.) The circuit diagram above shows the essential power supply connections for the AVR. We're also using the 3 V power supply as the reference input for the analog to digital converter.
*Note 1: The other AVRs in the same family will work too, ATmega88, '168PA, '328P, etc. Note 2: If you're new to AVR, you may want to look at our list of resources for getting started.
The next thing that we add is the 6-pin ISP header, which is necessary for programming the microcontroller through a standard ISP interface such as the USBtinyISP (also from Adafruit).
Now, the circuit diagram thus far-- with just power supply and ISP connections --is common to a lot of our projects, which is why we designed those ATmegaXX8 boards in the first place.
So here is the breakout board, AVR, 2 x AA battery box, and header. The three wire jumpers (like resistors with one black stripe) are used to connect pins 20-22 to power/power/ground. Having put this together, we have built the circuit shown in the last circuit diagram.
Next, we want to add the accelerometer board.
There are six pins on the ADXL335 breakout board. Two for power and ground, three analog outputs for X, Y and Z, plus a "test" pin that we can leave disconnected. We're going to connect the power supply up first and then wire up the X, Y, and Z lines to the analog inputs of our microcontroller.
First, solder the 6-pin header to the ADXL335 breakout board.
Next, we add that board to the breadboard-style proto area on the side of the microcontroller board. The locations inside each white rectangle are internally connected (and not connected to anything else).
Here, we wire up the 3 V and ground lines of the accelerometer board. Ground comes from the "GND" terminal on the upper left to one of the middle stripes through a blue wire, and then through another blue wire to the far left pin of the ADXL335 board-- the one labeled GND. Similarly we connect Vcc ("positive power supply") to the 3V terminal through a couple of red wires. (The perspective of this photo makes it hard to see which pin of the ADXL335 board goes where-- it's easier to see in the photo above this and to the right.)
Now that we've wired up the power supply connections, we can wire up the X, Y, and Z analog lines.
To do this, we add three wires. "X" goes to "ADC5", "Y" goes to "ADC4", and "Z" goes to "ADC3." Having done so, we are now caught up to the last circuit diagram.
Next, we will add some output LEDs that the AVR can drive to indicate the acceleration values as it reads them out.
Here, we add two LEDs (one red, one blue) for each of the three axes.
The big idea is that when there is no acceleration in (say) the X-axis direction, both X-axis LEDs are off. When it detects acceleration one way, the red LED lights up (and brighter, the higher the acceleration is) and it lights up blue for acceleration in the opposite direction. (Naturally, the other two axes work the same way.)
To do this, we're using the pulse width modulation outputs from the three timers (timer 0, timer 1, and timer 2) on the microcontroller. Each timer has two outputs, called "output compare" pins A and B, which go to the two LEDs. The six outputs are called OC0A, OC0B, OC1A, OC1B, OC2A, and OC2B, and are hooked up to the LEDs as indicated in the diagram. (No resistors are needed on the blue LEDs, because the forward voltage of those is 3.6 V-- we will not approach their rated current, ~25 mA, with our 3 V power supply.)
Our new parts: six LEDs (three red, three blue) and three resistors.
First, we'll add the LEDs for the X axis.
OC0A goes through the resistor to the LED, to ground. OC0B goes directly through that yellow wire to the blue LED, to ground.
You can download the firmware program (C code) for the AVR here (11 kB .ZIP file). It's a very simple AVR-GCC program, licensed under the GPL. It reads in three analog
inputs sequentially, and lights up the six display LEDs depending on the values that it reads.
Once you've gotten the AVR programmed, it should be ready to go and show you outputs that depend on the acceleration.
So far, we've only got the output LEDs for the one axis, but you can already try it out.
As you shake it, even fast, you can see the LEDs responding to motion along the X axis.
If you aren't wildly swinging the board around, what you'll see is just the steady-state gravitational acceleration displayed. You might call it a tilt sensor, and it can tell you which way is up.
If we tilt our board left or right, such that the X-axis is now pointing slightly up or down (slightly with or slightly against gravity) you can see the X-axis LED pair, shown here, switch from red to blue. (Which way is X? It's written on the circuit board, and also in the datasheet for the accelerometer.)
Finally, we add the Y and Z indicator LEDs.
And here's the completed project. The "Y" LED pair is in the upper right, connected to OC1A and OC1B. The "Z" LED pair is in the lower left, requiring one longer wire from MOSI/OC2A to the red LED for the Z axis.
Now, it's sensitive in all three directions and has the capability to tell you what it sees. Lying flat on our (not particularly level) photography table, the X and Y axes are reporting near-zero acceleration. There isn't much tilt in X or Y. The only bright LED is the blue one for Z, because there *is* a strong vertical acceleration. Naturally, the red Z LED comes on instead when you flip it upside down.
Comments (15)
Evil Mad Scientist Laboratories
http://www.evilmadscientist.com/article.php/ADXL335