Engineers Garage

  • Electronic Projects & Tutorials
    • Electronic Projects
      • Arduino Projects
      • AVR
      • Raspberry pi
      • ESP8266
      • BeagleBone
      • 8051 Microcontroller
      • ARM
      • PIC Microcontroller
      • STM32
    • Tutorials
      • Audio Electronics
      • Battery Management
      • Brainwave
      • Electric Vehicles
      • EMI/EMC/RFI
      • Hardware Filters
      • IoT tutorials
      • Power Tutorials
      • Python
      • Sensors
      • USB
      • VHDL
    • Circuit Design
    • Project Videos
    • Components
  • Articles
    • Tech Articles
    • Insight
    • Invention Stories
    • How to
    • What Is
  • News
    • Electronic Product News
    • Business News
    • Company/Start-up News
    • DIY Reviews
    • Guest Post
  • Forums
    • EDABoard.com
    • Electro-Tech-Online
    • EG Forum Archive
  • DigiKey Store
    • Cables, Wires
    • Connectors, Interconnect
    • Discrete
    • Electromechanical
    • Embedded Computers
    • Enclosures, Hardware, Office
    • Integrated Circuits (ICs)
    • Isolators
    • LED/Optoelectronics
    • Passive
    • Power, Circuit Protection
    • Programmers
    • RF, Wireless
    • Semiconductors
    • Sensors, Transducers
    • Test Products
    • Tools
  • Learn
    • eBooks/Tech Tips
    • Design Guides
    • Learning Center
    • Tech Toolboxes
    • Webinars & Digital Events
  • Resources
    • Digital Issues
    • EE Training Days
    • LEAP Awards
    • Podcasts
    • Webinars / Digital Events
    • White Papers
    • Engineering Diversity & Inclusion
    • DesignFast
  • Guest Post Guidelines
  • Advertise
  • Subscribe

RPi Python Programming 26 – Interfacing ADXL345 accelerometer sensor with Raspberry Pi

By Nikhil Agnihotri June 10, 2025

In the previous tutorial, we discussed synchronous serial communication in Raspberry Pi using I2C protocol. In this tutorial, we will use the I2C interface of Raspberry Pi to communicate with a digital sensor. The digital sensor that we will talk with is the ADXL345 accelerometer. ADXL345 is a small, ultra-low power, 3-axis accelerometer sensor that is used in electronic control systems of mobile device applications like mobile handsets, smartphones, gaming devices, pointing devices, personal navigation devices, hard drive protection, medical and industrial instrumentation.

ADXL345 accelerometer
ADXL345 is a 3-axis MEMS capacitive digital accelerometer sensor. It has a user-selectable range up to +/-16g, a maximum output resolution of 13 bits, sensitivity of 3.9 mg/LSB, and a maximum output data rate of 3200 Hz. It is a digital sensor in a 14-lead package that outputs sensor data through I2C and SPI interfaces. ADXL345 measures static acceleration due to gravity as well as dynamic acceleration resulting from motion or shock. It can be used to sense linear acceleration in 3 axes, tilt and free fall of an object. The sensor also has two interrupt pins and supports built-in sensing functions like free-fall detection and tapping by mapping sensing functions to its interrupt pins. ADXL345 can detect the presence or lack of motion by comparing acceleration values to user-defined thresholds.

The most basic thing that is done with any accelerometer sensor is getting the acceleration values. The ADXL345 sensor is a digital sensor, so it has several built-in registers that can be read and written over I2C or SPI. By reading and writing data to these registers, a controller/computer can configure the sensor (like set different measurement range, data transfer rate, sensitivity, and resolution), read acceleration values, set thresholds, map interrupts, and use built-in sensing functions.

ADXL345 offers four measurement range: +/-2g, +/-4g, +/-8g, and +/-16g. The default measurement range is +/-2g, which can be used to sense acceleration up to 19.6 m/s2 in either direction along each axis. The available resolutions are 10-bit for +/-2g, 11-bit for +/-4g, 12-bit for +/-8g and 13-bit for +/-16g range. The default resolution is 10-bit, which for +/-2g (default) range allows sensitivity of 3.9mg/LSB. The default data rate is 100 Hz. All these configurations can be changed or set by writing data to built-in registers of ADXL345. A controller/computer can read acceleration by reading values from registers 0x32 to 0x37. Learn more about the ADXL345 accelerometer sensor, its various technical specifications, and its practical implications.

ADXL345 Accelerometer Sensor Module

Example of ADXL345 accelerometer sensor module.

Interfacing ADXL345 with Raspberry Pi
Interfacing the ADXL345 sensor with Raspberry Pi is pretty straightforward. The digital sensor communicates data over I2C and SPI interfaces. In any ADXL345 sensor module, pins for both interfaces (I2C/TWI and SPI) and interrupt pins are available. The sensor supports both 3-wire and 4-wire SPI. Raspberry Pi has both I2C and SPI interfaces, and either can be used to talk with ADXL345.

In this tutorial, we are using I2C to talk with ADXL345.  The user I2C of Raspberry Pi is available at pins GPIO2 (Board Pin No. 3) and GPIO3 (Board Pin No. 5). GPIO2 is Serial Data (SDA) line, and GPIO3 is a Serial Clock (SCL) line of the I2C1. These I2C pins are internally pulled up to 3.3V via 1.8 k ohms resistors. So, the I2C lines of ADXL345 can be directly connected to the user’s I2C port of Raspberry Pi without the need for any external circuitry.

I2C pins on Raspberry Pi

I2C interface on Raspberry Pi’s GPIO header.

ADXL345 requires an operating voltage of 2.5V that can range from 2.0V to 3.6V. It consumes approximately 30 uA for a data transfer rate of less than 10 Hz and around 140 uA for data transfer rates above 100 Hz. The ADXL345 sensor can be supplied 3.3V supply with common ground from the Raspberry Pi itself, while the I2C channels can be directly connected without the need for any external pull-up circuit.

Circuit diagram for interfacing ADXL345 with Raspberry Pi

Circuit diagram for interfacing ADXL345 with Raspberry Pi.

I2C communication in Raspberry Pi
Raspberry Pi has two I2C ports, I2C0 and I2C1. The I2C1 is available for users, while I2C0 remains reserved for reading EEPROM of Raspberry Pi’s add-on boards called Hardware on The Top (HAT) boards. In older versions (256 MB) of Raspberry Pi, I2C0 was available for users and I2C1 was reserved for HAT boards. The ports were inversed from 512 MB versions of Raspberry Pi.

The I2C ports are connected to built-in Broadcom Serial Controllers (BSC) of Raspberry Pi that support standard-mode I2C-compatible serial communication with data speed up to 400 Kbps. The user I2C1 is disabled by default. It needs to be enabled through Raspberry Pi configurations. Once enabled, the user I2C port is listed as one of the available Linux devices in Raspberry Pi.

On Raspberry Pi, the I2C bus can be accessed in a Python script using the SMBus library. SMBus is a subset of the I2C interface. The Python library for SMBus can be used to communicate with I2C based devices. The latest version of this library is SMbus2. For serial I2C communication with devices like ADXL345, SMBus() method of the library can be used to configure I2C port on Raspberry Pi; read_byte(), read_byte_data() and read_block_data() methods can be used to read data from I2C device; write_byte(), write_byte_data(), and write_block_data() methods can be used to write data to I2C device. Learn more about the I2C protocol and Raspberry Pi’s I2C interface.

Talking with ADXL345 using Raspberry Pi
The I2C1 port of Raspberry Pi can communicate with data speeds up to 400 kbps. The ADXL345 sensor has a maximum output data rate of 3200 Hz or 3.2 kbps. So, the sensor can easily communicate with Raspberry Pi. The output data rate of ADXL345 can be set by writing to BW_RATE (0x2C) register. The I2C voltage levels of both Raspberry Pi and ADXL345 are 3.3V compatible, so there is no need for any logic level shifter between Raspberry Pi and ADXL345. The SDA and SCL lines of both can be directly connected.

Interfacing-ADXL345-Raspberry-Pi-2

ADXL345 has an ALT address pin that can be hardwired to set the I2C address of this digital sensor. If the ALT ADDRESS pin is pulled high in a module, the 7-bit I2C address for the device is 0x1D, followed by the R/W bit. This translates to 0x3A for a write and 0x3B for a read. If the ALT ADDRESS pin is connected to ground, the 7-bit I2C address for the device is 0x53 (followed by the R/W bit). This translates to 0xA6 for a write and 0xA7 for a read.

ADXL345-Accelerometer-Pin-Diagram

Pin Diagram of ADXL345 accelerometer sensor.

In a module, the ALT ADDRESS pin is already pulled high or low. The I2C address of the ADXL345 sensor can, therefore, be found by scanning for available I2C devices on Raspberry Pi on connecting the sensor. A scan for I2C devices can be conducted on Raspberry Pi using i2c-tools. First of all, install the i2c-tools by running the following command in the Raspberry Pi Terminal:
sudo apt-get install -y i2c-tools

Now run the following command to scan connected I2C slaves:
sudo i2cdetect -y 1

The i2c-detect is a tool that scans the I2C user port and returns the I2C addresses of the connected slave devices. The tool returns a table of addresses of connected I2C slave devices, as shown in the image below:

Scanning I2C devices on Raspberry Pi using i2c-tools

On connecting ADXL345, the i2c-tools must return a table containing either 0x53 or 0x1D as the I2C address. After verifying the I2C address of the ADXL345, I2C port 1 of Raspberry Pi can be used to talk with ADXL345.

The ADXL345 has 8-bit built-in registers. Most of these registers can be read/write while some are read-only. A table of these registers is given below:

(click to enlarge)

Configuring ADXL345 sensor
Below are listed a few simple steps to configure the ADXL345 sensor for serial communication.

  1. Set power mode and data transfer rate by writing to the 0x2C register. This register has the following bits:

If LOW_POWER bit is set to 0, the ADXL345 works in normal mode, and if it is set to 1, ADXL345 works are reduced power modes, in which there is higher noise. The bits D3 to D0 selects the data transfer rate according to the following table:

2. Set the data format by writing to 0x31 register. This register has the following bits:If the SELF-TEST bit is set to 1, a self-test force is applied to the sensor, causing a shift in the output data. If it is set to 0, the self-test force is disabled. If the SPI bit is set to 1, ADXL345 uses 3-wire SPI mode; otherwise, if set to 0, it uses 4-wire SPI mode. If INT_INVERT bit is set to 0, it sets the interrupts to active high, and if it is set to 1, it sets the interrupts to active low. If FULL_RES bit is set to 1, the sensor outputs full-resolution value (10-bit for +/- 2g; 11-bit for +/-4g; 12-bit for +/- 8g; 13-bit for +/- 16g) otherwise if it is set to 0, default 10-bit is used. If the justify bit is set to 1, acceleration values in registers 0x32 to 0x37 are left-justified; otherwise, if it is set to 0, values are right-justified. The following image shows the data format of data-value registers with left and right justification and position of LSB or MSB accordingly for different measurement range.

 

The range bits D1 and D0 selects the measurement range according to the following table

  1. Set power saving features by writing to 0x2D register. This register has the following bits:

If the link bit is set to 1, activity and inactivity functions are serially linked (activity function is delayed until inactivity function is detected); otherwise, if it is set to 0, both functions are concurrent. The inactivity function refers to a situation when acceleration is below the THRESH_INACT value (0x25 register) for at least the time indicated by TIME_INACT (0x26 register).

If the link bit is set and the AUTO_SLEEP bit is set to 1, it enables the auto-sleep functionality. In this mode, the ADXL345 automatically switches to sleep mode if the inactivity function is enabled and inactivity is detected. If activity is also enabled, the ADXL345 automatically wakes up from sleep after detecting activity and returns to operation at the output data rate set in the BW_RATE register. If the AUTO_SLEEP bit is set to 0, it disables automatic switching to sleep mode. If the link bit is not set, the AUTO_SLEEP feature is disabled, and setting the AUTO_SLEEP bit does not have an impact on device operation.

If Measure bit is set to 1, ADXL345 operates in measurement mode; otherwise, if it is set to 0, ADXL345 operates in standby mode. If Sleep bit is set to 1, ADXL345 operates in sleep mode; otherwise, if it is set to 0, ADXL345 operates in normal mode. Sleep mode suppresses DATA_READY, stops transmission of data to FIFO, and switches the sampling rate to one specified by the wake-up bits. In sleep mode, only the activity function can be used. The wake-up bits control the frequency of reading in sleep mode according to the following table:

Reading acceleration values from ADXL345
The acceleration along the x-axis is read from registers 0x32 and 0x33; acceleration along Y-axis is read from registers 0x34 and 0x35, and acceleration along Z-axis is read from registers 0x36 and 0x37. The raw values are 16-bit in two’s complement form. The resolution left or right justification of the values and measurement range is set as per the value written to the 0x31 register of ADXL345. Accordingly, the 16-bit values must be masked in a user program.

Once the raw 10-bit/11-bit/12-bit/13-bit acceleration values are derived, the acceleration in the gravity unit can be calculated by multiplying the raw values to 4 mg i.e., by multiplying to 0.004. This way, we get the value of acceleration along X-, Y- and Z- axes in G. These values can be multiplied by 9.8 to convert the acceleration in gravity unit to acceleration in m/s2 (SI units).

 

It should be noted that the acceleration read by ADXL345 includes both static acceleration (due to gravity of Earth) as well as dynamic acceleration (due to motion or shock). If the sensor has to be used to detect the motion of an object ignoring static acceleration, appropriate offset values must be set in registers 0x1E to 0x20.

The ADXL345 has built-in activity, inactivity, tapping, and free-fall detection sensing functions. These built-in functions can be enabled by setting 0x2E register and mapped to interrupt pins by setting 0x2F registers. These built-in sensing functions of ADXL345 are provided to reduce overload on interfaced controller/computer and are useful in electronic control applications.

Configuring ADXL345 to +/- 2g, 10-bit resolution and reading acceleration using Python
Hopefully, you must have an interfaced ADXL345 accelerometer with Raspberry Pi by now and found out if its I2C address is 0x53 or 0x1D. The ADXL345 sensor used in this tutorial has an I2C address of 0x53. The following Python script configures the ADXL345 sensor to +/- 2g measurement range and uses a 10-bit resolution. The script reads acceleration data of all axes, converts it to gravity units, and finally convert it to SI units.

The script imports the SMBus library for serial I2C communication with ADXL345, time and sleep libraries for providing time delays, and sys library to control script termination. The smbus() method is used to configure the script to communicate over I2C port 1.

First of all, data (0x0B) is written to 0x2C register of ADXL345 over I2C address 0x53 to configure the ADXL345 to use a data output rate of 200 bps. The data is written using bus.write_byte_data() method of the SMbus library. Then, the current status of 0x31 register of ADXL345 (that is at I2C address 0x53) is read using bus.read_byte_data() method. The read value is masked and written back to the 0x31 register of ADXL345 to use the right justification, default 10-bit resolution, and +/- 2g measurement range. The 0x2D register of ADXL345 is set to 0x08 to configure the sensor to operate in measurement mode.

A user-defined function getAxes() is defined that reads acceleration values, return and print them on the console. The function body uses bus.read_i2c_block_data() method to read data from 0x32 to 0x37 registers of ADXL345. The read bytes are stored in variables that are defined to store acceleration values in x, y, and z axes. The two’s complement is removed by bit-masking and bit-shifting the values. The derived raw values are converted to gravity unit by multiplying by 0.004 as the sensor has a sensitivity of 4mg/LSB. The values in the gravity unit are converted to the SI unit by multiplying by 9.80665. Finally, the rounded values of acceleration along x, y, and z axes are printed to the console and returned by the function.

The getAxes() function is called in a try-except statement where the function is called infinitely at a delay of 2 seconds until the Python script detects a keyboard interrupt. On detecting a keyboard interrupt, the script is terminated using sys.exit() function.

Results
Reading raw sensor data from ADXL345

Reading acceleration in SI units from ADXL345:

In the next tutorial, we will discuss the basics of the SPI protocol.


Filed Under: Featured Contributions, Raspberry pi

 

Next Article

← Previous Article
Next Article →

Questions related to this article?
👉Ask and discuss on Electro-Tech-Online.com and EDAboard.com forums.



Tell Us What You Think!! Cancel reply

You must be logged in to post a comment.

EE TECH TOOLBOX

“ee
Tech Toolbox: Internet of Things
Explore practical strategies for minimizing attack surfaces, managing memory efficiently, and securing firmware. Download now to ensure your IoT implementations remain secure, efficient, and future-ready.

EE Learning Center

EE Learning Center
“engineers
EXPAND YOUR KNOWLEDGE AND STAY CONNECTED
Get the latest info on technologies, tools and strategies for EE professionals.

HAVE A QUESTION?

Have a technical question about an article or other engineering questions? Check out our engineering forums EDABoard.com and Electro-Tech-Online.com where you can get those questions asked and answered by your peers!


RSS EDABOARD.com Discussions

  • Reducing "shoot-through" in offline Full Bridge SMPS?
  • High Side current sensing
  • How to simulate power electronics converter in PSpice?
  • Voltage mode pushpull is a nonsense SMPS?
  • Layout IRN reduction in Comparator

RSS Electro-Tech-Online.com Discussions

  • Back to the old BASIC days
  • Parts required for a personal project
  • PIC KIT 3 not able to program dsPIC
  • Failure of polypropylene motor-run capacitors
  • Siemens large industrial PLC parts

Featured – RPi Python Programming (27 Part)

  • RPi Python Programming 21: The SIM900A AT commands
  • RPi Python Programming 22: Calls & SMS using a SIM900A GSM-GPRS modem
  • RPi Python Programming 23: Interfacing a NEO-6MV2 GPS module with Raspberry Pi
  • RPi Python Programming 24: I2C explained
  • RPi Python Programming 25 – Synchronous serial communication in Raspberry Pi using I2C protocol
  • RPi Python Programming 26 – Interfacing ADXL345 accelerometer sensor with Raspberry Pi

Recent Articles

  • What is AWS IoT Core and when should you use it?
  • AC-DC power supply extends voltage range to 800 V DC
  • Infineon’s inductive sensor integrates coil system driver, signal conditioning circuits and DSP
  • Arm Cortex-M23 MCU delivers 87.5 µA/MHz active mode
  • STMicroelectronics releases automotive amplifiers with in-play open-load detection

EE ENGINEERING TRAINING DAYS

engineering

Submit a Guest Post

submit a guest post
Engineers Garage
  • Analog IC TIps
  • Connector Tips
  • Battery Power Tips
  • DesignFast
  • EDABoard Forums
  • EE World Online
  • Electro-Tech-Online Forums
  • EV Engineering
  • Microcontroller Tips
  • Power Electronic Tips
  • Sensor Tips
  • Test and Measurement Tips
  • 5G Technology World
  • Subscribe to our newsletter
  • About Us
  • Contact Us
  • Advertise

Copyright © 2025 WTWH Media LLC. All Rights Reserved. The material on this site may not be reproduced, distributed, transmitted, cached or otherwise used, except with the prior written permission of WTWH Media
Privacy Policy

Search Engineers Garage

  • Electronic Projects & Tutorials
    • Electronic Projects
      • Arduino Projects
      • AVR
      • Raspberry pi
      • ESP8266
      • BeagleBone
      • 8051 Microcontroller
      • ARM
      • PIC Microcontroller
      • STM32
    • Tutorials
      • Audio Electronics
      • Battery Management
      • Brainwave
      • Electric Vehicles
      • EMI/EMC/RFI
      • Hardware Filters
      • IoT tutorials
      • Power Tutorials
      • Python
      • Sensors
      • USB
      • VHDL
    • Circuit Design
    • Project Videos
    • Components
  • Articles
    • Tech Articles
    • Insight
    • Invention Stories
    • How to
    • What Is
  • News
    • Electronic Product News
    • Business News
    • Company/Start-up News
    • DIY Reviews
    • Guest Post
  • Forums
    • EDABoard.com
    • Electro-Tech-Online
    • EG Forum Archive
  • DigiKey Store
    • Cables, Wires
    • Connectors, Interconnect
    • Discrete
    • Electromechanical
    • Embedded Computers
    • Enclosures, Hardware, Office
    • Integrated Circuits (ICs)
    • Isolators
    • LED/Optoelectronics
    • Passive
    • Power, Circuit Protection
    • Programmers
    • RF, Wireless
    • Semiconductors
    • Sensors, Transducers
    • Test Products
    • Tools
  • Learn
    • eBooks/Tech Tips
    • Design Guides
    • Learning Center
    • Tech Toolboxes
    • Webinars & Digital Events
  • Resources
    • Digital Issues
    • EE Training Days
    • LEAP Awards
    • Podcasts
    • Webinars / Digital Events
    • White Papers
    • Engineering Diversity & Inclusion
    • DesignFast
  • Guest Post Guidelines
  • Advertise
  • Subscribe