ADXL345 Hookup Guide

Pages
Contributors: TheDarkSaint
Favorited Favorite 3

Introduction

The ADXL345 is a small, thin, low power, 3-axis MEMS accelerometer with high resolution (13-bit) measurement at up to +/-16 g. Digital output data is formatted as 16-bit two's complement and is accessible through either an SPI (3- or 4-wire) or I2C digital interface.

SparkFun Triple Axis Accelerometer Breakout - ADXL345

SparkFun Triple Axis Accelerometer Breakout - ADXL345

SEN-09836
$20.50
10

This hookup guide will explore the various functions of the ADXL345 utilizing the SparkFun ADXL345 Arduino Library and example code. First, let's get some background on this small yet powerful accelerometer.

As we step through the Hook Up Guide, you'll find it useful to have the ADXL345 Datasheet on hand.

ADXL345 Datasheet

Required Materials

The wish list below includes all of the materials that will be utilized in this tutorial:

**Note: ** If you plan on using the ADXL345 in I2C mode, you do not need to purchase the logic level converter from the list above.

Suggested Reading

If you're not sure if this product is right for your needs, check out the Accelerometer, Gyro and IMU Buying Guide. Some additional resources that might be helpful in this process, especially if you are just started out, you can find here:

How to Solder: Through-Hole Soldering

This tutorial covers everything you need to know about through-hole soldering.

Working with Wire

How to strip, crimp, and work with wire.

Accelerometer Basics

A quick introduction to accelerometers, how they work, and why they're used.

I2C

An introduction to I2C, one of the main embedded communications protocols in use today.

Hardware Overview

Features

  • Supply Voltage: 2.0 - 3.6 VDC
  • Ultra Low Power: As low as 23 uA in measurement mode, 0.1uA in standby mode at 2.5V
  • SPI or I2C Communication
  • Single Tap / Double Tap Detection
  • Activity / Inactivity Sensing
  • Free-Fall Detection

Whoa! What are those last three?! Yes, the ADXL345 has special sensing abilities! The single and double tap sensing detects when a single, or two simultaneous, acceleration events occur. Activity and inactivity sensing detect the presence or lack of motion. Free-fall sensing compares the acceleration on all axes with the threshold value to know if the device is falling. All thresholds levels that trigger the activity, free-fall, and single tap/double tap events are user-set levels. These functions can also be mapped to one of two interrupt output pins. An integrated, patent pending 32-level first in, first out (FIFO) buffer can be used to store data to minimize host processor intervention.

The ADXL345 is well suited to measure the static acceleration of gravity in tilt-sensing applications, as well as dynamic acceleration resulting from motion or shock. Its high resolution (4 mg/LSB) enables measurement of inclination changes less than 1.0°. Furthermore, low power modes enable intelligent motion-based power management with threshold sensing and active acceleration measurement at extremely low power dissipation.

Applications

  • Handsets
  • Medical Instrumentation
  • Gaming and Pointing Devices
  • Industrial Instrumentation
  • Personal Navigation Devices
  • Hard Disk Drive (HDD) protection

Pin Functionality

Below you can reference the ADXL345 breakout board and pin functions.

alt text

Breakout Board Pin Function Descriptions

Mnemonic Description
GND This pin must be connected to ground
VCC Supply Voltage
CS Chip Select
INT1 Interrupt 1 Output
INT2 Interrupt 2 Output
SDO

Serial Data Output (SPI 4-Wire) / I2C Address Select

SDA / SDI / SDIO

Serial Data I2C / Serial Data Input (SPI 4-WIRE) / Serial Data Input and Output (SPI 3-Wire)

SCL/SCLK

Serial Communications Clock

Assembly

With the ADXL345, I2C and SPI digital communications are available. In both cases, the ADXL345 operates as a slave device.

Note: A potential problem when hooking up the ADXL345 breakout to an Arduino (or compatible board) is, if you are using a breadboard with loosely connected jumper wires, you risk getting bad data. Make sure your connections are solid, and you should be fine.

SPI Communication

First, we will look at how to connect an Arduino (or compatible board like SparkFun's RedBoard) to the ADXL345 breakout board for SPI communication.

In SPI mode, the CS pin is controlled by the bus master. For SPI, either 3- or 4- wire configuration is possible.

Note: When using 3-wire SPI, it is recommended that the SDO pin be pulled up to VDD I/O or pulled down to GND via a 10 kΩ resistor. Please refer to page 15 of the ADXL345 Datasheet for additional information.

The following is a table describing which pins on the Arduino should be connected to the pins on the accelerometer for SPI 4-wire communication.

Arduino Pin ADXL345 Pin
GND GND
3V3 VCC
10 CS
12 SDO
11 SDA
13

SCL


Here is a wiring connection diagram to aid you in hooking it up for SPI 4-wire communication.

alt text

Heads up! If using a 5V Arduino, such as the SparkFun RedBoard or the Arduino Uno, you will need to use a logic level converter to protect the ADXL345's 3/3V tolerant pins (as shown in the diagram above). If using a 3.3V Arduino, such as the Arduino Pro or Pro Mini 3.3V/8MHz, logic level conversion is not necessary.

I2C Communication

Now, let's look at how to connect an Arduino (or compatible board like SparkFun's RedBoard) to the ADXL345 breakout board for I2C communication.

I2C mode is enabled if the CS pin is tied to high. There is no default mode if the CS pin is left unconnected, so it should always be tied high or driven by an external controller.

Note: If other devices are connected to the same I2C bus, the nominal operating voltage level of those other devices cannot exceed VDD I/O by more than 0.3 V. External pull-up resistors are necessary for proper I2C operation. Used in this connection diagram are two 4.7 kΩ resistors. Please refer to page 18 of the ADXL345 Datasheet for additional information.

The following is a table describing which pins on the Arduino should be connected to the pins on the accelerometer for I2C communication.

Arduino Pin ADXL345 Pin
GND GND
3V3 VCC
3V3 CS
GND SDO
A4 SDA
A5

SCL


Here is a wiring connection diagram to aid you in hooking it up for I2C communication.

alt text

Not using a SparkFun RedBoard or Arduino Uno? The reference table below shows where Two Wire Interface (TWI) pins are located on different and older Arduino boards.

Board I2C / TWI Pins
SparkFun Red, Uno, Ethernet A4 (SDA), A5 (SCL)
Mega2560 20 (SDA), 21 (SCL)
Leonardo 2 (SDA), 3 (SCL)
Due 20 (SDA), 21 (SCL), SDA1, SCL1

SparkFun ADXL345 Library

The most exciting part of the Hookup Guide is the SparkFun ADXL345 library we've put together for you. Now, you not only have the ability to customize your sensing functions but also switch easily back and forth between I2C and SPI communication.

To get started, you can download the library here along with example code. For the most up-to-date code visit the SparkFun ADXL345 Arduino Library Repo.

SparkFun ADXL345 Library and Example Code

The downloaded file includes:

  • Library .cpp and .h files
  • Arduino Sketch: ADXL345 Calibration Example
  • Arduino Sketch: ADXL345 Example
  • Arduino Sketch: SparkFun Baby Blynk Monitor Thing Example
  • README.md
  • keywords.txt

Before we are able to use the example code, we need to place the SparkFun_ADXL345_Library folder into your Arduino Library. If you don't know where that is located, you can usually find it here:

PC: My Documents > Arduino > Libraries
Mac: (home directory) > Documents > Arduino > libraries
Linux: (home directory) > Sketchbook > Libraries

For help installing the library, check out our Installing an Arduino Library tutorial.

Using the SparkFun ADXL245 Library

Once you've installed the SparkFun ADXL345 Library, you can open up SparkFun_ADXL345_Example.ino in the Arduino IDE.

Make sure you have downloaded and installed the Arduino Software IDE so you can open the example code and program your board.

Example Code

Now that you have the example sketch open, let's go through and take a look at all the ways we can customize the ADXL345.

SPI or I2C?

The first important selection to make is under the COMMUNICATION SECTION. This is where you will let the library know whether you have setup your hardware for SPI or I2C communication.

language:c
/*********** COMMUNICATION SELECTION ***********/
/*    Comment Out The One You Are Not Using    */
ADXL345 adxl = ADXL345(10);           // USE FOR SPI COMMUNICATION, ADXL345(CS_PIN);
//ADXL345 adxl = ADXL345();             // USE FOR I2C COMMUNICATION

Make sure to comment out // the line of code you are not using. By default, the code has you utilizing SPI communication.

Setup

The most complex part of the example code is the void setup() section. This is where you'll be able to configure your settings and sensing feature thresholds.

language:c
/******************** SETUP ********************/
/*          Configure ADXL345 Settings         */
void setup(){

Serial.begin(9600);                 // Start the serial terminal
Serial.println("SparkFun ADXL345 Accelerometer Hook Up Guide Example");
Serial.println();

adxl.powerOn();                     // Power on the ADXL345

adxl.setRangeSetting(16);           // Give the range settings
                                    // Accepted values are 2g, 4g, 8g or 16g
                                    // Higher Values = Wider Measurement Range
                                    // Lower Values = Greater Sensitivity

adxl.setSpiBit(0);                  // Configure the device to be in 4 wire SPI mode when set to '0' or 3 wire SPI mode when set to 1
                                    // Default: Set to 1
                                    // SPI pins on the ATMega328: 11, 12 and 13 as reference in SPI Library 

adxl.setActivityXYZ(1, 0, 0);       // Set to activate movement detection in the axes "adxl.setActivityXYZ(X, Y, Z);" (1 == ON, 0 == OFF)
adxl.setActivityThreshold(75);      // 62.5mg per increment   // Set activity   // Inactivity thresholds (0-255)

adxl.setInactivityXYZ(1, 0, 0);     // Set to detect inactivity in all the axes "adxl.setInactivityXYZ(X, Y, Z);" (1 == ON, 0 == OFF)
adxl.setInactivityThreshold(75);    // 62.5mg per increment   // Set inactivity // Inactivity thresholds (0-255)
adxl.setTimeInactivity(10);         // How many seconds of no activity is inactive?

adxl.setTapDetectionOnXYZ(0, 0, 1); // Detect taps in the directions turned ON "adxl.setTapDetectionOnX(X, Y, Z);" (1 == ON, 0 == OFF)

// Set values for what is considered a TAP and what is a DOUBLE TAP (0-255)
adxl.setTapThreshold(50);           // 62.5 mg per increment
adxl.setTapDuration(15);            // 625 μs per increment
adxl.setDoubleTapLatency(80);       // 1.25 ms per increment
adxl.setDoubleTapWindow(200);       // 1.25 ms per increment

// Set values for what is considered FREE FALL (0-255)
adxl.setFreeFallThreshold(7);       // (5 - 9) recommended - 62.5mg per increment
adxl.setFreeFallDuration(30);       // (20 - 70) recommended - 5ms per increment

// Setting all interupts to take place on INT1 pin
//adxl.setImportantInterruptMapping(1, 1, 1, 1, 1);     // Sets "adxl.setEveryInterruptMapping(single tap, double tap, free fall, activity, inactivity);" 
                                                        // Accepts only 1 or 2 values for pins INT1 and INT2. This chooses the pin on the ADXL345 to use for Interrupts.
                                                        // This library may have a problem using INT2 pin. Default to INT1 pin.

// Turn on Interrupts for each mode (1 == ON, 0 == OFF)
adxl.InactivityINT(1);
adxl.ActivityINT(1);
adxl.FreeFallINT(1);
adxl.doubleTapINT(1);
adxl.singleTapINT(1);

//attachInterrupt(digitalPinToInterrupt(interruptPin), ADXL_ISR, RISING);   // Attach Interrupt

}

The comments can help guide you as to what each function does along with recommended ranges to stay within where applicable. More detailed information of the sensing functions and interrupts can be found on the ADXL345 Datasheet.

Main Code

The main example code was kept very simple. It focuses on not only reading the accelerometer values but also checking to see if any interrupts have occurred.

language:c
/****************** MAIN CODE ******************/
/*     Accelerometer Readings and Interrupt    */
void loop(){

// Accelerometer Readings
int x,y,z;  
adxl.readAccel(&x, &y, &z);         // Read the accelerometer values and store them in variables declared above x,y,z

// Output Results to Serial
/* UNCOMMENT TO VIEW X Y Z ACCELEROMETER VALUES */  
//Serial.print(x);
//Serial.print(", ");
//Serial.print(y);
//Serial.print(", ");
//Serial.println(z); 

ADXL_ISR();
// You may also choose to avoid using interrupts and simply run the functions within ADXL_ISR(); 
//  and place it within the loop instead.  
// This may come in handy when it doesn't matter when the action occurs. 

}

Currently, the sketch will only output free fall detection, inactivity/activity, and single/double tap detection to the Serial Monitor.

In order to print the measured accelerometer values to the Serial Monitor, just remember to uncomment the following section to look like this:

language:c
// Output Results to Serial
/* UNCOMMENT TO VIEW X Y Z ACCELEROMETER VALUES */  
Serial.print(x);
Serial.print(", ");
Serial.print(y);
Serial.print(", ");
Serial.println(z); 

Serial Monitor Output

Let's see it in action! Go to Tools on your Arduino IDE, set your board and port, and upload the SparkFun_ADXL345_Example.ino sketch to your Arduino or compatible board. If you need further assistance in uploading your sketch this might be helpful: Uploading a Sketch.

The following two Serial Monitor outputs are what you should expect whether you have commented out the accelerometer values from being displayed or not.

Accelerometer Values Excluded

This is what your outputs will look like with the sensing features are triggered.

alt text

Accelerometer Values Included

This is the data you should see when you have uncommented the X, Y and Z Serial.print() lines of code. Also, keep in mind you will still see when the sensing features are triggered, it just might be harder to catch amongst the data stream.

alt text

Calibration

The other sketch available to you is the SparkFun_ADXL345_Calibration.ino. This will be useful whenever you have an application that requires your device to be precision calibrated.

Calibration Method

An accurate calibration method is to use two points per axis. In our case we have a three-axis design, therefore, we are interested in six points. In the datasheet and in the example sketch, you'll notice references to the g range with accepted values of 2g, 4g, 8g or 16g. 1g is equivalent to the force of gravity acting on a stationary object resting on Earth's surface. Acceleration relative to gravity can be measured in units of gravitational force.

A great resource is the Application Note from Analog Devices: Using an Accelerometer for Inclination Sensing

Calibration Example Sketch

Here is what the calibration example sketch looks like:

language:c
#include <SparkFun_ADXL345.h>

/*********** COMMUNICATION SELECTION ***********/
/*    Comment Out The One You Are Not Using    */
//ADXL345 adxl = ADXL345(10);           // Use when you want to use Hardware SPI, ADXL345(CS_PIN);
ADXL345 adxl = ADXL345();             // Use when you need I2C

/****************** VARIABLES ******************/
/*                                             */
int AccelMinX = 0;
int AccelMaxX = 0;
int AccelMinY = 0;
int AccelMaxY = 0;
int AccelMinZ = 0;
int AccelMaxZ = 0; 

int accX = 0;
int accY = 0;
int accZ = 0;

int pitch = 0;
int roll = 0;

/************** DEFINED VARIABLES **************/
/*                                             */
#define offsetX   0       // OFFSET values
#define offsetY   0
#define offsetZ   0

#define gainX     1     // GAIN factors
#define gainY     1
#define gainZ     1 

/******************** SETUP ********************/
/*          Configure ADXL345 Settings         */
void setup()
{
Serial.begin(9600);                 // Start the serial terminal
Serial.println("SparkFun ADXL345 Accelerometer Breakout Calibration");
Serial.println();

adxl.powerOn();                     // Power on the ADXL345

adxl.setRangeSetting(2);           // Give the range settings
                                    // Accepted values are 2g, 4g, 8g or 16g
                                    // Higher Values = Wider Measurement Range
                                    // Lower Values = Greater Sensitivity

adxl.setSpiBit(0);                // Configure the device to be in 4 wire SPI mode when set to '0' or 3 wire SPI mode when set to 1
                                    // It is set to 1 by Default.
                                    // SPI pins on the ATMega328 as reference in SPI Library are 11, 12, and 13

}

/****************** MAIN CODE ******************/
/*  Accelerometer Readings and Min/Max Values  */
void loop()
{
Serial.println("Send any character to display values.");
while (!Serial.available()){}       // Waiting for character to be sent to Serial
Serial.println();

// Get the Accelerometer Readings
int x,y,z;                          // init variables hold results
adxl.readAccel(&x, &y, &z);         // Read the accelerometer values and store them in variables declared above x,y,z

if(x < AccelMinX) AccelMinX = x;
if(x > AccelMaxX) AccelMaxX = x;

if(y < AccelMinY) AccelMinY = y;
if(y > AccelMaxY) AccelMaxY = y;

if(z < AccelMinZ) AccelMinZ = z;
if(z > AccelMaxZ) AccelMaxZ = z;

Serial.print("Accel Minimums: "); Serial.print(AccelMinX); Serial.print("  ");Serial.print(AccelMinY); Serial.print("  "); Serial.print(AccelMinZ); Serial.println();
Serial.print("Accel Maximums: "); Serial.print(AccelMaxX); Serial.print("  ");Serial.print(AccelMaxY); Serial.print("  "); Serial.print(AccelMaxZ); Serial.println();
Serial.println();


/* Note: Must perform offset and gain calculations prior to seeing updated results
/  Refer to SparkFun ADXL345 Hook Up Guide: https://learn.sparkfun.com/tutorials/adxl345-hookup-guide
/  offsetAxis = 0.5 * (Acel+1g + Accel-1g)
/  gainAxis = 0.5 * ((Acel+1g - Accel-1g)/1g) */

// UNCOMMENT SECTION TO VIEW NEW VALUES
//accX = (x - offsetX)/gainX;         // Calculating New Values for X, Y and Z
//accY = (y - offsetY)/gainY;
//accZ = (z - offsetZ)/gainZ;

//Serial.print("New Calibrated Values: "); Serial.print(accX); Serial.print("  "); Serial.print(accY); Serial.print("  "); Serial.print(accZ);
//Serial.println(); 

while (Serial.available())
{
    Serial.read();                    // Clear buffer
}
}

The main code will read your accelerometer maximums and minimums. With these values we will be able to calculate the offset values and gain factors giving us our new calibrated accelerometer readings. We will talk more about the equations for those calculations in a minute.

Mounting Accelerometer

Before taking these measurements, we want to have the accelerometer mounted with the Z axis parallel to the up direction. For example, if our accelerometer is on a table, our ADXL345 breakout board will be oriented like the picture below and the Z data should be constant.

alt text

Make sure it's secure to either your application or a block that has a level flat surface.

Load Sketch and Take Measurements

Load the Calibration Sketch to your board. Open the Serial Monitor, and wait for the prompt that says to Send any character to display values. Each time you want to measure a different axis, simply turn the enclosure or block the ADXL345 breakout is mounted on, type a character to the Serial Monitor, and hit return to print out the measurement result. You'll notice an X-Y-Z axis symbol on the breakout board that will help with orienting in each direction.

alt text

When an axis is placed into a +1 g and −1 g field, the measured outputs will look something like this on your Serial Monitor. You'll want to take measurements in each axis direction.

alt text

Recording Data

To leave room for offset and gain adjustments, it's probably best to do the calculations by hand. Record your data in a similar table like the one below.

+1 g -1 g Offset Gain
X-Axis
Y-Axis
Z-Axis

Calculations

The offset values and gain factors are calculated with the following equations as stated in the Application Note from Analog Devices (page 8: equations 17 and 18).

alt text

In the DEFINED VARIABLES section of the code is where we will place the new calculated values for offset and gain.

language:c
/************** DEFINED VARIABLES **************/
/*                                             */
#define offsetX     0    // OFFSET values
#define offsetY     0
#define offsetZ     0

#define gainX       1     // GAIN factors
#define gainY       1
#define gainZ       1

Hooray! Now you'll be able to acquire the adjusted values for X, Y and Z.

Note: You'll have to uncomment a section of the following code to see your new calibrated values:

language:c
// UNCOMMENT SECTION TO VIEW NEW VALUES
accX = (x - offsetX)/gainX;         // Calculating New Values for X, Y and Z
accY = (y - offsetY)/gainY;
accZ = (z - offsetZ)/gainZ;

Serial.print("New Calibrated Values: "); Serial.print(accX); Serial.print("  "); Serial.print(accY); Serial.print("  "); Serial.print(accZ);
Serial.println(); 

Now your Serial Monitor output will be calibrated and look something more like this...

alt text

Resources and Going Further

The SparkFun Triple Access Accelerometer ADXL345 and the ADXL345 Arduino Library are both open-source, so there are plenty of resources, including:

For more information on the ADXL345, the datasheet can be referred to.

ADXL345 Accelerometer Project Inspiration

Need some inspiration for your next project? Check out some of these related tutorials.

Elevator TARDIS Project
Motion Controlled Elevator TARDIS Tutorial

Dungeons and Dragons Dice Gauntlet

A playful, geeky tutorial for a leather bracer that uses a LilyPad Arduino, LilyPad accelerometer, and seven segment display to roll virtual 4, 6, 8, 10, 12, 20, and 100 side dice for gaming.

Das Blinken Top Hat

A top hat decked out with LED strips makes for a heck of a wedding gift.

Blynk Board Washer/Dryer Alarm

How to configure the Blynk Board and app to notify you when your washer or dryer is done shaking.

Or check out some of these blog posts for ideas: