The ADXL345 is a 3 axis accelerometer and there are two basic uses for this device:
Orientation: Determine which way is up using gravity.
Instantaneous force: Detect applied forces.
Typical applications include tilt and motion sensing e.g. self
levelling platforms, drone orientation, angle of tilt measurement, drop
It can measure accelerations
up to 16g with 13bit resolution translating to a resolution of
3.9mg (g representing gravity at 9.8m/s2).
To make it more useful, it has several built in functions:
You can setup thresholds on each axis to allow detection of movement
i.e. above a certain acceleration level it will generate an
interrupt. You could use that for detecting if the contents of a box of sensitive equipment had been mishandled.
ADXL345 Breakout board
You can also detect single or double taping in any direction. Another
built in function can detect free fall for drop sensing.
As above except for the power supply. The breakout board has a LDO
3V3 regulator so the input voltage to VCC must be:
4.0V to 6V.
CS is pulled high by a 10k resistor (active). Can be 4k7 on some boards.
ADDR(SDO) is pulled low by a 4k7 resistor.
SCL is pulled high to 3V3 by a 4k7 resistor.
SDA is pulled high to 3V3 by a 4k7 resistor.
VDDIO is connected to VS and both connect to 3V3.
Since the I2C interface uses open drain outputs, the interface is
compatible with a 5V system. This is true as the Arduino never drives
out 5V it only tristates an output to let the voltage level pull to 3V3.
To generate a zero it outputs a digital zero which is also compatible
with the 3V3 interface.
Warning: If you use the chip in SPI mode then you will need level
translators (when using a 5V controller) or a controller board that only uses 3V3 throughout.
Breakout Board ICs
Note: The addition of a 3V3 regulator means the board can be used in a 5V system if I2C mode is used.
ADXL345 Breakout board GY-291 Schematic
ADXL345 Interface to Arduino
Using the ADXL345 with the Arduino is quite easy if you use the
I2C interface, as this allows to controller to operate at 5V and the
ADXL345 to operate at 3V3.
Note: In I2C mode the SDO pin is an input, selecting an address.
For I2C mode operation the chip has an address pin. On the breakout board this is pulled low giving an I2C address of:
State of ADDR/SDO pin
I2C Address (hex)
I2C Address (binary)
ADDR pulled high
ADDR pulled low
Note: The ALT ADDRESS pin is an output in SPI mode, for SDO.
ADXL345 Output Data Rate
The ODR is 100Hz set by bits in the BW_RATE register. In the library use setRate() and the following defined values:
ADXL345_RATE_3200 // Must use SPI mode
ADXL345_RATE_1600 // Must use SPI mode
ADXL345_RATE_800 // Must use I2C rate of >=400kHz
ADXL345_RATE_400 // Must use I2C rate of >=200kHz
ADXL345_RATE_200 // Must use I2C rate of >=100kHz
Changing the data rate is useful for power saving (by going slow).
At 100Hz and above the current consumption is 140uA (p14 of datasheet) - except for 1600Hz (90uA). The minimum
you can get is at 0.39Hz (and below) with 23uA used.
You can select the acceleration range from the following values:
2g, 4g, 8g, 16g.
The same scaling factor is used in all resolutions because the
internal DAC resolution changes from 10bits to 13 bits as each
resolution is selected. So each bit is always worth 3.9mg:
Note the '-1' allows for the sign bit to give positive or negative results.
Using 16g mode gives maximum dynamic range.
However an extract from the datasheet shows the actual deviation from the above ideal values (Sensitivity deviation from ideal):
If you restrict the range of the adxl345 to 10bits then it becomes less
sensitive (fairly obvious). For full range you get the typical
sensitivity of 3.9mg/LSB and 3.5 ~ 4.3mg/LSB min ~ max deviation (this
is set using the FULL_RES bit). Why you would restrict to 10bits is
something I don't understand - seems pointless.
Why not ±90°?
Why can't the ADXL345 accelerometer indicate ±90°?
If you run the program below you will see that the accelerometer is
extremely good at indicating tilt at low angles (on a flat surface) to
about 70°, but does not reach ±90°. In fact it can't seem to reach that magic number ±90°!
At first, I thought there was something wrong with the accelerometer
since no one seems to talk about this. Why should it not be possible to
measure all angles?
If you think about holding a piece of wood - the maximum force on it
is when you hold it horizontally. The more you point it upwards, to the
vertical position, the less gravity can affect it, hence - the
accelerometer becomes less sensitive.
So it turns out that the sensitivity of the accelerometer decreases with
increasing angle and follows a near sinusoidal response, and accuracy decreases the closer you get to ±90° of tilt.
"The sensor is a polysilicon surface-micromachined structure built on
top of a silicon wafer. Polysilicon springs suspend the structure over
the surface of the wafer and provide a resistance against forces due to
applied acceleration." [datasheet]
You can imagine the sensor as a beam suspended on springs, with the
capacitance between the beam and the support base giving the
acceleration measurement. When the beam is perpendicular to the
acceleration field small tilt changes will have a large effect as gravity
acts over a larger area.
As the beam tilts vertically, the sensor becomes
less sensitive (interacting with the gravity vector less) until, at full
vertical orientation, it can not return a reading since the gravity
vector has no effect on the beam.
There is a very good discussion of accelerometer sensitivity in Analogue Devices Application note AN-1057 by C Fisher here. The following diagram is from that application note:
The diagram shows that around 0° ~ 23° tilt you only need a
sensitivity of 16mg/LSB to resolve 1° steps, and around 60° tilt you need 8mg, and around
80° you need 4mg. This is why the ADXl345 can not display 90° as
its sensitivity is too coarse to resolve tilt at that angle (3.8mg). So
the ADXL345 is good for tilt up to about ±80°. This is for the case
where you want to resolve tilt measurement to within 1°.
TIP: Increase resolution by oversampling to resolve smaller angles.
Why can't I measure yaw?
Yaw is the rotation about the z axis - or compass heading. You may think that the ADXL345 z axis is not working but it is!
When you rotate the accelerometer about the x or y axis, sensors
experience more or less of the gravity vector and therefore output
different values of acceleration.
When you rotate the accelerometer about the z axis the sensor
experiences the same value of gravity vector so you can't measure yaw.
This is why accelerometers are used in conjunction with a gyroscope or magnetometer for measuring yaw values.
What is the z accelerometer useful for?
So then the question becomes why do you need a z-accelerometer
The z axis
accelerometer indicates deviation from vertical. In conjunction with either x
or y accelerometer values you can calculate pitch and roll (deviation
from vertical in the x or y directions).
You can use an Arduino Uno or Nano (the Nano is convenient for
solderless breadboard use as it fits into one quite nicely). Here the ADXL345
is used on the Arduino in I2C mode so just connect SDA, SCL, power and ground:
Arduino Uno/Nano Connection
ADXL345 interfacing with the Arduino is simply to connecting the I2C interface as above.
The I2Cdevlib has ADXL345 library code as well as code for many other devices.
This library has a lot of features, supported chips, and can operate
on multiple processors but it is a little more involved to install and
you can not use the automatic Arduino zip file installer.
Unzip the file (ic2devlib-master) then navigate to the Arduino
directory within ic2devlib-master. Copy the directories ADXL345 and
I2Cdev to the Arduino libraries directory, usually found here (on
ADXL345 Self Test Sketch
Because the device is a mechanical system the ADXL345 includes a self
test circuit that imposes an electrostatic field on the physical
measuring elements. These has a similar effect to gravitational
acceleration adding to the existing acceleration element.
Note: Datasheet page 31 has more on using the self-test.
The following program tests the chip at 3.3V (the supply voltage
changes the test parameters). The program will output the results to the
serial monitor and gives you a PASS/FAIL indication. You can also
observe raw g values, roll and pitch.
Use this sketch if you thing that the AXL345 is not working.
Type 't' to start a self-test and 's to output g, roll and pitch values.
The following shows typical output from the program:
Starting I2C devices...
ADXL345 comms Ok.
Enter t - Self test, s - Show angles
stx-x 59 sty-y
-18 stz-z 88
X PASS (10 ~ 118)
Y PASS (-118 ~ -10)
Z PASS (14 ~ 161)
g values: -0.17 -0.02 1.05 Roll 0 Pitch -9
g values: -0.21 0.00 1.08 Roll 0 Pitch -11
g values: -0.18 -0.01 1.03 Roll 0 Pitch -9
g values: -0.17 -0.02 1.07 Roll -1 Pitch -9
g values: -0.17 -0.02 1.07 Roll 0 Pitch -8
g values: -0.01 -0.03 1.00 Roll -1 Pitch 0
g values: -0.69 -0.06 0.77 Roll -3 Pitch -41
g values: -1.30 -0.15 0.36 Roll -6 Pitch -73
g values: 0.24 -0.21 0.95 Roll -12 Pitch 13
g values: 0.22 -0.42 0.96 Roll -23 Pitch 11
g values: -0.06 -0.82 0.87 Roll -43 Pitch -2
g values: -0.01 0.05 1.01 Roll 2 Pitch 0
Sketch Example 2
This program outputs only roll and pitch values - these are used to show
a processing simulation of the orientation of the accelerometer. This
is the type of view produced by the processing code for the Arduino
This a cutting edge university level tutorial on mems and
micromachined structures with specific coverage of oscillator
This provides a fascinating look at the world of micromachining from
structures created between 1989 and the present day (Video released in Feb 2019).
The tutorial is from 2018.
It starts off showing how structures are created using transistor
etching techniques. The talk is given Professor Clark Nguyen - He was
Bill Tang's undergraduate researcher when MEMS was being invented.
This is a great video to see cutting edge techniques - it is very
advanced but starts off slowly, describing early designs - very good to