ADXL345 with adafruit Libary wrong readings after some time

Hey there,

I've got a sparkfun ADXL345 Breakout connecter over I2C, measuring with 200Hz. It works fine for quite a while, but all of a sudden, it reads wrong values:

in the beginning:

2892;-4.04;10.04;-0.75
2896;-4.08;10.08;-0.94
2901;-4.16;9.96;-0.98
2906;-4.12;10.12;-0.90

First is time in ms, the three values is x,y,z.

then, all of a sudden:

766754;-4.12;10.08;-0.86
766759;-4.08;10.00;-0.94
766764;-4.16;10.08;-0.82
766769;-4.12;10.08;-1.10
766774;-4.08;10.00;-0.82
766779;-4.20;10.12;-0.71
766834;0.00;80.02;-6.59
766836;-32.01;-0.04;-0.04
766840;-32.01;80.34;-8.79
766845;-32.01;80.34;-8.79
766850;-32.01;80.34;-8.79
766855;-32.01;80.34;-8.79
766860;-32.01;80.34;-8.79
766865;-32.01;80.34;-8.79
766870;-32.01;80.34;-8.79
766875;-32.01;80.34;-8.79

but still changing sometimes:

767760;-32.01;80.34;-8.79
767765;-32.01;80.34;-8.79
767770;-32.01;80.34;-8.79
767775;-32.01;80.34;-8.79
767780;-32.01;80.34;-8.79
767785;62.76;-33.89;178.87
767790;62.76;-33.89;178.87
767795;62.76;-33.89;178.87
767800;62.76;-33.89;178.87
767805;62.76;-33.89;178.87
767810;62.76;-33.89;178.87

did anyone had this behaviour before and could point me in a direction? A search didn't help me yet :confused:

relevant parts of my code are:

ADXL setup:

void setup_adxl(void)
{
  DEBUG_PRINTLN("Initializing Accelerometer:");

  // Initialise the sensor
  //DEBUG_PRINTBIN(accel.readRegister(ADXL345_REG_DEVID));

  int counter = 0;
  while (!accel.begin() && counter < 100)
  {
    if (counter > 98) {
      // There was a problem detecting the ADXL345 ... check your connections
      DEBUG_PRINTLN("Ooops, no ADXL345 detected ... Check your wiring!");
    }
    counter++;
    delayMicroseconds(10);
  }

  DEBUG_PRINTLN(counter);

  accel.setDataRate(ADXL345_DATARATE_800_HZ);
  accel.setRange(ADXL345_RANGE_8_G);

  // Setup: Int1 => Activity (AC gekoppelt, niedriger Threshold); Int2 => Freefall
  accel.writeRegister(ADXL345_REG_ACT_INACT_CTL, 0b11111111); //AC coupled, ACT: X Y Z
  accel.writeRegister(ADXL345_REG_THRESH_ACT, 2); // scale factor 62.5mg/LSB
  //accel.writeRegister(ADXL345_REG_THRESH_INACT, 2); // scale factor 62.5mg/LSB
  //accel.writeRegister(ADXL345_REG_TIME_INACT, 10); // scale factor 1s/LSB
  accel.writeRegister(ADXL345_REG_THRESH_FF, 5); // scale factor 62.5mg/LSB
  accel.writeRegister(ADXL345_REG_TIME_FF, 10); // scale factor 5ms/LSB
  accel.writeRegister(ADXL345_REG_INT_MAP, 0b00000100); //set to INT1 Pin (INT1 = 0, INT2 = 1)
  accel.writeRegister(ADXL345_REG_INT_ENABLE, 0b00010100); // Enable activity interrupt
  // Display some basic information on this sensor
  displaySensorDetails();

  // Display additional settings (outside the scope of sensor_t)
  displayDataRate();
  displayRange();
  DEBUG_PRINTLN("");

  accel.readRegister(ADXL345_REG_INT_SOURCE);
  accel.readRegister(ADXL345_REG_INT_SOURCE);
  

  String accMessage = "Measurement (Millis,X,Y,Z in m/s^2) startet at: " + getBackLocalTime();
  DEBUG_PRINTLN(accMessage);
}

Where I basically read it:

//Task1code: Core 0
void Task1code( void * pvParameters ) {
  Serial.print("Task1 running on core ");
  Serial.println(xPortGetCoreID());
  delay(1000);

  for (;;) {
    if (millis() - end_time >= 5) { // maximum request rate 200Hz -> 5
      end_time = millis();
      buffer_S += msg_adxl(false);
      buffer_S += "\n";
      //Serial.println(msg_adxl(false));
    }

    if (millis() - last_send_to_queue > 900 && recorded == false) {
      buffer_BME = msg_temp_hum();
      recorded = true;

      strcpy( TxBmeBuffer , buffer_BME.c_str() );

      if (pdTRUE == xQueueSend(queue, TxBmeBuffer, 100))
      {
        Serial.println("Task2: Successfully sent BME data");
        buffer_BME = "";
      }
      else
      {
        Serial.println("Sending BME Failed");
      }
    }


    if (millis() - last_send_to_queue > 1000) {

      strcpy( TxBuffer , buffer_S.c_str() );

      if (pdTRUE == xQueueSend(queue, TxBuffer, 100))
      {
        Serial.println("Task2: Successfully sent ACC data");
        buffer_S = "";
      }
      else
      {
        Serial.println("Sending Failed");
      }

      last_send_to_queue = millis();
      recorded = false;
    } else {
      //buffer_S += "\n";
    }
  }
}

where I generate the string:

String msg_adxl(boolean freefall)
{
  // Get a new sensor event
  sensors_event_t event;
  accel.getEvent(&event);

  String accMessage = "";
  accMessage += millis();
  accMessage += ";";
  accMessage += event.acceleration.x;
  accMessage += ";";
  accMessage += event.acceleration.y;
  accMessage += ";";
  accMessage += event.acceleration.z;
  if (freefall) {
    accMessage += ";";
    accMessage += "Freefall";
  }
  return accMessage;
  //writeAccString(accMessage);
}

I know, that string call is not that good at all, but this is not the problem in this case, as it happens with direct printing to UART as well. And it is not a problem due to the task thin, as it also happens without task-management.

This is running on an ESP32 then?

Posting snippets of code only raises more questions than it answers. It's better to just post all the code.
I see stuff printed to serial in the code snippets that I don't see in the output snippets. Has the output been edited? If it has, then please post a larger section of unedited output that begins before the problem and ends after it appears.

I see buffer_S is extended every 5ms, but is only emptied every 1000ms.
Are you sure the buffers you are strcpy'ing into are large enough?

Hello arduarn,

thanks for your reply and sorry that I didn't reply yet.

The problem about sporadic errors is, they take time to evaluate :confused:

Yes, it is running on an ESP32. To figure out the problem, I simplified the code. Error still was occurring. I changed to an Arduino pro mini, still, the error occurred. Finally found the problem: It was a cold soldering at the Sparkfun ADXL Board, so the SDO pin was not always on Vcc and it sporadically changed the I2C address.

Manny95:
thanks for your reply and sorry that I didn't reply yet.

Thanks for posting the update. By solving the problem yourself methodically, you have saved a lot of back and forth forum posts. Well done!