# [ADXL335] Measuring acceleration in Gs.

Hi.

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

``````float x, y, z;

void setup()
{
Serial.begin(9600);
}

void loop()
{

Serial.println("--MEASURING ACCELERATION... AXIS X, Y, Z--");
Serial.println(x);
Serial.println(y);
Serial.println(z);
delay(1000);
}
``````

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.

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.

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.

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

``````/*
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 ");
delay(2000);
Serial.write(1);
Serial.println(" Prototype 2012");
Serial.print(" J. Douglas III");
delay(2000);
Serial.write(1);               // clear display & home cursor
Serial.println(" Press any Key");
Serial.print("    to start ");
Serial.write(1);
}

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

void LCDpos(char x, char y) {
Serial.write(20);
Serial.write(x);
Serial.write(y);
}
``````

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...

r4m0n:
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.

``````// 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() {
Serial.begin(9600);

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++) {
}

Serial.print("X=");
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));
delay(500);
}
``````

Afternoon Guys,

I’m new to the Arduino world and would like some help from someone a lot more knowledgeable than myself. I am trying to use an ADXL335 accelerometer x axis to measure tilt in mm (use some form of trig function) length of base 1435mm and adjacent measuring up 150mm maximum.

I can get it to roughly measure angle and display in there Serial monitor, but would also like it to eventually display on LCD or similar value in mm from level (either “Level”,“L High”, “R High”).
at this stage I haven’t looked at the LCD display part.

I hope what I have asked makes sense, it you guys could help me out that would be much appreciated.

``````// these constants describe the pins. They won't change:
const int groundpin = 18;             // analog input pin 4 -- ground
const int powerpin = 19;              // analog input pin 5 -- voltage
int analogPin = A3;                 // x-axis of the accelerometer
int val = 0;

void setup() {
// initialize the serial communications:
Serial.begin(9600);

// Provide ground and power by using the analog inputs as normal
// digital pins.  This makes it possible to directly connect the
// breakout board to the Arduino.  If you use the normal 5V and
// GND pins on the Arduino, you can remove these lines.
pinMode(groundpin, OUTPUT);
pinMode(powerpin, OUTPUT);
digitalWrite(groundpin, LOW);
digitalWrite(powerpin, HIGH);

}

void loop() {
// print a tab between values:
Serial.println(val);
{Serial.println("Level");}
{Serial.println("L High");}
{Serial.println("R High");}
delay(100);
}
``````

@Damos

``````// these constants describe the pins. They won't change:
const int groundpin = 18;             // analog input pin 4 -- ground
const int powerpin = 19;              // analog input pin 5 -- voltage
int analogPin = A3;                 // x-axis of the accelerometer
int val = 0;

void setup() {
// initialize the serial communications:
Serial.begin(9600);

// Provide ground and power by using the analog inputs as normal
// digital pins.  This makes it possible to directly connect the
// breakout board to the Arduino.  If you use the normal 5V and
// GND pins on the Arduino, you can remove these lines.
pinMode(groundpin, OUTPUT);
pinMode(powerpin, OUTPUT);
digitalWrite(groundpin, LOW);
digitalWrite(powerpin, HIGH);

}

void loop() {
// print a tab between values:
Serial.println(val);
if (val== 0) Serial.println("Level");
else if (val> 0) Serial.println("L High");
else{Serial.println("R High");

delay(100);
}
``````

r4m0n:
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…

+1g. The vector is upwards. The table pushes upwards on the board, so it senses an upwards acceleration.
We only think of gravity acting downwards because we see objects in free fall going down, whereas free-fall
is the true reference frame. An accelerometer in free-fall registers a zero acceleration vector. Until it hits
the ground!