Documentation

ShillehTek ADXL345 3-Axis Accelerometer Sensor Arduino Raspberry Pi Tilt | ShillehTek Product Manual
Documentation / ShillehTek ADXL345 3-Axis Accelerometer Sensor Arduino Raspberry Pi Tilt | ShillehTek Product Manual

ShillehTek ADXL345 3-Axis Accelerometer Sensor Arduino Raspberry Pi Tilt | ShillehTek Product Manual

Overview

The ADXL345 is a small, low-power 3-axis digital accelerometer that measures static gravity (for tilt sensing) and dynamic acceleration from motion or shock. It outputs X, Y, and Z acceleration data over I2C or SPI, with selectable measurement ranges from plus/minus 2g all the way up to plus/minus 16g and 13-bit resolution in full-resolution mode.

This pre-soldered ShillehTek module makes the ADXL345 easy to drop into Arduino, Raspberry Pi, ESP32, and Pico projects. It's especially popular for Klipper 3D printer resonance testing and input-shaping calibration, motion-activated alarms, tilt-controlled robots, vibration loggers, and impact detection.

Built-in features go well beyond just reading acceleration: there's hardware tap and double-tap detection, free-fall detection, activity and inactivity sensing, and a 32-level FIFO buffer that lets you stream data without needing the host to read every sample in real time.

At a Glance

Sensor IC
Analog Devices ADXL345
Axes
3 (X, Y, Z)
Range
+/- 2g, 4g, 8g, 16g
Resolution
13-bit (full-res)
Interface
I2C or SPI
Supply Voltage
3V - 5V (on-board LDO)

Specifications

Parameter Value
Sensor IC Analog Devices ADXL345
Module Supply Voltage 3V to 5V (LDO regulator on board)
Sensor Operating Voltage 2.0V to 3.6V (chip), 3.3V regulated
Operating Current 40 microamps (measurement mode)
Standby Current 0.1 microamps
Measurement Ranges +/- 2g, +/- 4g, +/- 8g, +/- 16g (selectable)
Resolution 10-bit fixed, or 13-bit at full resolution
Sensitivity (full-res, +/-2g) 256 LSB / g
Output Data Rates 0.1 Hz to 3200 Hz
I2C Speed Up to 400 kHz (Fast Mode)
I2C Addresses 0x53 (SDO LOW) or 0x1D (SDO HIGH)
SPI Speed Up to 5 MHz (3- or 4-wire)
FIFO Buffer 32 samples (X, Y, Z each)
Built-in Functions Tap, double-tap, free-fall, activity, inactivity

Pinout Diagram

ShillehTek ADXL345 accelerometer module pinout showing SCL, SDA, SDO, INT2, INT1 on one side and 5V, 3V3, GND, VS, CS on the other side for I2C and SPI use

Wiring Guide

Arduino Wiring (I2C)

Wire the ADXL345 to an Arduino Uno over I2C using SDA (A4) and SCL (A5). The on-board LDO accepts 5V on the 5V pin and regulates it to 3.3V for the chip, so it's safe to power straight from Arduino. CS must be tied HIGH to enable I2C mode.

ADXL345 Pin Arduino Pin
5V 5V
GND GND
SDA A4 (SDA)
SCL A5 (SCL)
CS 3.3V (tied HIGH for I2C)
Tip: The default I2C address with SDO unconnected (or pulled LOW) is 0x53. If you need a second ADXL345 on the same bus, tie SDO HIGH on one of them to switch its address to 0x1D.
Note: Even though the Arduino is 5V, the ADXL345 chip itself is 3.3V. The on-board regulator handles power. The I2C lines are 3.3V tolerant on Arduino reads, and the Arduino's 5V pull-ups work fine with the ADXL345's 3.3V outputs because of the way I2C open-drain signalling works.

ESP32 Wiring (I2C)

The ESP32 is a 3.3V device, so the ADXL345 module is a perfect match. Use the default I2C pins (GPIO 21 for SDA, GPIO 22 for SCL) or any other GPIO pair you assign in software.

ADXL345 Pin ESP32 Pin
3V3 3.3V
GND GND
SDA GPIO 21
SCL GPIO 22
CS 3.3V (tied HIGH for I2C)
Tip: Power the ADXL345 from the ESP32's 3V3 pin (using the module's 3V3 input) for the cleanest power. You can also use the 5V pin if the ESP32 is USB-powered.

Raspberry Pi Wiring (I2C)

Wire the ADXL345 to the Raspberry Pi's hardware I2C bus. Make sure I2C is enabled in raspi-config first. The Pi's GPIO is 3.3V and matches the ADXL345 perfectly.

ADXL345 Pin Raspberry Pi Pin
3V3 Pin 1 (3.3V)
GND Pin 6 (GND)
SDA Pin 3 (GPIO 2 - SDA)
SCL Pin 5 (GPIO 3 - SCL)
CS Pin 1 (3.3V) - tied HIGH for I2C
Klipper note: If you're using this module for Klipper input shaping on a 3D printer, some board revisions ship with an R4 pull-down resistor that fights Klipper's CS handling. If your printer host fails to detect the accelerometer over SPI, removing R4 (or using an alternate header for CS) is a known fix.
Tip: After wiring, run i2cdetect -y 1 on the Pi. You should see device 0x53 (or 0x1D if SDO is tied HIGH) in the address grid.

Raspberry Pi Pico Wiring (I2C)

The Pico has two I2C buses. The wiring below uses I2C0 on GP4 (SDA) and GP5 (SCL). The Pico is 3.3V so it pairs cleanly with the ADXL345.

ADXL345 Pin Pico Pin
3V3 Pin 36 (3V3 OUT)
GND Pin 38 (GND)
SDA Pin 6 (GP4 - I2C0 SDA)
SCL Pin 7 (GP5 - I2C0 SCL)
CS Pin 36 (3V3) - tied HIGH for I2C
Tip: The Pico's internal pull-ups are usually enough for short jumper-wire I2C runs. For longer wires or if you see noisy data, add 4.7k external pull-ups from SDA and SCL to 3.3V.

Code Examples

Arduino

adxl345_arduino.ino
// ADXL345 3-Axis Accelerometer - Arduino I2C Example
// Library: Adafruit ADXL345 (install via Library Manager)
// Wiring: SDA -> A4, SCL -> A5, 5V -> 5V, GND -> GND, CS -> 3.3V

#include 
#include 
#include 

Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345);

void setup() {
  Serial.begin(9600);
  Serial.println("ADXL345 starting...");

  if (!accel.begin()) {
    Serial.println("No ADXL345 detected. Check wiring and CS pin.");
    while (1);
  }

  accel.setRange(ADXL345_RANGE_4_G);
  Serial.println("ADXL345 ready.");
}

void loop() {
  sensors_event_t event;
  accel.getEvent(&event);

  Serial.print("X: "); Serial.print(event.acceleration.x); Serial.print(" m/s^2  ");
  Serial.print("Y: "); Serial.print(event.acceleration.y); Serial.print(" m/s^2  ");
  Serial.print("Z: "); Serial.print(event.acceleration.z); Serial.println(" m/s^2");

  delay(200);
}

Raspberry Pi (Python)

adxl345_rpi.py
#!/usr/bin/env python3
# ADXL345 - Raspberry Pi I2C Example
# Install: sudo apt install python3-smbus
# Wiring: SDA -> GPIO 2, SCL -> GPIO 3, 3V3 -> 3.3V, GND -> GND, CS -> 3.3V

import smbus2
import time

ADDR = 0x53          # default I2C address
POWER_CTL = 0x2D
DATA_FORMAT = 0x31
DATAX0 = 0x32
SCALE = 0.0039 * 9.80665  # +/-2g, full-res: 3.9 mg/LSB -> m/s^2

bus = smbus2.SMBus(1)

def setup():
    bus.write_byte_data(ADDR, DATA_FORMAT, 0x08)  # full-res, +/-2g
    bus.write_byte_data(ADDR, POWER_CTL, 0x08)    # measurement mode

def read_axes():
    raw = bus.read_i2c_block_data(ADDR, DATAX0, 6)
    x = int.from_bytes(raw[0:2], 'little', signed=True) * SCALE
    y = int.from_bytes(raw[2:4], 'little', signed=True) * SCALE
    z = int.from_bytes(raw[4:6], 'little', signed=True) * SCALE
    return x, y, z

setup()
try:
    while True:
        x, y, z = read_axes()
        print("X: {:6.2f}  Y: {:6.2f}  Z: {:6.2f}  m/s^2".format(x, y, z))
        time.sleep(0.2)
except KeyboardInterrupt:
    print("Stopped by user")

Raspberry Pi Pico (MicroPython)

adxl345_pico.py
# ADXL345 - Raspberry Pi Pico MicroPython Example
# Wiring: SDA -> GP4, SCL -> GP5, 3V3 -> 3V3 OUT, GND -> GND, CS -> 3V3

from machine import I2C, Pin
import time

ADDR = 0x53
POWER_CTL = 0x2D
DATA_FORMAT = 0x31
DATAX0 = 0x32
SCALE = 0.0039 * 9.80665  # +/-2g, full-res

i2c = I2C(0, sda=Pin(4), scl=Pin(5), freq=400000)

# Configure: full-res, +/-2g, then enable measurement mode
i2c.writeto_mem(ADDR, DATA_FORMAT, b'\x08')
i2c.writeto_mem(ADDR, POWER_CTL, b'\x08')

while True:
    raw = i2c.readfrom_mem(ADDR, DATAX0, 6)
    x = int.from_bytes(raw[0:2], 'little')
    y = int.from_bytes(raw[2:4], 'little')
    z = int.from_bytes(raw[4:6], 'little')
    # Convert unsigned to signed 16-bit
    if x > 32767: x -= 65536
    if y > 32767: y -= 65536
    if z > 32767: z -= 65536
    print("X: {:6.2f}  Y: {:6.2f}  Z: {:6.2f}  m/s^2".format(
        x * SCALE, y * SCALE, z * SCALE))
    time.sleep(0.2)

ESP32 (MicroPython)

adxl345_esp32.py
# ADXL345 - ESP32 MicroPython Example
# Wiring: SDA -> GPIO 21, SCL -> GPIO 22, 3V3 -> 3.3V, GND -> GND, CS -> 3.3V

from machine import I2C, Pin
import time

ADDR = 0x53
POWER_CTL = 0x2D
DATA_FORMAT = 0x31
DATAX0 = 0x32
SCALE = 0.0039 * 9.80665

i2c = I2C(0, sda=Pin(21), scl=Pin(22), freq=400000)

i2c.writeto_mem(ADDR, DATA_FORMAT, b'\x08')  # full-res, +/-2g
i2c.writeto_mem(ADDR, POWER_CTL, b'\x08')    # measurement mode

while True:
    raw = i2c.readfrom_mem(ADDR, DATAX0, 6)
    x = int.from_bytes(raw[0:2], 'little')
    y = int.from_bytes(raw[2:4], 'little')
    z = int.from_bytes(raw[4:6], 'little')
    if x > 32767: x -= 65536
    if y > 32767: y -= 65536
    if z > 32767: z -= 65536
    print("X: {:6.2f}  Y: {:6.2f}  Z: {:6.2f}  m/s^2".format(
        x * SCALE, y * SCALE, z * SCALE))
    time.sleep(0.2)

Frequently Asked Questions

What's the I2C address of the ADXL345?
The default address is 0x53 when SDO is unconnected or tied to GND. Tie SDO HIGH (to 3.3V) to change the address to 0x1D. This lets you use two ADXL345 modules on the same I2C bus.
Can I power the ADXL345 from 5V?
Yes. The ShillehTek module has an on-board low-dropout regulator. Connect 5V to the 5V pin and the regulator drops it to 3.3V for the sensor. You can also power directly from 3.3V using the 3V3 pin if your microcontroller supplies 3.3V.
Do I need to set CS HIGH to use I2C?
Yes. The CS pin selects between SPI mode (CS LOW) and I2C mode (CS HIGH). For I2C, tie CS to 3.3V. If CS is left floating, the chip may not respond. This is the most common reason an ADXL345 doesn't show up on i2cdetect.
What's the measurement range and how do I change it?
The ADXL345 supports four ranges: plus/minus 2g, 4g, 8g, and 16g. Set the range by writing the bottom two bits of the DATA_FORMAT register (0x31). Lower ranges (2g) give the highest sensitivity for tilt and small motion; higher ranges (16g) capture sharp impacts and shocks without clipping.
Can I use this module for Klipper input shaping?
Yes - the ADXL345 is the standard accelerometer for Klipper resonance testing on 3D printers. Wire it to a Raspberry Pi running Klipper over SPI (or to the printer board if it has an accelerometer port). Some board revisions need an R4 pull-down resistor removed for reliable Klipper detection - check the board if you have CS issues.
What library should I use on Arduino?
The Adafruit ADXL345 library (Adafruit_ADXL345_U) is the easiest. Install it via the Arduino Library Manager and pull in Adafruit_Sensor as a dependency. SparkFun also publishes a more feature-rich library that exposes tap, double-tap, and free-fall detection.
Why are my readings noisy or jumpy?
A few common causes: long unshielded jumper wires, missing or weak I2C pull-ups, vibration from a nearby motor or fan, or running at the maximum 3200 Hz output rate without filtering. Lower the output data rate to 100 Hz or 200 Hz, add a simple moving-average in software, and keep the wires short for clean readings.

Related Tutorials