Summary
Learn how to connect the ADXL345 3-axis accelerometer to Arduino, read X, Y, and Z acceleration, and calculate pitch and roll. This tutorial includes wiring instructions, working code, and steps for configuring single-tap, double-tap, and free-fall detection for motion-sensing
Theย ADXL345 is a digital 3-axis accelerometer with selectable measurement ranges of ยฑ2g, ยฑ4g, ยฑ8g, and ยฑ16g. It communicates with Arduino over I2C or SPI and measures acceleration along the X, Y, and Z axes. With the right library and configuration, it can detect tilt, taps, double taps, and free-fall events without requiring the microcontroller to continuously analyse every sample.
This tutorial covers the ADXL345 pinout, Arduino wiring, code for reading X, Y, and Z acceleration, calculating tilt, and configuring tap and free-fall detection with interrupts.
What Is the ADXL345?
The ADXL345 is a small, low-power, 3-axis digital accelerometer from Analog Devices. It measures acceleration along three perpendicular axes, making it useful for detecting movement, orientation changes, vibration, and impact.
Acceleration is commonly expressed in g, where 1g is approximately the acceleration due to Earth's gravity. When the sensor is stationary, gravity contributes to its readings. By comparing the acceleration values across its three axes, a microcontroller can estimate the sensor's orientation relative to gravity.
Key features include:
-
Three-axis acceleration measurement along X, Y, and Z.
-
Selectable full-scale ranges of ยฑ2g, ยฑ4g, ยฑ8g, and ยฑ16g.
-
I2C and SPI digital communication.
-
Configurable data rate and measurement resolution.
-
Built-in tap, double-tap, activity, inactivity, and free-fall detection features.
-
Interrupt outputs that can alert a microcontroller when configured events occur.
The ADXL345 is an accelerometer, not a complete motion-tracking system. It does not directly measure angular velocity like a gyroscope, and it cannot reliably distinguish gravity from sustained linear acceleration using acceleration readings alone.
ADXL345 Pinout
The ADXL345 sensor IC has pins for power, ground, communication, and interrupt signals. Breakout boards often add convenient connectors and may include voltage regulation or logic-level circuitry. Check the documentation for your specific board before connecting it.
|
Pin or signal |
Function |
|---|---|
|
VCC or VIN |
Power input, depending on the breakout design |
|
GND |
Ground |
|
SDA |
I2C data |
|
SCL |
I2C clock |
|
CS |
Interface selection on the sensor; typically configured for I2C on many breakout boards |
|
SDO or ALT ADDRESS |
Helps select the I2C address on boards that expose this signal |
|
INT1 |
Configurable interrupt output |
|
INT2 |
Configurable interrupt output |
For a basic I2C project, the essential connections are power, ground, SDA, and SCL. Interrupt pins are optional until you configure events such as tap or free-fall detection.
Important: The ADXL345 chip operates at low voltage. Do not assume a bare sensor board accepts 5V on its power input or has 5V-tolerant I2C pins. Check the breakout's specified supply voltage and logic-level compatibility before connecting it to an Arduino Uno.
Wiring the ADXL345 With Arduino
For an Arduino Uno, I2C is the simplest interface for a basic accelerometer project. The Uno uses A4 for SDA and A5 for SCL. Other Arduino boards may use different pins.
|
ADXL345 breakout pin |
Arduino Uno |
|---|---|
|
VIN |
5V only if the breakout supports 5V input; otherwise use its specified supply |
|
GND |
GND |
|
SDA |
A4 (SDA) |
|
SCL |
A5 (SCL) |
|
INT1 |
Optional digital pin, such as D2 |
|
INT2 |
Optional digital pin, such as D3 |
The ADXL345 chip itself operates from a supply of 2.0V to 3.6V. Some breakout boards add a voltage regulator and logic-level shifting, allowing them to work with a 5V Arduino Uno. Others do not. Check the board documentation before applying power.
For the basic acceleration and tilt example below, you only need VIN, GND, SDA, and SCL. The interrupt pins are used later for tap and free-fall detection.
Reading X, Y and Z Acceleration
The easiest way to get started is with the Adafruit ADXL345 library.
Install the library
-
Open the Arduino IDE.
-
Select Sketch > Include Library > Manage Libraries.
-
Search for Adafruit ADXL345 and install it.
-
Install any required dependencies, including Adafruit Unified Sensor, when prompted.
-
Connect the sensor and upload the following sketch.
Arduino code to read acceleration and calculate tilt
This sketch reads the three axes, displays acceleration in metres per second squared, and estimates pitch and roll from gravity. The angles are most meaningful when the sensor is stationary or moving slowly.
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_ADXL345_U.h>
#include <math.h>
Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345);
void setup() {
Serial.begin(115200);
Wire.begin();
if (!accel.begin()) {
Serial.println("ADXL345 not detected. Check wiring.");
while (1) {
delay(10);
}
}
accel.setRange(ADXL345_RANGE_2_G);
Serial.println("ADXL345 ready");
}
void loop() {
sensors_event_t event;
accel.getEvent(&event);
float x = event.acceleration.x;
float y = event.acceleration.y;
float z = event.acceleration.z;
float pitch = atan2(-x, sqrt(y * y + z * z))
* 180.0 / PI;
float roll = atan2(y, z) * 180.0 / PI;
Serial.print("X: ");
Serial.print(x, 2);
Serial.print(" m/s^2, Y: ");
Serial.print(y, 2);
Serial.print(" m/s^2, Z: ");
Serial.print(z, 2);
Serial.println(" m/s^2");
Serial.print("Pitch: ");
Serial.print(pitch, 1);
Serial.print(" deg, Roll: ");
Serial.print(roll, 1);
Serial.println(" deg");
Serial.println();
delay(200);
}
Understanding the output
-
X, Y and Z: Acceleration measurements along the sensor's three axes, reported in m/sยฒ by the Adafruit library.
-
Pitch: An estimate of rotation derived from the X, Y and Z acceleration values.
-
Roll: Another orientation estimate calculated from the acceleration values.
-
Delay: The sketch waits 200 milliseconds between displayed readings.
When the sensor is stationary, gravity typically contributes approximately 9.81 m/sยฒ across the combined axes. An individual axis may show close to +9.81 or -9.81 m/sยฒ when aligned with gravity, while the other axes show values near zero.
The pitch and roll formulas depend on how the sensor is mounted. If the board is rotated or installed in a different orientation, you may need to change the formulas or coordinate mapping. These calculations also become less reliable during rapid movement because the accelerometer measures both gravity and motion-related acceleration.
Calculating Tilt With the ADXL345
An accelerometer can estimate tilt by comparing how gravity projects onto its axes. This is useful for a tilt alarm, a level indicator, or a basic orientation-sensitive switch.
For example, pitch can be estimated using:
Roll can be estimated using:
These equations use the axis values as inputs. Since the ratios are dimensionless, the same equations work whether the acceleration values are expressed in g or m/sยฒ, provided all axes use the same units.
For a simple tilt alarm, compare the calculated angle against a threshold. For example, you could activate an LED when the absolute pitch exceeds 30 degrees. Add filtering or averaging if the output fluctuates near the threshold.
Do not treat accelerometer-only pitch and roll as accurate orientation measurements during strong acceleration, vibration, or rapid rotation. For those applications, additional filtering or a sensor that combines an accelerometer with a gyroscope may be more appropriate.
Tap and Double-Tap Detection With the ADXL345
The ADXL345 includes hardware that can detect single-tap and double-tap events. Instead of continuously checking every acceleration sample in the Arduino sketch, you can configure the sensor to generate an interrupt when it detects a tap.
The sensor uses configurable thresholds and timing parameters to decide whether an acceleration event counts as a tap. These values need tuning for the physical device, mounting method, and force of the tap.
The example below uses the sensor's registers directly over I2C. It configures tap detection and free-fall detection, then polls the interrupt source register to identify events. It does not require the Adafruit acceleration library, but it does use the Arduino Wire library.
Arduino code for tap and free-fall events
#include <Wire.h>
const byte ADXL345_ADDR = 0x53;
const byte INT_SOURCE = 0x30;
const byte INT_ENABLE = 0x2E;
void writeRegister(byte reg, byte value) {
Wire.beginTransmission(ADXL345_ADDR);
Wire.write(reg);
Wire.write(value);
Wire.endTransmission();
}
byte readRegister(byte reg) {
Wire.beginTransmission(ADXL345_ADDR);
Wire.write(reg);
if (Wire.endTransmission(false) != 0) {
return 0;
}
Wire.requestFrom(ADXL345_ADDR, (byte)1);
if (Wire.available()) {
return Wire.read();
}
return 0;
}
void setup() {
Serial.begin(115200);
Wire.begin();
// Confirm that the connected device is an ADXL345.
if (readRegister(0x00) != 0xE5) {
Serial.println("ADXL345 not detected. Check wiring.");
while (1) {
delay(10);
}
}
// Standby before configuring registers.
writeRegister(0x2D, 0x00);
// Full-resolution mode, +/- 2g range.
writeRegister(0x31, 0x08);
// Output data rate: 100 Hz.
writeRegister(0x2C, 0x0A);
// Tap configuration.
writeRegister(0x1D, 0x30); // Tap threshold
writeRegister(0x21, 0x10); // Tap duration
writeRegister(0x22, 0x10); // Double-tap latency
writeRegister(0x23, 0xA0); // Double-tap window
writeRegister(0x2A, 0x07); // Enable tap detection on X, Y, Z
// Free-fall configuration.
writeRegister(0x28, 0x07); // Threshold: about 0.44g
writeRegister(0x29, 0x14); // Minimum duration: 100 ms
// Clear any pending interrupt status.
readRegister(INT_SOURCE);
// Enable single tap, double tap and free-fall interrupts.
writeRegister(INT_ENABLE, 0x64);
// Start measurement mode.
writeRegister(0x2D, 0x08);
Serial.println("Tap and free-fall detection ready");
}
void loop() {
byte source = readRegister(INT_SOURCE);
if (source & 0x40) {
Serial.println("Single tap detected");
}
if (source & 0x20) {
Serial.println("Double tap detected");
}
if (source & 0x04) {
Serial.println("Free-fall event detected");
}
delay(10);
}
How this code works
-
The device ID register is checked first. The ADXL345 returns
0xE5when read from register0x00. -
The sensor is placed in standby while its settings are configured.
-
The tap threshold, duration, latency, and window registers determine which tap events the sensor recognises.
-
The free-fall threshold and duration registers determine when a free-fall event is triggered.
-
The interrupt-enable register activates single-tap, double-tap, and free-fall detection.
-
The interrupt-source register is checked repeatedly to determine which events have occurred.
The threshold and timing values are starting points, not universal settings. For example, the free-fall threshold register uses a scale of 62.5 mg per least significant bit, while the free-fall time register uses 5 ms per step. Adjust the values based on the application and test results.
Important: This example polls the interrupt-source register instead of using the INT1 or INT2 pins as hardware interrupts. For a battery-powered or timing-sensitive application, connect an interrupt output to a suitable microcontroller pin and use an interrupt service routine or event flag. Read the sensor's interrupt documentation before changing interrupt mapping or polarity.
The default I2C address in this sketch is 0x53. If the sensor's SDO/ALT ADDRESS pin is configured high, the address may instead be 0x1D.
Common ADXL345 Problems and Fixes
The Arduino cannot detect the sensor
Check the power supply, ground, SDA and SCL connections. On an Arduino Uno, SDA is A4 and SCL is A5. Verify the I2C address and confirm that the breakout supports the voltage you are applying.
Acceleration readings look incorrect
Make sure the sensor is mounted securely and that the code uses the correct units. When stationary, the magnitude of the three-axis acceleration should be close to 9.81 m/sยฒ under normal conditions. Large deviations may indicate incorrect wiring, a damaged sensor, an unsuitable range setting, or calibration issues.
Tilt readings jump around
Small fluctuations are normal. Mechanical vibration and movement can affect the acceleration values. Try averaging several readings or applying a low-pass filter. If the sensor is moving quickly, acceleration-based tilt calculations may no longer represent the true orientation.
Tap detection triggers too often
Reduce the tap sensitivity by adjusting the threshold, duration, latency, and window settings. The ideal values depend on how firmly the device is mounted and how it is tapped. Test with the final enclosure and mounting arrangement.
Free-fall detection does not trigger
Free-fall detection depends on the acceleration dropping below the configured threshold for the required duration. A short drop may not meet the timing conditions, and vibrations or mounting constraints may affect the readings. Test safely using a controlled setup and protect the sensor from impact.
Do not use a hobby accelerometer as the sole safety mechanism for equipment where a missed detection could cause injury or damage.
ADXL345 vs ADXL335 vs MPU6050
These three sensors are used in motion-related electronics projects, but they serve different purposes.
|
Feature |
ADXL345 |
ADXL335 |
MPU6050 |
|---|---|---|---|
|
Sensor type |
Digital accelerometer |
Analog accelerometer |
Accelerometer and gyroscope |
|
Axes |
3-axis |
3-axis |
3-axis accelerometer plus 3-axis gyroscope |
|
Interface |
I2C or SPI |
Analog outputs |
I2C |
|
Tap detection |
Built-in hardware function |
Requires external processing |
Requires software processing |
|
Free-fall detection |
Built-in hardware function |
Requires external processing |
Requires software processing |
|
Best suited for |
Digital acceleration, tilt and event detection |
Analog acceleration measurement |
Projects that need acceleration and angular velocity |
Choose the ADXL345 when you want digital readings and built-in motion-event detection. The ADXL335 is useful when an analog output is preferred. Choose the MPU6050 when you need both acceleration and gyroscope measurements for applications such as motion tracking and orientation estimation.
Get the ADXL345 Accelerometer
The ADXL345 3-Axis Accelerometer is a useful option for Arduino and other compatible microcontroller projects that need digital acceleration readings, tilt estimation, or event detection.
Before connecting the module, check its pinout, supported input voltage, and logic-level compatibility. For tap and free-fall applications, test the configured thresholds and timing parameters with the actual device mounting and operating conditions.
Conclusion
The ADXL345 is a versatile digital accelerometer for measuring movement along three axes. Its I2C interface makes it straightforward to connect to an Arduino, while its built-in tap, double-tap, and free-fall detection features reduce the amount of signal processing needed in simple applications.
Start by reading the X, Y, and Z acceleration values, then use them to estimate tilt. Once the basic setup works, configure the sensor's event-detection registers and tune their thresholds for your project.
For dependable results, verify the breakout's voltage requirements, calibrate the sensor where necessary, and test the final setup under realistic conditions.
Excerpt
Frequently Asked Questions
1. What is the ADXL345 used for?
The ADXL345 measures acceleration along the X, Y, and Z axes. It is used for tilt sensing, motion monitoring, impact detection, vibration experiments, and projects that need built-in single-tap, double-tap, or free-fall detection.
2. What is the I2C address of the ADXL345?
The default 7-bit I2C address is 0x53 when the SDO/ALT ADDRESS pin is low. When that pin is high, the address can be 0x1D. Check the breakout board's documentation if the sensor is not detected.
3. Can the ADXL345 measure angles?
It can estimate pitch and roll from acceleration values when gravity is the dominant acceleration. However, it does not directly measure angles. Rapid movement and vibration can affect the estimates, so more advanced applications may need filtering or gyroscope data.
4. How do I detect a fall?
Configure the ADXL345's free-fall threshold and duration registers, then enable its free-fall event interrupt. The sensor detects when acceleration across the axes remains below the configured threshold for the required time. The settings must be tested and tuned for the application.
5. Does the ADXL345 work with ESP32?
Yes. The ADXL345 can communicate with an ESP32 over I2C. Connect SDA and SCL to suitable ESP32 GPIO pins, share ground, and ensure the sensor breakout's supply and logic levels are compatible with the ESP32's 3.3V I/O.
0x53 when the SDO/ALT ADDRESS pin is low. When that pin is high, the address can be 0x1D. Check the breakout board's documentation if the sensor is not detected.