2025-03-09 6:09 AM - edited 2025-03-09 6:31 AM
Hello ST Friends,
Here we are using H3LIS331DL in our product, using SPI interface. Below is the schematic.
and related code is below.
/* Check device ID */
static uint8_t whoamI, tData;
whoamI = 0;
h3lis331dl_device_id_get(&dev_ctx_xl, &whoamI);
user_printf("\r\nh3lis331dl whoamI: 0x%x\r\n", whoamI);
//REG1
tData = 0x27; //0010 0111
nrf_H3LIS331DL_write_reg(H3LIS331DL_CTRL_REG1, &tData, 1);
//REG2
tData = 0x00; //0000 0000
nrf_H3LIS331DL_write_reg(H3LIS331DL_CTRL_REG2, &tData, 1);
//REG3
tData = 0x92; //1001 0010
nrf_H3LIS331DL_write_reg(H3LIS331DL_CTRL_REG3, &tData, 1);
//REG4
tData = 0x80; //1000 0000
nrf_H3LIS331DL_write_reg(H3LIS331DL_CTRL_REG4, &tData, 1);
nrf_H3LIS331DL_read_reg(H3LIS331DL_CTRL_REG1, &tData, 1);
user_printf("REG1: 0x%x\r\n", tData);
nrf_H3LIS331DL_read_reg(H3LIS331DL_CTRL_REG2, &tData, 1);
user_printf("REG2: 0x%x\r\n", tData);
nrf_H3LIS331DL_read_reg(H3LIS331DL_CTRL_REG3, &tData, 1);
user_printf("REG3: 0x%x\r\n", tData);
nrf_H3LIS331DL_read_reg(H3LIS331DL_CTRL_REG4, &tData, 1);
user_printf("REG4: 0x%x\r\n", tData);
nrf_H3LIS331DL_read_reg(H3LIS331DL_CTRL_REG5, &tData, 1);
user_printf("REG5: 0x%x\r\n", tData);
nrf_H3LIS331DL_read_reg(H3LIS331DL_REFERENCE, &tData, 1);
user_printf("REFERENCE: 0x%x\r\n", tData);
nrf_H3LIS331DL_read_reg(H3LIS331DL_INT1_CFG, &tData, 1);
user_printf("INT1_CFG: 0x%x\r\n", tData);
nrf_H3LIS331DL_read_reg(H3LIS331DL_INT1_SRC, &tData, 1);
user_printf("INT1_SRC: 0x%x\r\n", tData);
nrf_H3LIS331DL_read_reg(H3LIS331DL_INT1_THS, &tData, 1);
user_printf("INT1_THS: 0x%x\r\n", tData);
nrf_H3LIS331DL_read_reg(H3LIS331DL_INT1_DURATION, &tData, 1);
user_printf("INT1_DURATION: 0x%x\r\n", tData);
HAL_Delay(200);
static uint8_t tx_buffer[64];
while(1)
{
if(nrf_gpio_pin_read(PIN_H3LIS331_SensorINT1)== 0)
{
h3lis331dl_acceleration_raw_get(&dev_ctx_xl, gH3LIS331_Acc);
user_printf("ACC Raw: %d, %d, %d\r\n", gH3LIS331_Acc[0],gH3LIS331_Acc[1],gH3LIS331_Acc[2]);
snprintf((char *)tx_buffer, sizeof(tx_buffer),"Acceleration [mg]:%5.2f\t%5.2f\t%5.2f\r\n", h3lis331dl_from_fs100_to_mg(gH3LIS331_Acc[0]), h3lis331dl_from_fs100_to_mg(gH3LIS331_Acc[1]), h3lis331dl_from_fs100_to_mg(gH3LIS331_Acc[2]));
user_printf("ACC: %s\r\n", tx_buffer);
}
and below is the UART output, seems the register are all configured successfully.
<info> app: SPI2 example started.
h3lis331dl whoamI: 0x32
REG1: 0x27
REG2: 0x0
REG3: 0x92
REG4: 0x80
REG5: 0x0
REFERENCE: 0x0
INT1_CFG: 0x0
INT1_SRC: 0x0
INT1_THS: 0x0
INT1_DURATION: 0x0
ACC Raw: 64, -48, 1008
ACC: Acceleration [mg]:196.00 -147.00 3087.00
ACC Raw: 16, -32, 928
ACC: Acceleration [mg]:49.00 -98.00 2842.00
ACC Raw: -16, -32, 912
ACC: Acceleration [mg]:-49.00 -98.00 2793.00
ACC Raw: 32, -48, 880
ACC: Acceleration [mg]:98.00 -147.00 2695.00
ACC Raw: 48, -48, 928
ACC: Acceleration [mg]:147.00 -147.00 2842.00
ACC Raw: 32, -32, 912
ACC: Acceleration [mg]:98.00 -98.00 2793.00
ACC Raw: 32, -32, 928
ACC: Acceleration [mg]:98.00 -98.00 2842.00
ACC Raw: 32, -64, 912
ACC: Acceleration [mg]:98.00 -196.00 2793.00
ACC Raw: 32, -64, 944
ACC: Acceleration [mg]:98.00 -196.00 2891.00
ACC Raw: 32, -32, 912
ACC: Acceleration [mg]:98.00 -98.00 2793.00
ACC Raw: 32, -32, 864
ACC: Acceleration [mg]:98.00 -98.00 2646.00
ACC Raw: -16, -16, 880
ACC: Acceleration [mg]:-49.00 -49.00 2695.00
ACC Raw: -16, -32, 928
ACC: Acceleration [mg]:-49.00 -98.00 2842.00
ACC Raw: 32, -32, 848
ACC: Acceleration [mg]:98.00 -98.00 2597.00
ACC Raw: 32, -16, 880
ACC: Acceleration [mg]:98.00 -49.00 2695.00
ACC Raw: 48, -16, 880
ACC: Acceleration [mg]:147.00 -49.00 2695.00
ACC Raw: 32, -48, 896
ACC: Acceleration [mg]:98.00 -147.00 2744.00
ACC Raw: 48, -48, 912
ACC: Acceleration [mg]:147.00 -147.00 2793.00
ACC Raw: 48, -32, 928
ACC: Acceleration [mg]:147.00 -98.00 2842.00
ACC Raw: 16, -16, 880
ACC: Acceleration [mg]:49.00 -49.00 2695.00
ACC Raw: 64, 0, 912
ACC: Acceleration [mg]:196.00 0.00 2793.00
ACC Raw: 48, -48, 864
ACC: Acceleration [mg]:147.00 -147.00 2646.00
ACC Raw: 32, -32, 880
ACC: Acceleration [mg]:98.00 -98.00 2695.00
ACC Raw: -16, -16, 928
ACC: Acceleration [mg]:-49.00 -49.00 2842.00
ACC Raw: 32, -16, 944
ACC: Acceleration [mg]:98.00 -49.00 2891.00
ACC Raw: 32, -48, 912
ACC: Acceleration [mg]:98.00 -147.00 2793.00
ACC Raw: 32, -32, 896
ACC: Acceleration [mg]:98.00 -98.00 2744.00
ACC Raw: 32, -16, 912
ACC: Acceleration [mg]:98.00 -49.00 2793.00
ACC Raw: 0, 32, 960
ACC: Acceleration [mg]: 0.00 98.00 2940.00
But the ACC XYZ result seems abnormal.
we also captured the waveform as below.
WhoAmI read out.
REG config.
XYZ read out.
And we just put the board steady on the table, but the XYZ vaule is abnormal in this condition.
Do you have any suggestion on this, thank you.
YAN.
Solved! Go to Solution.
2025-03-12 10:18 AM
H3LIS331DL has a very large zero-g level offset, typically +/-1g but can be larger as +/-3g at room temperature, and can be even larger if temperature is far from room temperature or if there are temperatures gradients on the PCB/package or if there is mechanical stress after soldering and assembly.
H3LIS331DL is a high-g accelerometer with 100/200/400g full scale and the offset is typically 1% of the full scale.
For comparison low-g accelerometers with 2/4/8/16g full scale have offset of the same order 1% (20mg for 2g full scale).
You need to perform at least 1-point calibration to measure the offset to be subtracted from accel data: have the unit rest in the horizontal plane, you expect 0g on X and Y, and 1g on Z. The offset to be subtracted is equal to measured value - expected value. Use the average of few measured values for higher accuracy.
For example, you may get average on X = 200mg, average on Y = -100mg, average on Z = 3000mg, this is the measured average.
You expect X = 0mg, Ymg = 0, Zmg = 1000mg.
The offset is OfsX = 200 - 0 = 200mg, OfsY = (-100) - 0 = -100mg, OfsZ = 3000 - 1000 = 2000mg.
CompensatedX = RawX - OfsX, CompensatedY = RawY - OfsY, CompensatedZ = RawZ - OfsZ.
For more information on how the accelerometer can be calibrated, have a look at the following design tips:
They require the accel to be in a precise orientation so that the stimulus is known and can be compared to measured output. If you cannot control the orientation precisely you can use the following method:
Typically used for magnetometers, but also applicable to accelerometers: move the accel in a specific orientation, stop wait for vibrations to die out, take few measurements and average them; repeat the process at least 4 times and check that the averaged data points are not all coplanar, ideally they are maximally distant on a sphere surface; 6 points should give you the best result.
Finally, account for the fact that the package can be misaligned with respect to PCB, PCB may be tilted inside the device housing, and the device may have some tilt with respect to the surface where it is mounted - this is the 'installation error'. Compensation of the installation error is automatic if you use the 6-point calibration. In other cases you need to follow the process described in DT0076.
For your information, for low-g accel ST has makes available the MotionAC library for accelerometer calibration in X-Cube-MEMS software package (use for high-g has not been validated and is probably not possible because of internal thresholds that limit the range of the computed offset bias - I will ask if it is possible to extend and validate for high-g)
2025-03-09 6:15 AM
Hello, here i add one more information, we are using the driver from ST Github, the link is below, thanks.
https://github.com/STMicroelectronics/h3lis331dl-pid
2025-03-11 3:13 AM
Hello ST Friends,
Any suggestion in this issue, we hope to get help from you.
Thanks in advance.
YAN
2025-03-12 10:18 AM
H3LIS331DL has a very large zero-g level offset, typically +/-1g but can be larger as +/-3g at room temperature, and can be even larger if temperature is far from room temperature or if there are temperatures gradients on the PCB/package or if there is mechanical stress after soldering and assembly.
H3LIS331DL is a high-g accelerometer with 100/200/400g full scale and the offset is typically 1% of the full scale.
For comparison low-g accelerometers with 2/4/8/16g full scale have offset of the same order 1% (20mg for 2g full scale).
You need to perform at least 1-point calibration to measure the offset to be subtracted from accel data: have the unit rest in the horizontal plane, you expect 0g on X and Y, and 1g on Z. The offset to be subtracted is equal to measured value - expected value. Use the average of few measured values for higher accuracy.
For example, you may get average on X = 200mg, average on Y = -100mg, average on Z = 3000mg, this is the measured average.
You expect X = 0mg, Ymg = 0, Zmg = 1000mg.
The offset is OfsX = 200 - 0 = 200mg, OfsY = (-100) - 0 = -100mg, OfsZ = 3000 - 1000 = 2000mg.
CompensatedX = RawX - OfsX, CompensatedY = RawY - OfsY, CompensatedZ = RawZ - OfsZ.
For more information on how the accelerometer can be calibrated, have a look at the following design tips:
They require the accel to be in a precise orientation so that the stimulus is known and can be compared to measured output. If you cannot control the orientation precisely you can use the following method:
Typically used for magnetometers, but also applicable to accelerometers: move the accel in a specific orientation, stop wait for vibrations to die out, take few measurements and average them; repeat the process at least 4 times and check that the averaged data points are not all coplanar, ideally they are maximally distant on a sphere surface; 6 points should give you the best result.
Finally, account for the fact that the package can be misaligned with respect to PCB, PCB may be tilted inside the device housing, and the device may have some tilt with respect to the surface where it is mounted - this is the 'installation error'. Compensation of the installation error is automatic if you use the 6-point calibration. In other cases you need to follow the process described in DT0076.
For your information, for low-g accel ST has makes available the MotionAC library for accelerometer calibration in X-Cube-MEMS software package (use for high-g has not been validated and is probably not possible because of internal thresholds that limit the range of the computed offset bias - I will ask if it is possible to extend and validate for high-g)
2025-03-12 10:50 PM
Hello Andrea,
Glad to get the help from you.
So it looks that the ACC Raw result from us is correct, and as you mentioned that this kind of high G device accuracy is about 1% of full scale. so "ACC Raw: 16, -32, 928 ACC: Acceleration [mg]: 49.00 -98.00 2842.00" is reasonable in this condition, right?
and in following, we need do more calibration and filter process in application. we will check the design tips you provide.
Thanks for your help.
YAN