ESP12-E and ADXL345 GY291 / different program output in comparison to ATMEL

Hi,

While below program is uploaded to Arduino Atmel everything works well, have +/-2 measurements from accelerometer. When the same one is uploaded to Lolin wifi esp8266 nodemcu v3 (ESP12-E) the output is very different. Has no negative values and some of the axis jumps sudenly to 255. What is the difference here?

#include   // Wire library - used for I2C communication
int ADXL345 = 0x53; // The ADXL345 sensor I2C address
float X_out, Y_out, Z_out;  // Outputs
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();
  delay(10);
}
void loop() {
  // === Read acceleromter data === //
  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
  X_out = X_out/256; //For a range of +-2g, we need to divide the raw values by 256, according to the datasheet
  Y_out = ( Wire.read()| Wire.read() << 8); // Y-axis value
  Y_out = Y_out/256;
  Z_out = ( Wire.read()| Wire.read() << 8); // Z-axis value
  Z_out = Z_out/256;
  Serial.print("Xa= ");
  Serial.print(X_out);
  Serial.print("   Ya= ");
  Serial.print(Y_out);
  Serial.print("   Za= ");
  Serial.println(Z_out);
    delay(10);
}

There are 7 mentions of 255 in the datasheet https://www.analog.com/media/en/technical-documentation/data-sheets/ADXL345.pdf. 6 of the 7 mentions are from the number 255 on a graph. The 7th mention is

The maximum value for TIME_INACT is 255 sec.

. Which data sheet did you refer to to get the 255 thingy?

The sudden jumps and no negative numbers indicate that the parsing of the data is not taking into account that the MSB is a +/- values.

If you read the data sheet https://www.analog.com/media/en/technical-documentation/data-sheets/ADXL345.pdf you will see that the data sent from the device is in 2 8 bit chunks. The device is able to give +/- 32K of info.

Each scale needs a 16 bit scale factor for each range setting such as

const float BitDivisor = 32767.0f;
const float LSM9DS1_ACCEL_MG_LSB_2G = ( 2.0f / BitDivisor );
const float LSM9DS1_ACCEL_MG_LSB_4G = ( 4.0f / BitDivisor );
const float LSM9DS1_ACCEL_MG_LSB_8G = ( 8.0f / BitDivisor );
const float LSM9DS1_ACCEL_MG_LSB_16G = ( 16.0f / BitDivisor );

Multiplying the result by 255 is not going to give the scaled readings but multiplying the result by the scale factor will give a proper result.

void fReadAccelerometers()
{
  int16_t temp = 0;
  // read status register
  fReadSPIdata16bits( hAG, STATUS_REG );
  // is new accel data available
  if ( GetHighBits() & AccelerometerDataReady )
  {
    fReadSPIdata16bits( hAG, LSM9DS1_REGISTER_OUT_X_L_XL ); // read x accel
    temp = GetHighBits(); temp <<= 8; temp |= GetLowBits();
    aX = (float)temp;
    aX = (aX * _accel_mg_lsb) - aXbias;
    temp = 0;
    //
    fReadSPIdata16bits( hAG, LSM9DS1_REGISTER_OUT_Y_L_XL ); // read Y accel
    temp = GetHighBits(); temp <<= 8; temp |= GetLowBits();
    aY = (float)temp;
    aY = (aY * _accel_mg_lsb) - aYbias;
    temp = 0;
    //
    fReadSPIdata16bits( hAG, LSM9DS1_REGISTER_OUT_Z_L_XL ); // read z accel
    temp = GetHighBits(); temp <<= 8; temp |= GetLowBits();
    aZ = (float)temp;
    aZ = (aZ * _accel_mg_lsb) - aZbias;
  }
}

That is the code of reading the accelerometer data, converting the 2 8 bits into one 16 bit, note how temp is declared as a int16_t and not a uint16_t. then multiplying the result by the scale factor, _accel_mg_lsb. Also, GetHighBits() is a int8_t and not a uint8_t

Well of course I have the same datasheet You are referring to. Your code seems to be for SPI connection (?), I'm using I2C but case with 2x8 bits data for single axis seems to be right I guess. I will investigate this as I'm pretty beginner :)

Problem solved with below. X_out = (int16_t( Wire.read() | Wire.read() << 8)) / 256.0;