How to Connect and Calibrate the ADXL345 with Arduino

Welcome to this tutorial on the ADXL345 accelerometer sensor and how to interface it with an Arduino. The ADXL345 is a popular 3-axis accelerometer that measures acceleration in three directions: X, Y, and Z. This sensor is often used in various applications, such as robotics, gaming, and wearable technology.

In this tutorial, we will walk you through the provided Arduino code, which demonstrates how to set up and calibrate the ADXL345 sensor. Calibration is an essential step to ensure accurate measurements. We'll discuss the code's functions, explain the sensor's configuration, and guide you through the calibration process for accurate data collection.

By the end of this tutorial, you'll have a better understanding of how the ADXL345 sensor works and how to calibrate it to achieve reliable acceleration data. This knowledge will be valuable in your Arduino-based projects that involve motion and orientation sensing.

Let's get started by examining the code and understanding how it communicates with the ADXL345 sensor, configures it, and calibrates it for accurate measurements.

Before reading the remainder, be sure to subscribe and support the channel if you have not!

Subscribe:

Youtube

Support:

https://www.buymeacoffee.com/mmshilleh

Remember you can purchase an ADXL345 at our Shop!

https://shillehtek.com/collections/all

Step 1-) Physical Connection:

You should setup I2C connection with the device as follows:

We need four jumper wires. In this case I am using a two sided ADXL and an Arduino Nano, but in reality you can use any ADXL model or Arduino controller as long as you match the connections!

Step 2-) Code:

Run the following code on the device

#include <Wire.h>

int ADXL345 = 0x53; // The ADXL345 sensor I2C address
float X_out, Y_out, Z_out; // Outputs
int X_offset = 0, Y_offset = 0, Z_offset = 0; // Offset values

void setup() {
  Serial.begin(9600);
  Wire.begin();
  configureADXL345(); // Configure the sensor
  // Note: You should calibrate upon re-powering the sensor
  // Uncomment if you want to calibrate
  // calibrateADXL345(); // Calibrate the sensor
}

void calibrateADXL345() {
  // You should calibrate with the positive axis pointed upwards against gravity
  // You should calibrate each axis separately and change the offset constant, 
  // You need to run this code three times if you want to calibrate all three axes
  float numReadings = 500;
  // float xSum = 0;
  // float ySum = 0;
  float zSum = 0;
  Serial.print("Beginning Calibration");
  Serial.println();
  for (int i = 0; i < numReadings; i++) {
    Serial.print(i);
    Serial.println();
    Wire.beginTransmission(ADXL345);
    Wire.write(0x32); // Start with register 0x32 (ACCEL_XOUT_H)
    Wire.endTransmission(false);
    Wire.requestFrom(ADXL345, 6, true);
    X_out = (Wire.read() | Wire.read() << 8);
    Y_out = (Wire.read() | Wire.read() << 8);
    Z_out = (Wire.read() | Wire.read() << 8);
    // xSum += X_out;
    // ySum += Y_out;
    zSum += Z_out;
  }
  //// 256 is the raw value for 1g, (we calibrate at 1g hence why we take the difference)

  // X_offset = (256 - xSum / numReadings) / 4;
  // Serial.print("X_offset= " );
  // Serial.print(X_offset);
  // Y_offset = (256 - ySum / numReadings) / 4;
  // Serial.print("Y_offset= " );
  // Serial.print(Y_offset);

  Z_offset = (256 - (zSum / numReadings)) / 4;
  Serial.print("Z_offset= " );
  Serial.print(Z_offset);
  Serial.println();
  delay(1000);
  // We need to add it to the offset channel respectively =
  // Once you write to the offset channel you do not need to do it again,
  // unless you unpower and power the device
  // Each offset address is different for X, Y, and Z

  // Wire.beginTransmission(ADXL345);
  // Wire.write(0x1E);
  // Wire.write(X_offset);
  // Wire.endTransmission();
  // Wire.beginTransmission(ADXL345);
  // Wire.write(0x1F);
  // Wire.write(Y_offset);
  // Wire.endTransmission();
  Wire.beginTransmission(ADXL345);
  Wire.write(0x20);
  Wire.write(Z_offset);
  Wire.endTransmission();
}

void configureADXL345() {
  Wire.beginTransmission(ADXL345);
  Wire.write(0x2D); // Access/ talk to POWER_CTL Register - 0x2D
  Wire.write(8); // Enable measurement (D3 bit high)
  Wire.endTransmission();
  delay(10);
}

void loop() {
  Wire.beginTransmission(ADXL345);
  Wire.write(0x32); // Start with register 0x32 (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(ADXL345, 6, true);
  X_out = (Wire.read() | Wire.read() << 8);
  X_out = X_out / 256;
  Y_out = (Wire.read() | Wire.read() << 8);
  Y_out = Y_out / 256;
  Z_out = (Wire.read() | Wire.read() << 8);
  Serial.print(Z_out);
  Z_out = Z_out / 256;

  Serial.print("Xa= ");
  Serial.print(X_out);
  Serial.print("   Ya= ");
  Serial.print(Y_out);
  Serial.print("   Za= ");
  Serial.println(Z_out);
  delay(500);
}

The code provided includes the following sections:

Setup: In the setup() function, the code initializes serial communication for debugging, sets up I2C communication, configures the ADXL345 sensor, and calls the calibration function. You should only call the calibration function initially when re-powering, then uncomment it in practice. The sensor is able to remember the calibration value as long as it remains on. See video above for further details on how to use this code for calibration.

Calibration: The calibrateADXL345() function is responsible for calibrating the sensor. Calibration should be performed with the positive axis (e.g., X, Y, Z) pointed upwards against gravity; you need to do one at a time in this code (room for improvement on the code level for sure). For example, when calibrating the Z-axis, the code collects data from the Z-axis (vertical) acceleration and calculates an offset value (Z_offset) based on the difference between the raw sensor values and a known value (256 for 1g). This offset is later applied to correct measurements and is written back to the sensor's register. You will need to uncomment and comment accordingly to calibrate the X and the Y. When the sensor is calibrated it should be as steady as possible, ideally using a calibration block.

Configuration: The configureADXL345() function sets up the ADXL345 sensor by accessing the POWER_CTL register to enable measurements.

Loop: In the loop() function, the code continuously reads acceleration data from the ADXL345 sensor. It sends an I2C request to get the raw acceleration values for the X, Y, and Z axes, converts these values to meaningful data, and prints them to the Serial Monitor. This code allows you to interface with the ADXL345 accelerometer, configure it, and calibrate it for accurate measurements of acceleration in multiple directions. You can further utilize this data in your Arduino projects, such as detecting motion or controlling devices based on orientation.

Conclusion

Hope this high-level overview of the code makes sense, you do not need to calibrate if you do not want to; it is only meant for improvement of results! Hope you got it working and enjoyed the tutorial. Do not forget to subscribe to our Youtube channel above for more in depth guides on projects. Stay tuned!

Create a free account to access full content.

All access to code and resources on ShillehTek.

Signup Now

Already a member? Sign In

Explore More on Our Blog

Controlling a 5V Laser Diode with Raspberry Pi Pico W

Controlling a 5V Laser Diode with Raspberry Pi Pico W

Learn how to safely control high-power components like a ShillehTek 5V laser diode using the Raspberry Pi Pico W and...

How to Connect and Use the HCSR501 PIR Sensor with a Raspberry Pi Pico/Pico W

How to Connect and Use the HCSR501 PIR Sensor with a Raspberry Pi Pico/Pico W

Learn how to set up the HCSR501 PIR sensor with a Raspberry Pi Pico to detect motion and trigger...

Powering the Raspberry Pi Pico W with the MB102 Power Supply

Powering the Raspberry Pi Pico W with the MB102 Power Supply

Learn how to power your Raspberry Pi Pico W projects easily and flexibly with the MB102 Power Supply Module...

How to Use L298N Motor Driver with Pico W

How to Use L298N Motor Driver with Pico W

Learn how to use the L298N motor driver to control DC motors with the Raspberry Pi Pico W in MicroPython.

Controlling an LED with a Snap Using the KY-037 Sound Sensor and Raspberry Pi

Controlling an LED with a Snap Using the KY-037 Sound Sensor and Raspberry Pi

Discover how to set up, code, and activate the LED based on detected sound with the Raspberry Pi...

Getting Started with the KY-037 Sound Sensor and Raspberry Pi: Detecting Sound Using Python

Getting Started with the KY-037 Sound Sensor and Raspberry Pi: Detecting Sound Using Python

In this tutorial, I’ll guide you through setting up the KY-037 sound sensor with a Raspberry Pi using...

How to Post to Reddit Using Python

How to Post to Reddit Using Python

Post to reddit automatically using a Python script.

How to Create a Time-Lapse Video with a Raspberry Pi Camera

How to Create a Time-Lapse Video with a Raspberry Pi Camera

Learn how to make a timelapse with your Raspberry Pi in Python.

How to Integrate the MPU6050 with the STM32 Blue Pill

How to Integrate the MPU6050 with the STM32 Blue Pill

Learn how to measure acceleration with the STM32 and the MPU6050 in the Arduino IDE.

Getting Started with STM32 Blue Pill in Arduino IDE Using a USB to TTL Converter — Write Your First Program

Getting Started with STM32 Blue Pill in Arduino IDE Using a USB to TTL Converter — Write Your First Program

This comprehensive tutorial will guide you through the process of setting up and programming the STM32 Blue Pill...

Back to blog

Leave a comment

Please note, comments need to be approved before they are published.