cancel
Showing results for 
Search instead for 
Did you mean: 

[MPU9250][AK8963] Read magnetometer data problem

MNowa.10
Associate

Hey.

I have a small problem with the MPU9250 module, and more specifically AK8963 (Magnetometer). Reading the values ​​measured by the accelerometer and gyro did not cause me major problems and everything works properly. The matter was complicated when I wanted to read the values ​​measured by the magnetometer. In general, communication with the magnetometer works correctly (WHO_AM_I etc.). The problem is that after reading the values ​​from the registers HXL, HXH ... all the time I get the value -1 for each axis.

Code fragment with magnetometer initialization:

MPU9250_Error_code MPU9250_Magnetometer_Configuration(I2C_HandleTypeDef *I2Cx,
												      struct MPU9250 *DataStructure) {
 
 
	uint8_t Byte_temp = 0x00;
	uint8_t Bytes_temp[3] = {0};
 
	DataStructure->Magnetometer_addres = 0x0C << 1;
 
	// Case 2: Disable the I2C master interface
	Byte_temp = 0x00;
 
	if( HAL_I2C_Mem_Write(I2Cx, DataStructure->Device_addres, MPU9250_USER_CTRL, 1, &Byte_temp, 1, 1000) != HAL_OK ) {
 
		//HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
		return MPU9250_Magnetometer_Config_FAIL;
	}
 
	// Case 3: Enable the bypass multiplexer
	Byte_temp = 0x02;
 
	if( HAL_I2C_Mem_Write(I2Cx, DataStructure->Device_addres, MPU9250_INT_PIN_CFG, 1, &Byte_temp, 1, 1000) != HAL_OK ) {
 
		//HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
		return MPU9250_Magnetometer_Config_FAIL;
	}
 
	// Case 1: Is device connected ?
	if( HAL_I2C_IsDeviceReady(I2Cx, DataStructure->Magnetometer_addres, 1, 1000) != HAL_OK ) {
 
		//HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
		return MPU9250_Magnetometer_Config_FAIL;
	}
 
	// Case 2: Who am i test
	if( HAL_I2C_Mem_Read(I2Cx, DataStructure->Magnetometer_addres, MPU9250_WIA, 1, &Byte_temp, 1, 1000) != HAL_OK ) {
 
		//HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
		return MPU9250_Init_FAIL;
	}
 
	if( Byte_temp != 0x48 ) {
 
		//HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
		return MPU9250_Init_FAIL;
	}
 
	// Case 4: Setup to fuse ROM access mode and 16-bit output
	Byte_temp = 0x1F;
 
	if( HAL_I2C_Mem_Write(I2Cx, DataStructure->Magnetometer_addres, MPU9250_CNTL1, 1, &Byte_temp, 1, 1000) != HAL_OK ) {
 
		//HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
		return MPU9250_Magnetometer_Config_FAIL;
	}
 
	HAL_Delay(100);
 
	// Case 5: Read from the fuse ROM sensitivity adjustment values
	if( HAL_I2C_Mem_Read(I2Cx, DataStructure->Magnetometer_addres, MPU9250_ASAX | 0x80, 1, Bytes_temp, 3, 1000) != HAL_OK ) {
 
		//HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
		return MPU9250_Magnetometer_Config_FAIL;
	}
 
	DataStructure->Magnetometer_ASAX = ( ( (Bytes_temp[0] - 128) * 0.5 ) / 128 ) + 1;
	DataStructure->Magnetometer_ASAY = ( ( (Bytes_temp[1] - 128) * 0.5 ) / 128 ) + 1;
	DataStructure->Magnetometer_ASAZ = ( ( (Bytes_temp[2] - 128) * 0.5 ) / 128 ) + 1;
 
	// Case 6: Reset to power down mode
	Byte_temp = 0x00;
 
	if( HAL_I2C_Mem_Write(I2Cx, DataStructure->Magnetometer_addres, MPU9250_CNTL1, 1, &Byte_temp, 1, 1000) != HAL_OK ) {
 
		//HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
		return MPU9250_Magnetometer_Config_FAIL;
	}
 
	// Case 7: Enable continuous mode 2 and 16-bit output
	Byte_temp = 0x16;
 
	if( HAL_I2C_Mem_Write(I2Cx, DataStructure->Magnetometer_addres, MPU9250_CNTL1, 1, &Byte_temp, 1, 1000) != HAL_OK ) {
 
		//HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
		return MPU9250_Magnetometer_Config_FAIL;
	}
 
	HAL_Delay(100);
 
	return MPU9250_Magnetometer_Config_OK;
}

Code fragment with reading of measured values:

MPU9250_Error_code MPU9250_Read_Magnetometer(I2C_HandleTypeDef *I2Cx,
										     struct MPU9250 *DataStructure) {
 
	uint8_t Bytes_temp[7] = { 0x00 };
 
	if( HAL_I2C_Mem_Read(I2Cx, DataStructure->Magnetometer_addres, MPU9250_HXL | 0x80, 1, Bytes_temp, 7, 1000) != HAL_OK ) {
 
		//HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
		return MPU9250_Read_Magnetometer_FAIL;
	}
 
	DataStructure->Magnetometer_X = Bytes_temp[0] | Bytes_temp[1] << 8;
	DataStructure->Magnetometer_Y = Bytes_temp[2] | Bytes_temp[3] << 8;
	DataStructure->Magnetometer_Z = Bytes_temp[4] | Bytes_temp[5] << 8;
 
	return MPU9250_Read_Magnetometer_OK;
}

1 REPLY 1
Eleon BORLINI
ST Employee

Hi @MNowa.10​ , MPU9250 module is a TDK and not an ST module :smiling_face_with_smiling_eyes: These libraries (HAL_I2C_Mem package) are intended to work for ST sensors (e.g. LSM9DS1 i-Nemo module). I suggest you to share your question with TDK and STM32 community; in case you are interfacing the module with an Arduino, I suggest you to directly post your question to TDK support. Regards