cancel
Showing results for 
Search instead for 
Did you mean: 

LIS331HH Offset in Z-direction

mathias
Associate II
Posted on October 19, 2016 at 17:30

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
5 REPLIES 5
Miroslav BATEK
ST Employee
Posted on October 19, 2016 at 18:25

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 << 😎 | LSB) / 16;

It is valid for 24G range, according to datasheet the sensitivity is 12mg/digit.

Best regards

Miroslav

mathias
Associate II
Posted on October 20, 2016 at 10:05

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.

Miroslav BATEK
ST Employee
Posted on October 20, 2016 at 11:19

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

mathias
Associate II
Posted on October 20, 2016 at 11:52

I made some tests:

6g:

X: 0g

Y: 0g

Z: ~ 0.85g

6g upsidedown:

X: 0g

Y: 0g

Z: ~ -1.15g

24g:

X: 0g

Y: 0g

Z: ~ 0.85g

24g upside down:

X: 0g

Y: 0g

Z: ~ -1.15g

Best regards Mathias

Miroslav BATEK
ST Employee
Posted on October 25, 2016 at 13:16

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