2024-12-03 11:33 AM - last edited on 2024-12-03 12:02 PM by Peter BENSCH
Hello
I am working with an ST magnetometer sensor to detect movement along the X-axis. I have a custom board featuring an L4 microcontroller, which enters STOP MODE 2 until an interrupt is triggered. I use the following function to initialize the sensor for this mode, after which the device goes to sleep. When the magnetic data exceeds a specified threshold, the magnetometer generates an interrupt and the device wakes up.
However, I am facing a challenge regarding maintaining the device's proper functionality when exposed to temperature variations. The interrupt generation is based on raw magnetic data returned by the function lis2mdl_magnetic_raw_get(). I am aware that the temperature fluctuations, such as reaching 50 C, can distort the magnetic readings, potentially causing inaccuracies. The magnetometer will require calibration, but my question is how to apply the calibrated values in the system?
Currently, my approach is to keep the device in sleep mode and wake it up only when the magnetic data exceeds the threshold. Should I recalibrate the threshold based on the magnetic data to account for temperature changes?
Below is the function I use for sensor initialization:
int LIS2MDL_init(lis2mdlType magnet)
{
lis2mdl_int_crtl_reg_t int_ctrl;
/*Initialize driver interface*/
dev_ctx.write_reg = platform_write;
dev_ctx.read_reg = platform_read;
dev_ctx.mdelay = platform_delay;
dev_ctx.handle = &SENSOR_BUS;
/*Wait for sensor boot*/
platform_delay(20);
/*Check device ID*/
magnet.whoamI = LIS2MDL_get_id();
if (magnet.whoamI != LIS2MDL_ID)
{
LOG_ERR("Device is not accessible");
return -1;
}
/*Reset and reinitialize sensor*/
lis2mdl_reset_set(&dev_ctx, PROPERTY_ENABLE);
uint8_t rst;
do {
lis2mdl_reset_get(&dev_ctx, &rst);
} while (rst);
/*Enable block data update*/
lis2mdl_block_data_update_set(&dev_ctx, PROPERTY_ENABLE);
/*Set output data rate to 10 Hz*/
lis2mdl_data_rate_set(&dev_ctx, LIS2MDL_ODR_10Hz);
/*Set magnetic condition restoration policy*/
lis2mdl_set_rst_mode_set(&dev_ctx, LIS2MDL_SET_SENS_ONLY_AT_POWER_ON);
/*Enable temperature compensation if needed*/
lis2mdl_offset_temp_comp_set(&dev_ctx, PROPERTY_ENABLE);
/*Set continuous mode for measurement*/
lis2mdl_operating_mode_set(&dev_ctx, LIS2MDL_CONTINUOUS_MODE);
/*Set low-power mode*/
lis2mdl_power_mode_set(&dev_ctx, LIS2MDL_LOW_POWER);
/*Enable interrupt on INT pin*/
lis2mdl_int_on_pin_set(&dev_ctx, PROPERTY_ENABLE);
/*Set interrupt threshold*/
lis2mdl_int_gen_threshold_set(&dev_ctx, NORMAL_THRESHOLD);
/*Configure interrupt control*/
int_ctrl.iea = PROPERTY_ENABLE; // Interrupt signal active HIGH
int_ctrl.ien = PROPERTY_ENABLE; // Enable interrupt system
int_ctrl.iel = PROPERTY_DISABLE; // Pulse interrupt signal
/*Enable X-axis interrupt only*/
int_ctrl.zien = PROPERTY_DISABLE; // Disable Z-axis interrupt
int_ctrl.yien = PROPERTY_DISABLE; // Disable Y-axis interrupt
int_ctrl.xien = PROPERTY_ENABLE; // Enable X-axis interrupt
/*Apply interrupt configuration*/
lis2mdl_int_gen_conf_set(&dev_ctx, &int_ctrl);
LOG_INF("LIS2MDL configured for continuous low-power mode with X-axis interrupt enabled");
return 0;
}
Solved! Go to Solution.
2024-12-09 12:10 AM
Hi @ngrigoriadis ,
You can refer to AN5069 - Section 9, for an explanation of how to embed calibration for hard-iron effects. It is not possible to embed sensitivity calibration in the device, so you must take margin in the interrupt threshold setting. Then you can easily apply a multiplicative sensitivity calibration factor on the output data at microcontroller data processing stage.
2024-12-09 12:10 AM
Hi @ngrigoriadis ,
You can refer to AN5069 - Section 9, for an explanation of how to embed calibration for hard-iron effects. It is not possible to embed sensitivity calibration in the device, so you must take margin in the interrupt threshold setting. Then you can easily apply a multiplicative sensitivity calibration factor on the output data at microcontroller data processing stage.
2024-12-10 06:06 AM
I created a function for hard-iron calibration, which I call after my initialization function. It operates well and successfully centers my axis readings to 0. However, when running in a loop and needing to recalibrate the sensor using hard-iron calibration again, it doesn't work as expected. I noticed that if I reinitialize my magnetometer using LIS2MDL_init() and then call my hard-iron calibration function, it works correctly. How can I avoid this step of reinitialization?
I tried disabling offset cancellation before calling the function
lis2mdl_mag_user_offset_set(&dev_ctx, mag_offset);
and then re-enabling offset cancellation afterward, but it didn’t work. Is there something I can do to resolve this issue?