Multiple ADX345 on same i2c bus

ARDUINO

Hello there,
I’m looking for some advices about to how two handle multiple i2c slaves connected to an arduino.
In my project I have 6 ADXL345 connected to the i2c bus. ADXL345 has only 2 different addressed that can be configured.
I decided to configure some arduino pins to drive they CS while keeping all accelerator to use the same address.
It seems to work, but sometimes the acceleration reading fails and the arduino get stuck inside the loop.
For the ADXL345 I’m using the Arduino library.

Here some code about how I confgigure the sensor, this function is called inside the main setup()

void setupAcc(ADXL345 acc) {
  /* Initialise the sensor */
  Serial.println("Setting up accelerometer");

  byte deviceID = acc.readDeviceID();
  if (deviceID != 0) {
    //    digitalWrite(ACC_ON_CONTROL_PIN, HIGH);
    Serial.print("0x");
    Serial.print(deviceID, HEX);
    Serial.println("");
  } else {
    Serial.println("read device id: failed");
    while (1) {
      delay(100);
    }
  }

  if (!acc.writeRate(ADXL345_RATE_1600HZ)) {
    Serial.println("write rate: failed");
    while (1) {
      delay(100);
    }
  }


  if (!acc.writeRange(ADXL345_RANGE_16G)) {
    Serial.println("write range: failed");
    while (1) {
      delay(100);
    }
  }

  if (!acc.start()) {
    Serial.println("start: failed");
    while (1) {
      delay(100);
    }
  }
}

void setupAccelerators(void) {
  Wire.begin();
  delay(10);
  for (int i = 0; i < 6; i++) {
    delay(100);
    digitalWrite(tap_pin_map[i], HIGH);
    delay(100);
    setupAcc(accelarators[i]);
    delay(100);
    digitalWrite(tap_pin_map[i], LOW);
    delay(100);
  }
}

And here is how I read:

bool detectTouch() {
  // Find correct accelerometer
  if (accel.update()) {
    int16_t mod_acc = sqrt(pow(accel.getX(), 2) + pow(accel.getY(), 2) + pow(accel.getZ(), 2));
    if (mod_acc >= ACC_MOD_THRESHOLD) {
      Serial.println(mod_acc);
      return true;
    } else {
      return false;
    }
  }
  return false;
}

And switch inside a for loop that loops through all sensors:

digitalWrite(tap_pin_map[new_map], HIGH);
if (detectTouch()) {
	Serial.println("Touch detected");
} else {
	Serial.println("No Touch detected");
}
digitalWrite(tap_pin_map[new_map], LOW);
new_map++;
delay(10);

I guess that the issue is due to some unsync behavior between when I switch chip select and when I do the readings.

Considering that time ( by means of fast switching) is “critical” in my project and that even if some readings (between each switching) fail it would be acceptable,
How can I achieve the maximum performance without getting the program stuck? different hardware solution are acceptable as well, for instance I’ve read a solution that uses Schotty diode to force SDA line on devices that we don’t want to use.

You could consider an i2c multiplexer.
s-l300 (1).jpg

s-l300 (1).jpg

PaulRB:
You could consider an i2c multiplexer.
s-l300 (1).jpg

Already ordered, waiting for the shipment.
Thanks,
Andrea

drama999:
ADXL345 has only 2 different addressed that can be configured.

Then use that address pin as chip select pin.
Set all the other devices on address#2, while the device you're working with is set to address#1.
Leo..

Wawa:
Then use that address pin as chip select pin.
Set all the other devices on address#2, while the device you're working with is set to address#1.
Leo..

Thank you Wawa, I will try but I think that the issue ha something to do with settle times of turning on CS on a sensor and tuning off on another.

Really, if your project is time critical, you might want to use accelerometers with SPI interface. They are a little more expensive, though.

PaulRB:
Really, if your project is time critical, you might want to use accelerometers with SPI interface. They are a little more expensive, though.

ADXL345 already have an SPI interface, I will give a try even if the number of wires will require a PCB redesign.
THX