How to use multiple accelerometers on arduino MEGA through I2C

Hi all,

I need to hook up 8 (but will start with 2) ADXL345 accelerometers. I thought of using the library by loveelectronics:

https://www.loveelectronics.co.uk/Tutorials/12/adxl345-accelerometer-arduino-tutorial

which works fine (after minor updates) for one accelerometer. The output of the sensor in flat position is:

Raw 1:	24   -4   247   	Scaled 1:	X: 0.09G   Y: -0.02G   Z: 0.96G

which is correct according to the datasheet.

But i need to hook up some more sensors, so I tried instantiating another accelerometer in my code and pass it the alternate address as given in the datasheet on page 18:

http://www.analog.com/static/imported-files/data_sheets/ADXL345.pdf which is 0x53.

But now the output becomes (both sensors in flat position):

Raw 2:	1024   51   -13050   	Scaled 2:	3.99G   0.20G   -7.98G
Raw 1:	18   4   40   	        Scaled 1:	0.07G   0.02G   0.16G
Raw 2:	1024   51   -13050   	Scaled 2:	3.99G   0.20G   -7.98G
Raw 1:	18   2   40   	        Scaled 1:	0.06G   0.02G   0.16G
Raw 2:	1024   51   -13050   	Scaled 2:	3.99G   0.20G   -50.90G
Raw 1:	18   4   42   	        Scaled 1:	0.07G   0.02G   0.16G
Raw 2:	1024   51   -13050   	Scaled 2:	3.99G   0.20G   -50.91G

It seems that readings from one sensor are multiplied, subtracted or divided by the reading from the other sensor.

the wiring is like this:

i just connected the SDA and SDL pins from both sensors to pin 20 and 21 on the arduino. My guess is that i went wrong here.

Then the code for reference:

// Include the Wire library so we can start using I2C.
#include <Wire.h>
// Include the Love Electronics ADXL345 library so we can use the accelerometer.
#include <ADXL345.h>

// Declare a global instance of the accelerometer.
ADXL345 accel;
ADXL345 accel_2;

// Set up a pin we are going to use to indicate our status using an LED.
int statusPin = 2; // I'm using digital pin 2.

void setup()
{
  // Begin by setting up the Serial Port so we can output our results.
  Serial.begin(9600);
  // Start the I2C Wire library so we can use I2C to talk to the accelerometer.
  Wire.begin();

  // Ready an LED to indicate our status.
  pinMode(statusPin, OUTPUT);

  // Create an instance of the accelerometer on the default address (0x1D)
  accel = ADXL345();
  accel_2 = ADXL345(0x53);

  // Check that the accelerometer is infact connected.
  if(accel.EnsureConnected())
  {
    Serial.println("Connected to sensors.");
    digitalWrite(statusPin, HIGH); // If we are connected, light our status LED.
  }
  else 
  {
    Serial.println("Could not connect to ADXL345.");
    digitalWrite(statusPin, LOW); // If we are not connected, turn our LED off.
  }

  // Set the range of the accelerometer to a maximum of 2G.
  accel.SetRange(4, true);
  accel_2.SetRange(4, true);
  // Tell the accelerometer to start taking measurements.
  accel.EnableMeasurements();
  accel_2.EnableMeasurements();
}

void loop() {
  if(accel.IsConnected) // If we are connected to the accelerometer.
  {
    // Read the raw data from the accelerometer.
    AccelerometerRaw raw = accel.ReadRawAxis();
    AccelerometerRaw raw_2 = accel_2.ReadRawAxis();

    AccelerometerScaled scaled = accel.ReadScaledAxis();
    AccelerometerScaled scaled_2 = accel_2.ReadScaledAxis();

    Output(raw, raw_2, scaled, scaled_2);
  }
}

void Output(AccelerometerRaw raw, AccelerometerRaw raw_2, AccelerometerScaled scaled, AccelerometerScaled scaled_2)
{
  // Tell us about the raw values coming from the accelerometer.
  Serial.print("Raw 1:\t");
  Serial.print(raw.XAxis);
  Serial.print("   ");   
  Serial.print(raw.YAxis);
  Serial.print("   ");   
  Serial.print(raw.ZAxis);

  // Tell us about the this data, but scale it into useful units (G).
  Serial.print("   \tScaled 1:\t");
  Serial.print(scaled.XAxis);
  Serial.print("G   ");   
  Serial.print(scaled.YAxis);
  Serial.print("G   ");   
  Serial.print(scaled.ZAxis);
  Serial.println("G");
  
    // Tell us about the raw values coming from the accelerometer.
  Serial.print("Raw 2:\t");
  Serial.print(raw_2.XAxis);
  Serial.print("   ");   
  Serial.print(raw_2.YAxis);
  Serial.print("   ");   
  Serial.print(raw_2.ZAxis);

  // Tell us about the this data, but scale it into useful units (G).
  Serial.print("   \tScaled 2:\t");
  Serial.print(scaled_2.XAxis);
  Serial.print("G   ");   
  Serial.print(scaled_2.YAxis);
  Serial.print("G   ");   
  Serial.print(scaled_2.ZAxis);
  Serial.println("G");

}

Any help on getting multiple I2C sensors working is appriciated!

Jorrit

It's not getting very clear from the picture: are you using 10k pullups? If you do so, lower them. With two devices I'd use about 3.3k. Take a look at the following link, the page describes the relevant facts:

I changed the resistors to 2k (placed 2 times 1k in serie) and directly connected the SDA and SCL from both slaves (the sensors) to each other. From this junction i connected to the 3.3V throuh a 2k pull up resistor.

hope this picture clarifies somewhat:

My output is still strange:

Raw 1:	-110   12   814   	Scaled 1:	-0.43G   0.03G   3.00G
Raw 2:	1024   51   -13050   	Scaled 2:	3.99G   0.20G   -50.90G
Raw 1:	-104   8   815   	        Scaled 1:	-0.41G   0.03G   3.18G
Raw 2:	1024   51   -13050   	Scaled 2:	3.99G   0.20G   -50.90G

The readings from slave device 2 (left in the picture) are still way too large (especially the 50,90 G)

In single setup both the sensors work fine.

Can the wiring be the problem?

Thank you

Have you tried to connect just the second sensor but with the address changed to 0x53? From the numbers you get this could be one possibility that the address change is not working and both sensors respond to the first request. So you can keep your wiring, just disconnect the Vcc from the first sensor to make this test.

Hi pylon,

I was being dumb.

the readings:

horizontal:

Raw 1:	-63   -117   945   	Scaled 1:	-0.25G   -0.46G   3.69G
Raw 2:	-338   -177   1213   	Scaled 2:	-1.32G   -0.69G   4.73G

and after switching the sensors:

Raw 1:	-344   -154   1203   	Scaled 1:	-1.34G   -0.60G   4.69G
Raw 2:	-73   -110   936   	Scaled 2:	-0.27G   -0.43G   3.65G

Which seem ok, the rows just changed their position.

but vertical:

Raw 1:	-368   -85   727   	Scaled 1:	-1.44G   -0.33G   2.84G
Raw 2:	138   33   503   	     Scaled 2:	0.55G   0.12G   1.95G

and switched positions:

Raw 1:	139   21   479   	Scaled 1:	0.55G   0.08G   1.88G
Raw 2:	-377   -90   704   	Scaled 2:	-1.47G   -0.35G   2.75G

Ok these reading are OK too. Well at least its consistent and i know i got the wiring right. The values are not consitent though from accelerometer to accelerometer. But i got these from China, for 5$ per breakout so something had to be wrong somewhere i guess :frowning:

About the multiplexer, would it requiere a library or is it just a matter of coding a loop in order to get all readings from all connected slaves?

OK thanks once more.

Jorrit

So is there anyway of connecting a third (and fourth) ADXL345 (which all have the same addresses than)

You can use a multiplexer (something like a PCA9544A) to select to which chip your sending the clock signal (SCL) to. This way only the selected chip will answer your requests. Drawback is: you cannot use the I2C interface for anything else without integrating it into your multiplexer too.

But, if you look at the picture attached, i would say that switching the position of the sensors would make no difference right?

I would expect it to make a difference. The way you mounted them they are turned by 180° to each other, so they deliver different values although you should be able to compensate that computationally.

What value are you getting from them?

Ok according to http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=63921 you cant hookup more than four (of the same) sensors on I2C.

So went for SPI instead. Was a good learn though!

The I2C bus has a data signal and a clock signal. The clock signal tells the devices that the level currently at data is valid and can be read. If you send your clock signal to just one device at a time it will be the only one answering because all the others don't know that there was any traffic on the bus. The mentioned chip is handling this stuff for both lines bi-directionally for 4 channels, other chips have more channels (PCA9548A has 8). To use the SPI interface you need much more pins than with such a solution.

Hi, im working on the same project. Could you solve it?
Thank you.

Hi Gaska,

It is possible, but you need a digital multiplexer in between your arduino and your sensors. I've read that that is difficult but doable. I went for a more easy solution instead.
I used 8 analog sensors with a regular multiplexer, this was good engough for me!

godd luck!

I've been working on this for too long. It worked for me connecting 2 sensor over i2c, but like you,i want to connect about 8 sensors.
I've tried with SPI too but without success.
Maybe it's time to try de multiplexing jeje

Thank you for the reply.

Hi Gaska,

Can you be a little more specific why your SPI didn't work i.e. how many could you get to work? what is happening to make you think things aren't working? what clock speed and accelerometers are you using? how long are your wires? are you using a library for the accelerometers or just the default Arduino SPI one?

Hello to all,
I am trying to connect two sensors ADXL345 and run your code but I keep getting error.