2019-12-21 09:05 PM
Hello dear st engineer
For example, the yaw angle is random,and if (mag_cal_test.cal_quality == MFX_MAGCALGOOD) is always MFX_MAGCALUNKNOWN
this is my code ,
void example_main_lsm9ds1(void) {
/* Initialize platform specific hardware */
platform_init();
/* Initialize inertial sensors (IMU) driver interface */
uint8_t i2c_add_mag = LSM9DS1_MAG_I2C_ADD_L;
dev_ctx_mag.write_reg = platform_write;
dev_ctx_mag.read_reg = platform_read;
dev_ctx_mag.handle = (void*) &i2c_add_mag;
/* Initialize magnetic sensors driver interface */
uint8_t i2c_add_imu = LSM9DS1_IMU_I2C_ADD_H;
dev_ctx_imu.write_reg = platform_write;
dev_ctx_imu.read_reg = platform_read;
dev_ctx_imu.handle = (void*) &i2c_add_imu;
/* Check device ID */
lsm9ds1_dev_id_get(&dev_ctx_mag, &dev_ctx_imu, &whoamI);
if (whoamI.imu != LSM9DS1_IMU_ID || whoamI.mag != LSM9DS1_MAG_ID) {
while (1) {
/* manage here device not found */
}
}
/* Restore default configuration */
lsm9ds1_dev_reset_set(&dev_ctx_mag, &dev_ctx_imu, PROPERTY_ENABLE);
do {
lsm9ds1_dev_reset_get(&dev_ctx_mag, &dev_ctx_imu, &rst);
} while (rst);
/* Enable Block Data Update */
lsm9ds1_block_data_update_set(&dev_ctx_mag, &dev_ctx_imu, PROPERTY_ENABLE);
/* Set full scale */
lsm9ds1_xl_full_scale_set(&dev_ctx_imu, LSM9DS1_4g);
lsm9ds1_gy_full_scale_set(&dev_ctx_imu, LSM9DS1_2000dps);
lsm9ds1_mag_full_scale_set(&dev_ctx_mag, LSM9DS1_4Ga);
/* Configure filtering chain - See datasheet for filtering chain details */
/* Accelerometer filtering chain */
lsm9ds1_xl_filter_aalias_bandwidth_set(&dev_ctx_imu, LSM9DS1_AUTO);
lsm9ds1_xl_filter_lp_bandwidth_set(&dev_ctx_imu, LSM9DS1_LP_ODR_DIV_100);
lsm9ds1_xl_filter_out_path_set(&dev_ctx_imu, LSM9DS1_LP_OUT);
/* Gyroscope filtering chain */
lsm9ds1_gy_filter_lp_bandwidth_set(&dev_ctx_imu, LSM9DS1_LP_ULTRA_LIGHT);
lsm9ds1_gy_filter_hp_bandwidth_set(&dev_ctx_imu, LSM9DS1_HP_MEDIUM);
lsm9ds1_gy_filter_out_path_set(&dev_ctx_imu, LSM9DS1_LPF1_HPF_LPF2_OUT);
/* Set Output Data Rate / Power mode */
lsm9ds1_imu_data_rate_set(&dev_ctx_imu, LSM9DS1_IMU_119Hz);
lsm9ds1_mag_data_rate_set(&dev_ctx_mag, LSM9DS1_MAG_UHP_155Hz);
// while (1) {
// magGetData();
//// osDelay(1);
// }
}
the senser data is good
void magGetData() {
// lsm9ds1_dev_status_get(&dev_ctx_mag, &dev_ctx_imu, ®);
//
// if (reg.status_imu.xlda && reg.status_imu.gda) {
/* Read imu data */
memset(data_raw_acceleration.u8bit, 0x00, 3 * sizeof(int16_t));
memset(data_raw_angular_rate.u8bit, 0x00, 3 * sizeof(int16_t));
lsm9ds1_acceleration_raw_get(&dev_ctx_imu, data_raw_acceleration.u8bit);
lsm9ds1_angular_rate_raw_get(&dev_ctx_imu, data_raw_angular_rate.u8bit);
appInfo->acceleration[0] = lsm9ds1_from_fs4g_to_mg(
data_raw_acceleration.i16bit[0]);
appInfo->acceleration[1] = lsm9ds1_from_fs4g_to_mg(
data_raw_acceleration.i16bit[1]);
appInfo->acceleration[2] = lsm9ds1_from_fs4g_to_mg(
data_raw_acceleration.i16bit[2]);
appInfo->angular[0] = lsm9ds1_from_fs2000dps_to_mdps(
data_raw_angular_rate.i16bit[0]);
appInfo->angular[1] = lsm9ds1_from_fs2000dps_to_mdps(
data_raw_angular_rate.i16bit[1]);
appInfo->angular[2] = lsm9ds1_from_fs2000dps_to_mdps(
data_raw_angular_rate.i16bit[2]);
// sprintf((char*) tx_buffer,
// "mg1=%d,mg2=%d,mg3=%d,mdps1=%d,mdps2=%d,mdps3=%d,",
// (int) (appInfo->acceleration[0] * (float) 100),
// (int) (appInfo->acceleration[1] * (float) 100),
// (int) (appInfo->acceleration[2] * (float) 100),
// (int) (appInfo->angular[0] * (float) 100),
// (int) (appInfo->angular[1] * (float) 100),
// (int) (appInfo->angular[2] * (float) 100));
// tx_com(tx_buffer, strlen((char const*) tx_buffer));
// }
// if (reg.status_mag.zyxda) {
/* Read magnetometer data */
memset(data_raw_magnetic_field.u8bit, 0x00, 3 * sizeof(int16_t));
lsm9ds1_magnetic_raw_get(&dev_ctx_mag, data_raw_magnetic_field.u8bit);
appInfo->magnetic[0] = lsm9ds1_from_fs4gauss_to_mG(
data_raw_magnetic_field.i16bit[0]);
appInfo->magnetic[1] = lsm9ds1_from_fs4gauss_to_mG(
data_raw_magnetic_field.i16bit[1]);
appInfo->magnetic[2] = lsm9ds1_from_fs4gauss_to_mG(
data_raw_magnetic_field.i16bit[2]);
// sprintf((char*) tx_buffer, "mG1=%d,mG2=%d,mG3=%d\r\n",
// (int) ((float) appInfo->magnetic[0] * (float) 100),
// (int) ((float) appInfo->magnetic[1] * (float) 100),
// (int) ((float) appInfo->magnetic[2] * (float) 100));
//
// tx_com(tx_buffer, strlen((char const*) tx_buffer));
// }
// }
}
motionFxInit is success
void motionFxInit() {
char acc_orientation[4];
char gyro_orientation[4];
char mag_orientation[4];
acc_orientation[0] = 'n';
acc_orientation[1] = 'e';
acc_orientation[2] = 'u';
gyro_orientation[0] = 'n';
gyro_orientation[1] = 'e';
gyro_orientation[2] = 'u';
mag_orientation[0] = 's';
mag_orientation[1] = 'e';
mag_orientation[2] = 'u';
MotionFX_initialize();
MotionFX_getKnobs(ipKnobs);
(void) strcpy(ipKnobs->acc_orientation, acc_orientation);
(void) strcpy(ipKnobs->gyro_orientation, gyro_orientation);
(void) strcpy(ipKnobs->mag_orientation, mag_orientation);
ipKnobs->gbias_acc_th_sc_6X = GBIAS_ACC_TH_SC_6X;
ipKnobs->gbias_gyro_th_sc_6X = GBIAS_GYRO_TH_SC_6X;
ipKnobs->gbias_mag_th_sc_6X = GBIAS_MAG_TH_SC_6X;
ipKnobs->gbias_acc_th_sc_9X = GBIAS_ACC_TH_SC_9X;
ipKnobs->gbias_gyro_th_sc_9X = GBIAS_GYRO_TH_SC_9X;
ipKnobs->gbias_mag_th_sc_9X = GBIAS_MAG_TH_SC_9X;
ipKnobs->output_type = MFX_ENGINE_OUTPUT_ENU;
ipKnobs->LMode = 2;
ipKnobs->modx = 1;
MotionFX_setKnobs(ipKnobs);
MotionFX_enable_6X(MFX_ENGINE_DISABLE);
MotionFX_enable_9X(MFX_ENGINE_ENABLE);
char lib_version[35];
MotionFX_GetLibVersion(lib_version);
MotionFX_MagCal_init(10, 1);
}
and i use freertos
Once triggered by a timer every 10ms transmit data to motionFx
void StartImuTask(void const * argument){
for(;;){
xEventGroupWaitBits(appInfo->appEvent, IMU_TIM_BIT, pdTRUE, pdTRUE, portMAX_DELAY);
HAL_GPIO_TogglePin(SYSTEM_LED_GPIO_Port, SYSTEM_LED_Pin);
magGetData();
getMotionFxData();
}
}
static float ans_float;
void getMotionFxData(){
MFX_input_t data_in;
MFX_output_t data_out;
data_in.gyro[0] = (float)appInfo->angular[0] * FROM_MDPS_TO_DPS;
data_in.gyro[1] = (float)appInfo->angular[1] * FROM_MDPS_TO_DPS;
data_in.gyro[2] = (float)appInfo->angular[2] * FROM_MDPS_TO_DPS;
data_in.acc[0] = (float)appInfo->acceleration[0] * FROM_MG_TO_G;
data_in.acc[1] = (float)appInfo->acceleration[1] * FROM_MG_TO_G;
data_in.acc[2] = (float)appInfo->acceleration[2] * FROM_MG_TO_G;
MFX_MagCal_input_t magDataIn = {0};
magDataIn.mag[0] = (float)appInfo->magnetic[0] * FROM_MGAUSS_TO_UT50;
magDataIn.mag[1] = (float)appInfo->magnetic[1] * FROM_MGAUSS_TO_UT50;
magDataIn.mag[2] = (float)appInfo->magnetic[2] * FROM_MGAUSS_TO_UT50;
magDataIn.time_stamp = HAL_GetTick();
MotionFX_MagCal_run(&magDataIn);
MFX_MagCal_output_t mag_cal_test;
MotionFX_MagCal_getParams(&mag_cal_test);
/* If calibration data are available load HI coeficients */
if (mag_cal_test.cal_quality == MFX_MAGCALGOOD) {
ans_float = (mag_cal_test.hi_bias[0] * FROM_UT50_TO_MGAUSS);
appInfo->magneticOffset[0] = (int32_t) ans_float;
ans_float = (mag_cal_test.hi_bias[1] * FROM_UT50_TO_MGAUSS);
appInfo->magneticOffset[1] = (int32_t) ans_float;
ans_float = (mag_cal_test.hi_bias[2] * FROM_UT50_TO_MGAUSS);
appInfo->magneticOffset[2] = (int32_t) ans_float;
data_in.mag[0] = appInfo->magnetic[0] - appInfo->magneticOffset[0];
data_in.mag[1] = appInfo->magnetic[1] - appInfo->magneticOffset[1];
data_in.mag[2] = appInfo->magnetic[2] - appInfo->magneticOffset[2];
float atim = 0.01f;
MotionFX_propagate(&data_out, &data_in, &atim);
MotionFX_update(&data_out, &data_in, &atim, NULL);
char temp[100] = {0};
sprintf(temp, "%d,yaw=%d\r\n",(int)add,
(int)(data_out.rotation_9X[0]*(float)100));
add++;
HAL_UART_Transmit(&huart2, temp, strlen(temp), 100);
}
}
but the yaw value is never good ,
please help me thank you very much
2020-04-08 03:37 AM
Hi @XXu.1 , are you using also the X-NUCLEO-IKS01A2 expansion board for the LSM9DS1 interfacing? This because the issues could come from two sides: first one the HW used, second one the fact that the X-CUBE-MEMS1 expansion software package and the related libraries such as the MotionFX is optimized for LSM6DSxx and LSM303AGR products, not for the LSM9DS1 one. I suggest you to try first with the former products and maybe interfacing with Unicleo-GUI for the initial debug. Regards
2020-06-12 02:26 AM
@Eleon BORLINI :
I also need to interface the LSM9DS1 sensor, however with a different board, the P-Nucleo_WB55.
Where do I get the right driver files for getting the LSM9DS1 up and running? It seems that the MEMS1 package is of no help, however I can't find any other .h or .c files for addressing the chip?
ST, please can you help?