ADXL335 Accelerometer on an Arduino

I picked up an ADXL335 accelerometer in a packaging designed to fit onto a solder-less breadboard so that I could interface it to my Arduino. I had a few time-consuming problems interfacing with it because I’m not used to reading chip data sheets.

My assumption was that you’d deliver voltage to it, and it would spit out an analog signal that could be easy translated to acceleration using some constant factor. This isn’t exactly the case. The output resolution, milliVolts per g (1 g = Earth gravity), and voltage bias, is dependent on the voltage delivered to the power pin. I think in hindsight this makes sense, but the data sheet phrases this, and a few other things very peculiarly. I’m fairly inexperienced reading chip data sheets.

The data sheet is here (PDF). On the third page is pretty much everything you need to know to get useful data out of it, and the rest of the doc is stuff most hobbyist level people don’t care about, like how it behaves in different temperatures, and noise expectancy.

The phrase “RATIOMETRIC” shows up a few times. What this means is that a few of the specs are dependent on the power delivered to the chip. The sensitivity (mV/g) is stated to be ratiometric, and the example they give is that when you deliver 3V to the power supply, the sensitivity is 300 mV/g. In a later section called “Use with operating voltages other than 3V” it gives the example of 360 mV/g with a 3.6V power supply, and 195 mV/g with a 2V power supply. You can pretty much gather that the sensitivity in mV/g is the power supply voltage divided by 10. More or less.

Another ratiometric value is the “0g bias”. I don’t do a whole lot of analog electronics stuff, so this took me a bit to figure out. The accelerometer chip can detect negative acceleration, but it doesn’t output a negative voltage signal. What you do is consider the middle point of the power supply voltage range the 0 point. My power supply voltage is 3.3V, so I have to treat 1.6V as the zero point. You’ll add have to subtract that zero point from any voltage reading to get the actual mV/g value.

Here’s some numbers to drive the point home. My power supply is 3.3V, which is 3300 mV. 3300 divided by 10 is 330, so the chip is going to deliver 330 mV per 1g of acceleration. If I have the module on my table with the z-axis point up, it’s going to have 1g of acceleration applied to it, since it’s going to just read the pull of the Earth’s gravity and no other force. The chip’s zero point is the middle of the power supply range, 1.6V (1600 mV), so the actual voltage value it’s going to output for 1g of acceleration is 1930 mV, or 1.93 Volts. Since I know all this, I only need to subtract the zero point voltage to get the true value of 330 mV.

If I turn my accelerometer upside-down, it’s going to feel -1g of force. The voltage it would output would be 1.27V. When you subtract the zero point voltage you get -330 mV, which comes out to -1g.

Anyways, here’s the Arduino code that gets values for the X, Y, and Z axis spit out in units of g.

//Quick accelerometer test
//X is on A0; Y is on A1; Z is on A2

//Analog input pins 0, 1, and 2
//are what I send the x,y, and z
//accelerometer outputs to, respectively
int xAxisPin = A0;
int yAxisPin = A1;
int zAxisPin = A2;

//Variables to hold the returned
//ADC data from the analog input
//pins
int xAxisValADC = 0;
int yAxisValADC = 0;
int zAxisValADC = 0;

//Variables to hold the voltage
//values after converting from ADC
//units to mV
float xAxisValmV = 0;
float yAxisValmV = 0;
float zAxisValmV = 0;

//My Arduino Uno has a 10-bit
//AD converter, with a max value
//of 1023
int ADCMaxVal = 1023;

//The AD converter voltage
//is powered by 5V
float mVMaxVal = 5000;

//I measured the power going to the
//accelerometer as actually being 
//3230 mV, so I use this value to 
//define the mid-point
float supplyMidPointmV = 3230 / 2;

//Since the supply is actually 3230
//mV, I know the output will be 323mV
//per 1g detected
int mVperg = 323;

//Multiply any acquired ADC value
//by mVPerADC to convert to mV
float mVPerADC = mVMaxVal / ADCMaxVal;

void setup()
{
  Serial.begin(9600);
  
  //I don't know if setting them to
  //input is necessary, but I do it
  //anyways.
  pinMode(A0, INPUT);
  pinMode(A1, INPUT);
  pinMode(A2, INPUT);
  
}

void loop()
{
  //Read the x, y, and z values from
  //the analog input pins
  xAxisValADC = analogRead(xAxisPin);
  yAxisValADC = analogRead(yAxisPin);
  zAxisValADC = analogRead(zAxisPin);
  
  //Convert the ADC values to millivolts
  xAxisValmV = xAxisValADC * mVPerADC;
  yAxisValmV = yAxisValADC * mVPerADC;
  zAxisValmV = zAxisValADC * mVPerADC;
  
  //This could be prettier. What's happening is the mid-point
  //voltage value is subtracted from the voltage recorded
  //from the analog input, and then that value is divided
  //by how many millivolts per g the accelerometer is
  //ouputing. This results in the value being printed
  //in units of g.
  Serial.print((xAxisValmV - supplyMidPointmV) / mVperg);
  Serial.print("\t");
  Serial.print((yAxisValmV - supplyMidPointmV) / mVperg);
  Serial.print("\t");
  Serial.print((zAxisValmV - supplyMidPointmV) / mVperg);
  Serial.print("\t");   
  
  Serial.println();
  
  delay(100);
}

It’s a bit verbose, but I wanted to be super clear about what is going on.

I dumped 20 seconds of gathered data into a .txt file and used Excel to make this pretty graph.

accelchart

For the first few seconds it’s just sitting on the table, so the z-axis is at 1g, and the x and y-axis are at about 0 (these aren’t calibrated readings, but it’s good enough). You can see when I pick it up and shake it around a bit, then put it back on the table. Neat.

The motivation for writing this post is because it took me about an hour to reconcile the info in the data sheet with the values I was reading on the analog inputs. It was hard to find anything useful online that stated plainly what you need to do on the Arduino end. Hopefully this helps someone out.

Post a comment or message me on Twitter (@cheydrick) if you have any questions.

This entry was posted in Uncategorized and tagged . Bookmark the permalink.

11 Responses to ADXL335 Accelerometer on an Arduino

  1. Wags says:

    Did the data that you gathered come from serial print? if not where ? Did you simply dump data the data and excel did the formatting or is that a step you have to do with each row and column? Thank you for this article very very helpful 11/10

  2. Yes, the data came from the serial print lines in the listed code. I printed out “/t” in between the readings, which inserts a tab. Excel knows how to import tab delimited text and can automatically put the readings into columns. I could have also used a comma to delimit the data.

    Glad you liked the article; let me know if you have any other questions.

  3. Wags says:

    Thanks again for your fast reply, I am a high school student new to Arduino so excuse the simple questions …when you say you “dumped” the data into a txt file did you do this separately or did you use a plx-daq, program and if so where in the code would I put instructions? Is there any order to which I open first Excel or my arduino board/code. It is a nice graph have you tried different baud rates or delay settings to smooth things out? Do you think it would make any difference in sentivities. Thanks again for the post and response!

  4. Sure thing. I can’t remember how I got the data into a text file in this particular project, but it would have been one of two ways. I either copied the output from the serial monitor that’s part of the Arduino IDE, or I wrote a Python program to connect to the Arduino and save the data to a text file. All of my Arduino stuff is sitting on a shelf at work – I’ll dig it up on Monday and replicate the results so I can be more specific.

    Increasing the baud rate or the delay won’t affect the sensitivity (more on that later), but it would affect the max vibration frequency I could detect. The delay of 100 milliseconds means I’m sampling at 10 times a second, or 10 Hz. There’s a rule (called the Nyquist frequency) that says you have to sample data at least twice as fast as the frequency of interest. So at a 10 Hz sampling rate, I can only (barely) capture a 5 Hz vibration safely. Any other higher frequencies will be garbled (or aliased).

    The sensitivity of the accelerometer is a product of the power supply voltage, and the bit depth of the A/D converter. If I needed more sensitivity I think I’d start with using an A/D converter with 16 bits of resolution. The Arduino only has 10 bits, which is pretty good for most purposes.

  5. I think I did just copy/paste from the serial monitor into Excel. I just tried it and it worked.

    The fancier way would be to write a receiver program on the PC to read what the Arduino is outputting over the serial line. That’s not so hard to do in Python. It depends on what you’re trying to do.

    I use Arduino boards at work, but instead of reading serial data from them, I send serial data to them. They read the serial data and parse out the commands and to various things, like turn power on/off to some devices and send control signals to others.

  6. Upik Jamil says:

    I’m still confused about the power going to accelerometer, how do you determine the value is 3230mV? and what the function midpoint?

    • I used a multi-meter to read the actual voltage powering the accelerometer.

      The midpoint between 0 mV and 3230 mV is the voltage that is output by the accelerometer when the acceleration is 0 G. Knowing this is required to calculate the actual G value.

  7. DShah says:

    Hey, Thank you for this project. I am planning to use same sensor for my project. I want to know that, is this code helpful for acceleration measurement of falling object ? I also want to know that can I detect that, at what acceleration falling object hit the ground?

    • Sure. The code samples just print out what acceleration is measured by the sensor.

      Here’s a copy/paste from Wikipedia’s article on accelerometers: “…an accelerometer at rest on the surface of the Earth will measure an acceleration due to Earth’s gravity, straight upwards (by definition) of g ≈ 9.81 m/s2. By contrast, accelerometers in free fall (falling toward the center of the Earth at a rate of about 9.81 m/s2) will measure zero.”

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