2016-10-19 08:30 AM
Hello,
I have a problem with the LIS331HH Sensor. The X and Y direction are send correctly to my microcontroller, only the Z value has an offset. I've tried different LIS331HH and the offset is not always the same, so I don't think that I have an error in my code, and when I change the resolution, I have the same offset, e.g. 2 m/s². Here are samples of my code:/* Registers */
volatile static uint8_t ACCEL_ADDRESS = 0x30;
volatile static uint8_t CTRL_REG1 = 0x20;
volatile static uint8_t CTRL_REG4 = 0x23;
//CTRL_REG1
volatile static uint8_t MODE_NORMAL = 0x20;
volatile static uint8_t ODR_1000Hz = 0x18;
volatile static uint8_t Xen = 0x01;
volatile static uint8_t Yen = 0x02;
volatile static uint8_t Zen = 0x04;
//CTRL_REG4
volatile static uint8_t FS_24G = 0x30;
//For Result
volatile static uint8_t OUT_X_L = 0x28;
/* Variables */
volatile static int16_t X, Y, Z;
static uint8_t Accels[6] = { 0, 0, 0, 0, 0, 0 };
/* Init */
uint8_t ctrl_reg1 = MODE_NORMAL | ODR_1000Hz | Xen | Yen | Zen;
HAL_I2C_Mem_Write(&hi2c1, ACCEL_ADDRESS, CTRL_REG1, I2C_MEMADD_SIZE_8BIT, &ctrl_reg1, 1, 10);
uint8_t ctrl_reg4 = FS_24G;
HAL_I2C_Mem_Write(&hi2c1, ACCEL_ADDRESS, CTRL_REG4, I2C_MEMADD_SIZE_8BIT, &ctrl_reg4, 1, 10);
/* While */
HAL_I2C_Mem_Read(&hi2c1, ACCEL_ADDRESS, OUT_X_L | 0x80, I2C_MEMADD_SIZE_8BIT, &Accels[0], 6,10);
X = ConvertDigitToMilliG(Accels[0], Accels[1]);
Y = ConvertDigitToMilliG(Accels[2], Accels[3]);
Z = ConvertDigitToMilliG(Accels[4], Accels[5]);
/* Functions */
int16_t ConvertDigitToMilliG(uint8_t LSB, uint8_t MSB) {
uint8_t lsb = (uint8_t) LSB;
int8_t msb = (int8_t) MSB;
int16_t val = ((msb * 256 + lsb) * 3000) >> 12;
return val;
}
I hope anybody can help me.
Greets Mathias
#lis331hh #accelerameter-offset
2016-10-19 09:25 AM
I think your conversion function is not correct. Why are you multiplying the raw value by 3000 and then divide by 2^12?
I would suggest to use following:
val = 12 * (int16_t) ((MSB << 8) | LSB) / 16;
It is valid for 24G range, according to datasheet the sensitivity is 12mg/digit.
Best regards
Miroslav
2016-10-20 01:05 AM
Hi Miroslav,
according to the datasheet, you get 12 Bit output. The last 4 Bit are 0, of the 2x8 Bit registers.When you calculate 32768*3000/4096=24000mg or 3000/4096*16 (for the lsb) you get about 12mg.For the X and Y registers the calculation is correct, and when I turn the sensor on the side, Z value should be 0 but I see the offset.An other example, when I lay the sensor on the table I get, 1.2 g and upside down 0.8g on the Z direction.Best regards Mathias.2016-10-20 02:19 AM
You are right the last 4 bits are 0, the 12bits value is left aligned. I corrected the formula in my previous posts.
But your formula is not exactly correct, for example:
1g .. the raw value is 1333 ... by my proposed calculation you will get 12 * 1333/16 = 1000mg, but by your calculation you will get 1333 * 3000/4096 = 976mg.
The sensitivity for different ranges (how to convert raw value to mg) is define in datasheet on page 9 (So ... Sensitivity).
Can you please confirm that you have also such a big offset in 6g measurement range.
The datasheet specify that for 6g range the offset should be in range +-70mg. So the offset should be in this range.
For range 24g which you are currently usign the offset can be higher.
Best regards
Miroslav
2016-10-20 02:52 AM
I made some tests:
6g:X: 0gY: 0gZ: ~ 0.85g6g upsidedown:X: 0gY: 0gZ: ~ -1.15g24g:X: 0gY: 0gZ: ~ 0.85g24g upside down:X: 0gY: 0gZ: ~ -1.15gBest regards Mathias2016-10-25 04:16 AM
I double check your issue with application team.
They told me that your offset 150mg is possible for this device. The performance of the device is not as good as modern ones.
I think the only way how to remove the offset is to make a calibration in your microcntroler.
Best regards
Miroslav