Thursday, June 20, 2013

Connecting two ADXL345s to one Arduino

I'm getting this question more frequently than others on my previous post about ADXL345 and Arduino, so I've decided to answer it with a post of itself. So, how do you connect and read from two ADXL345s with a single Arduino board? It's pretty straight forward if you already have one ADXL345 running. If you don't, head here, set everything up and get back here because I'll be assuming that you have read it and familiar with the concepts from the previous post.

A tiny bit of explanations first, but you can jump to the drawings if you're bored, and also grab the sources from the bottom of the post. So, what's special about connecting two ADXLs? The fact that the communication between Arduino and the ADXLs is carried out by the means of the I2C protocol and the Arduino Wire library which basically implements this protocol. The Wire library uses analog pins 4 and 5 (20 and 21 on Arduino Mega) as the data and clock pins respectively. Each I2C device - in our case both ADXLs - needs to be connected to both pins. Which means both devices have to be connected to Arduino's data and clock pins. How does the Arduino tell them apart though? Well, the I2C protocol has a property called device address, which lets the master device talk to a specific device that's connected to the data and clock pins by pointing out it's address.

The ADXL345 datasheet says on page 10 tells us that the ADXL may have two addresses, depending on how you wire it. These addresses are 0x53 and 0xD1. The addresses altering is made by changing the HIGH/LOW state of the ADXL SDO pin. In my previous ADXL post I've wired it so that it responds to address 0x53, by grounding the SDO pin (setting it to LOW):

But here we need to connect another ADXL to the same Arduino, so we need another address, that's why we're applying voltage to the SDO pin, setting it to HIGH:

So, now to make everything clear here's a scheme of both ADXL's connected to the same Arduino (click the image to enlarge):

Ok, with that done let's take a look at the code that makes this stuff work. I won't go in detail through basic ADXL345/Arduino interaction because I've done that here, I'll just point out the differences between connecting one and two ADXLs.

This is the write function (it will be used for both devices):

void writeTo(int device, byte address, byte val) {
   Wire.beginTransmission(device); //start transmission to device 
   Wire.write(address);        // send register address
   Wire.write(val);        // send value to write
   Wire.endTransmission(); //end transmission

This is the read function (it will be used for both devices):

void readFrom(int device, byte address, int num, byte buff[]) {
  Wire.beginTransmission(device); //start transmission to device 
  Wire.write(address);        //sends address to read from
  Wire.endTransmission(); //end transmission
  Wire.beginTransmission(device); //start transmission to device
  Wire.requestFrom(device, num);    // request 6 bytes from device
  int i = 0;
  while(Wire.available())    //device may send less than requested (abnormal)
    buff[i] =; // receive a byte
  Wire.endTransmission(); //end transmission

Now the interesting parts.

#include <Wire.h>

#define DEVICE_A (0x1D)    //first ADXL345 device address
#define DEVICE_B (0x53)    //second ADXL345 device address
#define TO_READ (6)        //num of bytes we are going to read each time (two bytes for each axis)

byte buff[TO_READ] ;      //6 bytes buffer for saving data read from the device
char str[512];            //string buffer to transform data before sending it to the serial port

void setup()
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start serial for output
  //Turning on the both ADXL345s
  writeTo(DEVICE_A, 0x2D, 24);   
  writeTo(DEVICE_B, 0x2D, 24);

What's interesting here? First of all we define two addresses, one for each device, and we send the ON command to each device separately (the writeTo() lines).

Now let's see the actual readings from the devices:

int regAddress = 0x32;      //first axis-acceleration-data register on the ADXL345
int xa = 0, ya = 0, za = 0;  
int xb = 0, yb = 0, zb = 0;
void loop()
  readFrom(DEVICE_A, regAddress, TO_READ, buff); //read the acceleration data from the ADXL345  
   //each axis reading comes in 10 bit resolution, ie 2 bytes.  Least Significat Byte first!!
   //thus we are converting both bytes in to one int
  xa = (((int)buff[1]) << 8) | buff[0];   
  ya = (((int)buff[3])<< 8) | buff[2];
  za = (((int)buff[5]) << 8) | buff[4];
  readFrom(DEVICE_B, regAddress, TO_READ, buff); //read the acceleration data from the second ADXL345
  xb = (((int)buff[1]) << 8) | buff[0];   
  yb = (((int)buff[3])<< 8) | buff[2];
  zb = (((int)buff[5]) << 8) | buff[4];
  //we send the x y z values as a string to the serial port
  sprintf(str, "%d %d %d %d %d %d", xa, ya, za, xb, yb, zb);  
  //It appears that delay is needed in order not to clog the port
Ok, first we have defined the variables needed for reading - the address that we want to read from (it's the same for both devices, because they're two instances of the same device). And then we define the vars we want to store that data in. Now, in the loop we perform a reading from DEVICE_A, convert the data that we got in the buff variables to the respective axes vars, and then do the same reading only from DEVICE_B, and again, store the data and voilà, we pack the data in to a nice string and send it away through the serial port!

Well, me thinks that that's it :) give me a shout if you have questions or find errors.

Thy sources


  1. With great pleasure I found your post, as I (am too old to become a coder I) was looking for such an solution!.

    Now I've run into some ?wiring? issue: when connecting the SDO to 3V3 (the right ADXL), all lEDs go out and the monitor doesn't give any new lines.

    Switching the ADXL's shows that both sensors are not broken.

    Do you have any suggestion?

    thx Cor

    1. Hi Cor :)

      If all LEDs go out it might mean that you are shorting the circuit when connecting the second SDO to 3v3 - maybe putting it in GND by mistake?

  2. Hello Euristic,

    I also think that somewhere I must have misconnected a wire. As a test I made:
    the left ADXL SDO connect to 3V3
    the right ADXL SDO connect to GND.

    When doing so: All LED's go of and no readings at the serial monitor
    When disconnecting the left ADXL SDO from 3V3, then the lights go on again.

    As the "problem" shifted from right to left, I think that my wiring of both ADXL's is conform drawing, and are working individually. But not yet together...

    1. When you plug them individually they work? Are you using different breadboards for that, or simply cutting the power off for each one?

  3. individually: ADXL left SDO GND : works
    individually: ADXL right SDO GND : works
    individually: ADXL left or right SDO 3V3 : LEDs out = doesn't work

    I use one breadboard, I have both ADXL's connected with ribbon cables

    If you like I can send you a few pictures of how I wired.
    you can send your email adres to



    1. Cool, I'll contact you via email

    2. did you figure it out? Ive got two working individualy, but not both at the same time :(

  4. Any luck getting both to work? I'm having basically the same problem, when I connect both, nothing works, but individually they work.

    I have the 0x53 device's SDO floating. I plan to ground it to test if that's the issue. I also am not using the resisitors for sda and scl.

    1. @Jeff hi there :)
      Maybe you should wire the elements just as described on the scheme? I just did to re-test the whole thing and it works like a charm.

    2. You sir are correct!

      adding the ground on 0x53 didn't matter, but the resistors are needed. Individually they aren't, but when you run both, you need the resistors.

      Thanks for posting this, the wiring diagram is helpful.

      I'm using the code from:

      it's the only library I found that doesn't hard code the device address, and also has nice functions to handle all the config and interupts

  5. please give me a solution to programm ADXL345 with arduino

    1. @Khawla do you need help with anything specific?

      You can also email me: livefast.codeyoung at gmail dot com

  6. Sergey llunal@mail.ruApril 22, 2015 at 3:45 PM

    Hi! in this article you have connected 2 ADXL345, and how to connect 3 pieces?

    1. Hi Sergey,

      as there are only two possible addresses for the ADXLs, you can either reimplement the Wire library (probably a bad idea!) so it uses other in/out ports than Analog4/5. Or you could use another arduino to the readings of the 3rd/4th ADXL. There might be another way, but I can't really think of one.

  7. Hey Buddy!

    The thing is i want the accelerometers to read different readings based on their relative motions in whatever directions. However this does not seem to be the case.

    What is happening is the values of xb,yb,zb are shown as values of xa,ya,za in the very next instance and it keeps on repeating. i want the vales of xa,ya,za to be completely different than xb,yb,zb and different in every instance.

    could you please help me out?

    Appreciate it. Thanks for the code and connections bud! Really helped

    1. Yo. Are yo usure you're using the right code? You can download the complete source code from here:

  8. This comment has been removed by the author.

  9. hello friend,can you help me to replace ADXL335 with ADXL345
    I need to replace this in my project
    what changes should i make to program