Go Down

Topic: [ADXL335] Measuring acceleration in Gs. (Read 6523 times) previous topic - next topic



I've bought an ADXL335 acceleration sensor and I want to measure the acceleration in Gs.

I've made this code:

Code: [Select]

float x, y, z;

void setup()

void loop()
  x = analogRead(0) / 330.000;       
  y = analogRead(1) / 330.000;       
  z = analogRead(2) / 330.000;       
  Serial.println("--MEASURING ACCELERATION... AXIS X, Y, Z--");

When I put the acceleration sensor on a table, I can read this values:

1.02 (X)
1.27 (Y)
1.02 (Z)

I'm not sure this code is ok. Is it? The values it returns seem to be OK.
Is there a better code to measure acceleration in Gs? Than you.


Start by calibrating your accelerometer:

Take the average of 100 raw analog readings and display them.  Measure with each axis facing UP (-1G) and DOWN (+1G).  For each axis, note the minimum and maximum values.

Then you can then convert your analog readings directly to milli-g's:

      long int x = map(analogInput(0),minimumX, maximumX, -1000, +1000);

To print in G's:  Serial.print(x/1000.0);

By calibrating you can correct for offset error and scale error.
Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e


Jan 03, 2013, 06:31 pm Last Edit: Jan 03, 2013, 06:55 pm by JD3 Reason: 1
The calibration method is really important.

If you use the 1g numbers for min and max, the only range you will get is 1g.
Any readings out of that range will not display properly.

Finding the range of +/- 1g is important.  Add them and divide by two.
That will give you the analogRead() value of 0g, assuming the accelerometer is perfectly level.
The difference between 0g and the min or max is your resolution.  How many units read/g.

For an example, on my sensor I get 401 & 611 on the X axis.  (I am using external voltage reference @ 3.6v)
Zero g would be at 506.  The resolution would be 105.  
Multiply the difference of analog reading from 0g by .0095 (1/105 or 1/resolution) and there is your g reading.
Or (analogRead(analog pin) - 506) * .0095

Here is the code I used for calculating g forces while driving.
The orientation of the Adafruit accelerometer:  X points left, Y points to the rear.
Arduino orientated natural (USB on left) and accelerometer header pins mounted next to analog pins on protoshield.

WARNING - please do not use alone while driving.  Ask a friend to be your Co-pilot or Navigator - WARNING

Code: [Select]
Designed by AB9VH James Douglas July 2012
Unified Microsystem's ATS-1 LCD Terminal Display Shield
with adafruit 3 axis accelerometer, external 3.3v reference
Shows g forces while driving


int Xaxis = 0;         // fresh data from accelerometer
int Yaxis = 0;
int Xcal = 505;        // calibration data, zero g
int Ycal = 505;
int key = -1;

void setup() {
 analogReference(EXTERNAL);     // uses 3.3v from accelerometer for reference voltage
 Serial.begin(4800);            // opens serial port for LCD shield
 Serial.write(1);               // clears display and homes cursor
 Serial.println("   Automobile  ");
 Serial.print(" Accelerometer ");
 Serial.println(" Prototype 2012");
 Serial.print(" J. Douglas III");
 Serial.write(1);               // clear display & home cursor
 Serial.println(" Press any Key");
 Serial.print("    to start ");
 while (key<0) key = Serial.read();

void loop() {
 Xaxis = analogRead(2);
 Yaxis = analogRead(1);
 if (Xaxis<Xcal) {                          // calculate Left & right
   Serial.print("Right ");
   Serial.println("g   ");
 else if (Xaxis>Xcal) {                      // always display left and right
   Serial.print("Left ");                   // g force as positive value
   Serial.println("g   ");
 else Serial.println("L/R 0.00g     ");    // display forward as positive g
 Serial.print("Front ");                   // display rearward as negative g
 Serial.println("g   ");
 LCDpos(1,1);                                // home cursor ATS-1

void LCDpos(char x, char y) {

That little black caterpillar you just stepped on will set you back a few bucks....


I think I'm doing something wrong or my code isn't good, because when I face down the ADXL335 I get values around 0'85 G's in the Z axis, and I should get -1G...


Jan 03, 2013, 10:11 pm Last Edit: Jan 03, 2013, 11:18 pm by johnwasser Reason: 1

I think I'm doing something wrong or my code isn't good, because when I face down the ADXL335 I get values around 0'85 G's in the Z axis, and I should get -1G...

From the datasheet it looks like the zero point and the sensitivity can both be off by about 10%.  I think that means that if you use the nominal zero (Vs/2) and the nominal sensitivity (Vs*0.1 per g) you may get readings as much as 20% off.  If you get 0.85 instead of 1.0 your error is only about 15%, well within specs.

Below is what code with calibration looks like.  Of course your calibration values will be different from mine.

Yes, you will get results outside the -1000/+1000 range.  The map() function does not constrain the inputs or outputs.  It just uses the input range and output range to calculate the offset and scale.

Code: [Select]

// Accelerometer calibrate
const int XPin = A2;
const int YPin = A1;
const int ZPin = A0;

// Raw analog values for -1g and +1g.  Position carefully and look for min and max values.
// These are from an accelerometer running on 3.3V measured agains a 5V analog reference.
// You would expect (3.3V/2-0.33V)*1024/5V = 270 for -1g and (3.3V/2+0.33V)*1024/5V = 405 for +1g.
// As you can see, my accelerometer does not match the nominal values.
const int XMin = 180;
const int XMax = 507;
const int YMin = 199;
const int YMax = 542;
const int ZMin = 152;
const int ZMax = 477;

void setup() {
  pinMode(A3, OUTPUT);
  digitalWrite(A3, HIGH);  // Power
  pinMode(A4, OUTPUT);
  digitalWrite(A4, LOW);  // Ground

void loop() {
  unsigned long XSum = 0;
  unsigned long YSum = 0;
  unsigned long ZSum = 0;
  for (int i=0; i<100; i++) {
    XSum += analogRead(XPin);
    YSum += analogRead(YPin);
    ZSum += analogRead(ZPin);
  Serial.print(map(XSum/100, XMin, XMax, -1000, 1000));
  Serial.print(", Y=");
  Serial.print(map(YSum/100, YMin, YMax, -1000, 1000));

  Serial.print(", Z=");
  Serial.println(map(ZSum/100, ZMin, ZMax, -1000, 1000));

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Go Up

Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

via Egeo 16
Torino, 10131