AnsweredAssumed Answered

LIS3DH outputting unexpected data

Question asked by Maxime TORRELLI on Oct 16, 2017
Latest reply on Apr 8, 2018 by Kefei Yao



I am trying to log accelerations above 2g. To do so I parametrized the LIS3DH as following:

- CTRL_REG0: 0x10
- CTRL_REG1: 0x57 (100Hz + Xen + Yen + Zen)

- CTRL_REG2: 0x00

- CTRL_REG3: 0x40 (IA1 on INT1)

- CTRL_REG4: 0xB0 (BDU + FS +/- 16g)
- CTRL_REG5: 0x08 (INT1 Latched)

- CTRL_REG6: 0x00


- INT1_THS: 0x0A (+/- 16g  => 186 mg/LSb, 2000/186 = 0x0A)

- INT1_DURATION: 0x00 (trigger INT1 as soon as the acceleration goes above threshold)

- INT1_CFG: 0x2A (OR combination + Z high event + Y high event + X high event)


Everything works fine, I get interrupts signals, read the acceleration available inside the corresponding buffers, clear the interrup. Whereas, I do not understand some results that I get.

First issue, I do not understand how the sensitivity for the +/-16g is obtained. For the other full scale modes there is a logic ( Normal mode: 8g /  (2^9) = 15,625 ~ 16 mg/LSb) but I can not find the logic for 16g.

Assuming that the sensitivity given in the datasheet is correct, then the maximum value returned by the sensor must be 16000/48=333. Or the sensor can go above this limit but then the measured value is not anymore linear with respect to sensitivity? Because the sensor returned few tims values of -24480 mg.
Second issue is that I get interrupts from signals which are above my threshold. For example, I get interrupts for Z = -1776 mg even if the threshold I set is 1860 mg.


I believe I am correctly transforming data from the sensor but I'll describe what I do, just to be sur:


INT16 LIS3DH_DataConverter(BYTE LSB_Data, BYTE MSB_Data, INT16 Sensitivity)
{    // This function convert 2's complement 10 bits data left-justified (splited into two 8 bits variables)
    // into a single signed variable (type INT16) of 16 bits right-justified
    UINT16 u16Value;
    INT16 ConvValue;

    u16Value = LSB_Data + (MSB_Data << 8);
    RETAILMSG( ACC_TRACE, (_T("u16Value = LSB_Data + (MSB_Data << 8): %4.4Xh\r\n"), u16Value));
    u16Value >>= 6; //only 10 high bits are relevant (WARNING! VALID ONLY IF DEVICE IN NORMAL MODE)
    RETAILMSG( ACC_TRACE, (_T("u16Value >>= 6: %4.4Xh\r\n"), u16Value));

    //This value is define has followed
    // if Bit10 is 1 then a(mg) = -(2's complement of AccData)*resolution
    // if Bit10 is 0 then a(mg) = AccData*resolution
    if (u16Value & 0x0200)
        u16Value = ~u16Value;    //1's complement
        RETAILMSG(ACC_TRACE, (_T("u16Value inverted: %d\r\n"), u16Value));
        u16Value &= 0x03FF;     // only 10bits are relevant
                                // (OR 0x 3FF) because bit 10 is 0 because it is the inversion of a negative number.
        RETAILMSG(ACC_TRACE, (_T("u16Value troncated: %d\r\n"), u16Value));
        u16Value++;                //2's complement
        RETAILMSG(ACC_TRACE, (_T("u16Value + 1: %d\r\n"), u16Value));
        ConvValue = -(u16Value * Sensitivity); // TODO: multiply u16Value by resolution
        u16Value = (UINT16)(-ConvValue); //for display only
        RETAILMSG( ACC_TRACE, (_T("Negative a=-%d mg (%2.2X%2.2Xh)!\r\n"), u16Value, LSB_Data, MSB_Data));
        ConvValue = u16Value * Sensitivity; //
        u16Value = (UINT16)ConvValue; //for display only
        RETAILMSG( ACC_TRACE, (_T("Positive a=%d mg (%2.2X%2.2Xh)!\r\n"), u16Value, LSB_Data, MSB_Data));

    return ConvValue;



Thanks for your help.