I hadn't bothered with the magnetometer on the MPU-9250 since I was interested in high rate gyro data and a previous bad experience with the MPU-9150.
When using an SPI interface with the MPU-9250 like I am (I2C can't support 32KSPS gyro data.) you need to use the slave controller to access the magnetometer.
I setup two I2C slave controller channels. The first (slave 0) is configured to read the results while the second sends the command to start a conversion. This runs at the sample rate so the sample rate must be 100Hz or less.
I like to use a table of register number/value pairs to initialize:
This is in Forth but you should be able to get the point. (numbers with a leading "$" are base 16 while the others are base 10.)
After doing that the magnetometer will make a conversion at the sample rate and the results will be moved to the slave data registers (73+). Where it can be read along with the rest of the data.
I captured a little data just to see if the 9250 really had improved on the magnetometer in the 9150. It is better but still not great. The useful range is improved (at least when using the 16 bit conversion mode) but the noise is still excessive. If you want to get decent results for something like a compass you will have to run the data through a low pass filter.
The initial offset is also large. Since that isn't stable, you will have to do periodic recalibration.
When using an SPI interface with the MPU-9250 like I am (I2C can't support 32KSPS gyro data.) you need to use the slave controller to access the magnetometer.
I setup two I2C slave controller channels. The first (slave 0) is configured to read the results while the second sends the command to start a conversion. This runs at the sample rate so the sample rate must be 100Hz or less.
I like to use a table of register number/value pairs to initialize:
Code:
0 \ mpu-9250 init table for magnetometer use 23Sep2018
1 VARIABLE INIT-TAB
2 106 , $10 , \ disable I2C slave interface
3 107 , 1 , \ use gyro as clock source (1%)
4 25 , 9 , \ sample rate divider = 10
5 26 , 5 , \ gyro DLPF is 10Hz
6 27 , $8 , \ 1KHz sample rate, 500 dps
7 28 , $18 , \ accel range = 16G
8 29 , 5 , \ 1KHz sample rate, DLPF = 10Hz
9 55 , $30 , \ int pin is active high till cleared
10 56 , 1 , \ enable data ready interrupt
11
12 ( Configures the gyros and accels for 100SPS and uses the
13 I2C master controller to capture data from the magnetic
14 sensor. )
15
0 \ MPU-9250 init table for magnetometer, cont. 23Sep2018
1 37 , $8C , \ read from slave address $C
2 38 , 2 , \ start at register 2 (status 1)
3 39 , $88 , \ 8 registers read, at the sample rate
4 40 , $C , \ write to slave address $C
5 41 , 10 , \ to control register
6 42 , $81 , \ 1 byte, at sample rate
7 100 , $11 , \ single conversion mode, 16 bit
8 36 , $4D , \ wait for slave data before data ready
9 106 , $20 , \ enable I2C master
10
11 HERE INIT-TAB - 1 CELLS / 2/ INIT-TAB !
12
13
14
15
After doing that the magnetometer will make a conversion at the sample rate and the results will be moved to the slave data registers (73+). Where it can be read along with the rest of the data.
I captured a little data just to see if the 9250 really had improved on the magnetometer in the 9150. It is better but still not great. The useful range is improved (at least when using the 16 bit conversion mode) but the noise is still excessive. If you want to get decent results for something like a compass you will have to run the data through a low pass filter.
The initial offset is also large. Since that isn't stable, you will have to do periodic recalibration.