The same program behaves randomly after power loss

Hi,

Another challange :slight_smile:
I’m experiencing strange program serial print behaviour. Once Arduino NANO is connected to PC via USB and program uploaded output is okay - shows ADXL345 values in 6 columns (3 for each measuring device). When I disconnect USB and connect it again, open serial monitor I see randomly only one device measurement working. 2nd reports zero values, I have to push reset button few times (or upload program again) and then suddenly everything comes back to normal - 6 columns data - until next power loss.
Both ADXL’s345 connected to I2C via TCA9548A multiplexer.

What I am missing here?

#include <Wire.h>  // Wire library - used for I2C communication
int ADXL345 = 0x53; // The ADXL345 sensor I2C address
#define TCAADDR 0x70
float X_out, Y_out, Z_out;  // Outputs
float X_out1, Y_out1, Z_out1;

void setup() {
  Serial.begin(115200); // Initiate serial communication for printing the results on the Serial monitor
  Wire.begin(); // Initiate the Wire library
  // Set ADXL345 in measuring mode
  Wire.beginTransmission(ADXL345); // Start communicating with the device
  Wire.write(0x2D); // Access/ talk to POWER_CTL Register - 0x2D
  // Enable measurement
  Wire.write(8); // (8dec -> 0000 1000 binary) Bit D3 High for measuring enable
  Wire.endTransmission();
}

void tcaselect(uint8_t i) {
  if (i > 7) return;
  Wire.beginTransmission(TCAADDR);
  Wire.write(1 << i);
  Wire.endTransmission();
}

void loop() {
  {
    tcaselect(4);
    Wire.beginTransmission(ADXL345);
    Wire.write(0x32); // Start with register 0x32 (ACCEL_XOUT_H)
    Wire.endTransmission(false);
    Wire.requestFrom(ADXL345, 6, true); // Read 6 registers total, each axis value is stored in 2 registers
    X_out = ( Wire.read() | Wire.read() << 8); // X-axis value
    Y_out = ( Wire.read() | Wire.read() << 8); // Y-axis value
    Z_out = ( Wire.read() | Wire.read() << 8); // Z-axis value
    delay(7);

    tcaselect(6);
    Wire.beginTransmission(ADXL345);
    Wire.write(0x32); // Start with register 0x32 (ACCEL_XOUT_H)
    Wire.endTransmission(false);
    Wire.requestFrom(ADXL345, 6, true); // Read 6 registers total, each axis value is stored in 2 registers
    X_out1 = ( Wire.read() | Wire.read() << 8); // X-axis value
    Y_out1 = ( Wire.read() | Wire.read() << 8); // Y-axis value
    Z_out1 = ( Wire.read() | Wire.read() << 8); // Z-axis value
    delay(7);
  }
  Y_out = Y_out / 128;
  X_out = X_out / 128; //For a range of +-2g, we need to divide the raw values by 256, according to the datasheet
  Z_out = Z_out / 128;
  X_out1 = X_out1 / 128;
  Y_out1 = Y_out1 / 128;
  Z_out1 = Z_out1 / 128;
  static char X_outt1 [7];
  static char Y_outt1 [7];
  static char Z_outt1 [7];
  static char X_outt2 [7];
  static char Y_outt2 [7];
  static char Z_outt2 [7];
  dtostrf(X_out, 5, 2, X_outt1);
  dtostrf(Y_out, 5, 2, Y_outt1);
  dtostrf(Z_out, 5, 2, Z_outt1);
  dtostrf(X_out1, 5, 2, X_outt2);
  dtostrf(Y_out1, 5, 2, Y_outt2);
  dtostrf(Z_out1, 5, 2, Z_outt2);

  char text [30];
  sprintf(text, "%s,%s,%s,%s,%s,%s,", X_outt1, Y_outt1, Z_outt1, X_outt2, Y_outt2, Z_outt2);
  // sprintf(text, "%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,", X_outt1, Y_outt1, Z_outt1, X_outt2, Y_outt2, Z_outt2, X_outt3, Y_outt3, Z_outt3, X_outt4, Y_outt4, Z_outt4);
  Serial.println(text);
  delay(7);
}

One thing more noticed. No need to hard reset, same behaviour when I close and open serial monitor few times.

float X_out, Y_out, Z_out;  // Outputs
float X_out1, Y_out1, Z_out1;

So X_out and X_outt1 are floats

Later you do

 dtostrf(X_out, 5, 2, X_outt1);

which treats X_outt1 as a C style string (null terminated array of chars) and which you later use in sprintf() as a string because sprintf() does not support floats on most Arduinos

Whatever else is going on, why isn't X_outt1 (etc) declared as a char array ?

Actually, X_outt1 is a string, X_out1 is a float. Which suggests that some better variable names would make things clearer.

As to opening the serial monitor, that resets the nano, so that behavior at least, is expected.

Right, naming could be better - I will update as for sure soon I will open another thread with something else :slight_smile:

So in overall program works but after few times hard reset only - I guess it shall have nothing to do with floats and char functions as serial print is being displayed properly with desired values.

Not sure if I'm thinking right way but it seems after power loss one of ADXL's is not running. By pressing reset few times void setup is being uploaded again and finally it finds 2nd missing ADXL - first one remains activated as reset is not cutting power off. (?) Could this be?

This is still only one multiplexer and target is to have 3 multiplexers and 20x ADXL's.

Actually, X_outt1 is a string, X_out1 is a float. Which suggests that some better variable names would make things clearer.

So it is, and I agree wholeheartedly about the variable names