cancel
Showing results for 
Search instead for 
Did you mean: 

stm32f4 + lsm9ds1 + motionFx The output data looks like random,i need help thankyou

XXu.1
Associate

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, &reg);
//
//	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

2 REPLIES 2
Eleon BORLINI
ST Employee

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

MHell.1
Associate II

@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?