Post Go back to editing

ADXL372 sends Garbage Data

Thread Summary

The user is experiencing incorrect data readings from the ADXL372 accelerometer, even after a successful self-test. The issue is resolved by correctly combining the high and low bytes of the acceleration data without erasing the LSBs, and then shifting the entire word 4 bits to the right. The SPI configuration is 8-bit, MSB first, CPOL=0, CPHA=0, and 3.75 Mbit/s.
AI Generated Content
Category: Hardware
Product Number: ADXL372

I can't get the ADXL372 to work. 

Self Test is successful:

uint8_t val;

// SELF TEST
reg_write(0x3F, 0x00);
reg_write(0x41, 0x52);
HAL_Delay(10);
reg_write(0x3F, 0b11);
HAL_Delay(10);
reg_write(0x40, 0b1);
HAL_Delay(1000);
reg_read(0x40, &val);
if (val == 0x6) {
    printf("\r\nADXL372 self-test sucess\r\n");
}



And this is the init and first read out:
HAL_StatusTypeDef ret = HAL_OK;
ret |= reg_write(0x3F, 0x00); // standy mode
ret |= reg_write(0x41, 0x52); // reset
HAL_Delay(10);

ret |= reg_write(0x3D, 0x00); // ODR 400Hz
ret |= reg_write(0x3E, 0b1000); // BW 200Hz, Low Noise
ret |= reg_write(0x3F, 0b1111); // full bandwidth measurment mode, disable HPF and LPF
if (ret != HAL_OK) return ret;

do {
    ret = reg_read(0x04, &val); // check if data is availabe
} while ((val & 0x01) == 0);

// read data
uint8_t buf[6];
ret |= spi_raw_accel_read_reg(0x08, buf, 6);
if (ret != HAL_OK) return ret;

uint16_t x = (((int16_t)((buf[0] << 8) | buf[1])) >> 4)&0x0FFF;
uint16_t y = (((int16_t)((buf[2] << 8) | buf[3])) >> 4)&0x0FFF;
uint16_t z = (((int16_t)((buf[4] << 8) | buf[5])) >> 4)&0x0FFF;

printf("ADXL372 X=%5d Y=%5d Z=%5d\r\n", x, y, z);

After I read out as soon data is available.

Output:

ADXL372 X=    14 Y=     0 Z=  4078
ADXL372 X=     9 Y=  4095 Z=  4079
ADXL372 X=    13 Y=  4093 Z=  4078
ADXL372 X=     6 Y=     1 Z=  4075
ADXL372 X=     9 Y=     2 Z=  4076
ADXL372 X=    11 Y=  4095 Z=  4079
ADXL372 X=    16 Y=     3 Z=  4078
ADXL372 X=    11 Y=     0 Z=  4076
ADXL372 X=    13 Y=  4093 Z=  4083



Whats wrong? I've tested two devices and the FIFO, and different Modes, same behavior.

Parents
  •     uint16_t x = ((int16_t)((buf[0] << 8) | buf[1]));
        uint16_t y = ((int16_t)((buf[2] << 8) | buf[3]));
        uint16_t z = ((int16_t)((buf[4] << 8) | buf[5]));

    x,y,z are signed (16-bit) integers. Try instead:

        int16_t x = ((int16_t)((buf[0] << 8) | buf[1]));
        int16_t y = ((int16_t)((buf[2] << 8) | buf[3]));
        int16_t z = ((int16_t)((buf[4] << 8) | buf[5]));
    

    The units are 200g/2048ticks = ~0.1g/tick, so we expect Z to be about +/-10, which is consistent with the 4086 in your display.

    [Edit: Minor clarification]

Reply
  •     uint16_t x = ((int16_t)((buf[0] << 8) | buf[1]));
        uint16_t y = ((int16_t)((buf[2] << 8) | buf[3]));
        uint16_t z = ((int16_t)((buf[4] << 8) | buf[5]));

    x,y,z are signed (16-bit) integers. Try instead:

        int16_t x = ((int16_t)((buf[0] << 8) | buf[1]));
        int16_t y = ((int16_t)((buf[2] << 8) | buf[3]));
        int16_t z = ((int16_t)((buf[4] << 8) | buf[5]));
    

    The units are 200g/2048ticks = ~0.1g/tick, so we expect Z to be about +/-10, which is consistent with the 4086 in your display.

    [Edit: Minor clarification]

Children
No Data