LIS3DH outputting unexpected data
Hello,
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
- FIFO_CTRL_REG: 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)); } else { 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.
Sincerely,Maxime TORRELLI#lis3dh