This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nrf52840 MPU9250 Magnetometer Reading

Hello, I am using nrf52840 PDK, sdk 13.0.0. I managed to read accel, gyro data from the MPU9250 using MPU library based on this example. However, I got magnetometer reading 0. I've checked this question and this question. Here is the code how I setup the MPU:

void mpu_setup(void)
{
	printf("\r\nMPU setup start... \r\n");

    ret_code_t ret_code;
    // Initiate MPU driver
    ret_code = mpu_init();

	printf("\r\nMPU init complete! \r\n");	

    APP_ERROR_CHECK(ret_code); // Check for errors in return value

    // Setup and configure the MPU with intial values
    mpu_config_t p_mpu_config = MPU_DEFAULT_CONFIG(); // Load default values
    p_mpu_config.smplrt_div = 19;   // Change sampelrate. Sample Rate = Gyroscope Output Rate / (1 + SMPLRT_DIV). 19 gives a sample rate of 50Hz
    p_mpu_config.accel_config.afs_sel = AFS_16G; // Set accelerometer full scale range
    p_mpu_config.gyro_config.fs_sel = GFS_1000DPS; //Set gyroscope full scale range 
    ret_code = mpu_config(&p_mpu_config); // Configure the MPU with above values
    APP_ERROR_CHECK(ret_code); // Check for errors in return value 
}

void magn_setup()
{
	ret_code_t ret_code;
	
	
	//Enable bypass mode
	mpu_int_pin_cfg_t bypass_config;
	bypass_config.i2c_bypass_en = 1;
	ret_code = mpu_int_cfg_pin(&bypass_config); // Set bypass mode
	APP_ERROR_CHECK(ret_code); // Check for errors in return value
	

	// Setup and configure the MPU Magnetometer
	mpu_magn_config_t p_mpu_magn_config;
	p_mpu_magn_config.resolution = OUTPUT_RESOLUTION_16bit; // Set output resolution
	p_mpu_magn_config.mode = CONTINUOUS_MEASUREMENT_100Hz_MODE;	//Set measurement mode
	
	ret_code = mpu_magnetometer_init(&p_mpu_magn_config);
	APP_ERROR_CHECK(ret_code); // Check for errors in return value

}

The full project can be found here. Need some help. Many thanks.

======================================================================

Update 22 Jan 2018:

Code added to magn_setup:

    ret_code = nrf_drv_mpu_write_magnetometer_register(0x0A, 6);	//writing to the control register
	APP_ERROR_CHECK(ret_code);	
	
	uint8_t TempReading;
	ret_code = nrf_drv_mpu_read_magnetometer_registers(0x00, &TempReading, 8);
	APP_ERROR_CHECK(ret_code);
	printf("Device ID: %d \n", TempReading);

	ret_code = nrf_drv_mpu_read_magnetometer_registers(0x0A, &TempReading, 8);
	APP_ERROR_CHECK(ret_code);
	printf("Vaule read from control register: %d \n", TempReading);

Result observed by Termite:

Test1: MPU twi communication 

MPU setup start... 

MPU init complete! 

MPU setup complete! 
Device ID: 72 
Vaule read from control register: 6 
Accel Data: X: 000732 ; Y: -00111 ; Z: -02000 ; 
Gyro Data: X: -00010 ; Y: 000030 ; Z: 000021 ; 
Magn Data: X: 000000 ; Y: 000000 ; Z: 000000 ; 
Parents
  • Hi,

    It seems like I forgot to add functions for actually starting the magnetometer. Please refer to the MPU 9250 register map and look at Chapter 5.8, CNTL1: Control 1. Write e.g. 6 to this register to start continuous measurement.

    A quick and dirty way to do it is to include nrf_drv_mpu.h in main.c and call nrf_drv_mpu_write_magnetometer_register(0x0A, 6) when you initialize your MPU.

    Note to MPU 9150 users: There is no continuous mode on the MPU 9150 so a single measurement has to be started before every read. Note that it seems like it takes ~5ms from the measurement is started until valid data is ready to be read.

  • If you write '1' to the control register (CNTL1 at 0x0A) you start a single magnetometer measurement. It could be that you start the measurement, but read the data before the measurement is completed. When I put in a 5ms delay between starting a single mode measurement and reading the data it worked fine (with an MPU 9150 though). If you write '6' to the register instead you will start continuous measurements.

Reply
  • If you write '1' to the control register (CNTL1 at 0x0A) you start a single magnetometer measurement. It could be that you start the measurement, but read the data before the measurement is completed. When I put in a 5ms delay between starting a single mode measurement and reading the data it worked fine (with an MPU 9150 though). If you write '6' to the register instead you will start continuous measurements.

Children
No Data
Related