jefmenegazzo/mpu-i2c-drivers-python

Values are changing while complete still

JohnPreston opened this issue · 4 comments

Describe the bug
The readings from the board are changing dramatically whilst the board is completely still.

Hello :)
I recently aquired the MPU9250 as an upgrade to get the magnetometer to be able to read the heading.
Whilst looking for a library, this one seemed to be by far the most solid in docs and examples.
So unless I am a complete dummy (which is possible) something seems wrong with the readings I am getting.

|.....MPU9250 in 0x68 Address.....|
Accelerometer [-0.19921875, -1.550048828125, -7.0]
Gyroscope [-0.0682830810546875, -0.15316009521484353, 0.21915435791015614]
Magnetometer [-0.2911545341232835, 0.2014987670749353, 1.4122445841195845]
Temperature 28.475963698445504
145.31412714135627

[1 sec later]

|.....MPU9250 in 0x68 Address.....|
Accelerometer [-0.197265625, -1.538330078125, -7.0]
Gyroscope [0.0537872314453125, -0.06160736083984353, -0.11653900146484386]
Magnetometer [-0.2911545341232835, 1.4104913695245713, 1.0356460283543585]
Temperature 28.284272321562284
101.66321840226273

Because it is not moving, the accelerometer seems to be rather stable.
The gyro and the magnetometer though are behaving as if there was movement.

I do not have another MPU9250 to compare this to.
Any good guess on what might be going on / what I am doing wrong ?

Many thanks,

To Reproduce

import time
import math
from mpu9250_jmdev.registers import *
from mpu9250_jmdev.mpu_9250 import MPU9250

mpu = MPU9250(
    address_ak=AK8963_ADDRESS,
    address_mpu_master=MPU9050_ADDRESS_69,
    address_mpu_slave=None,
    bus=1,
    gfs=GFS_1000,
    afs=AFS_8G,
    mfs=AK8963_BIT_16,
    mode=AK8963_MODE_C100HZ,
)

mpu.configure()
mpu.calibrate()

while True:

    print("|.....MPU9250 in 0x68 Address.....|")
    print("Accelerometer", mpu.readAccelerometerMaster())
    print("Gyroscope", mpu.readGyroscopeMaster())
    print("Magnetometer", mpu.readMagnetometerMaster())
    print("Temperature", mpu.readTemperatureMaster())

    magnet = mpu.readMagnetometerMaster()
    print(90 - math.atan2(magnet[0], magnet[1]) * 180 / math.pi)

    time.sleep(1)

Expected behavior
Expecting the values to be constant when the module is not moving at all

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • RaspberryPI (raspbian)
  • Python3.7

@JohnPreston Some considerations:

  1. Sensor calibration

Are you doing the calibration correctly? Remember that that:

  • To calibrate the accelerometer and gyroscope sensors, make sure that the sensors remain fixed and stationary. Align the accelerometer's Z axis with gravity, i.e., gravity (1g or 9.8m/s²) should only appear on the sensor's Z axis (place the sensor in a flat place). Look at the figure below, the Z axis must point towards the sky.

image

  • After calibrating the sensors, call:
    mpu.configure()

Better yet, calculate the calibration values only once and in the next execution pass the values as follows:

mpu.calibrate() # Calibrate all sensors
abias = mpu.abias # Get the master accelerometer biases
gbias = mpu.gbias # Get the master gyroscope biases
magScale = mpu.magScale # Get magnetometer soft iron distortion
mbias = mpu.mbias # Get magnetometer hard iron distortion

Save the values of all these variables (print on the console) and set parameters for the following variables:

mpu.abias = [0, 0, 0] # Set the master accelerometer biases
mpu.gbias = [0, 0, 0] # Set the master gyroscope biases
mpu.magScale = [0, 0, 0] # Set magnetometer soft iron distortion
mpu.mbias = [0, 0, 0] # Set magnetometer hard iron distortion

Final code example:

import time
import math
from mpu9250_jmdev.registers import *
from mpu9250_jmdev.mpu_9250 import MPU9250

##################################################
# Create                                         
##################################################

mpu = MPU9250(
    address_ak=AK8963_ADDRESS,
    address_mpu_master=MPU9050_ADDRESS_69,
    address_mpu_slave=None,
    bus=1,
    gfs=GFS_1000,
    afs=AFS_8G,
    mfs=AK8963_BIT_16,
    mode=AK8963_MODE_C100HZ,
)

##################################################
# Configure                                      
##################################################
mpu.configure() # Apply the settings to the registers.

##################################################
# Calibrate - Only the first time/execution                                  
##################################################
# mpu.calibrate() # Calibrate sensors
# mpu.configure() # The calibration function resets the sensors, so you need to reconfigure them

##################################################
# Get Calibration - Only the first time/execution - Place the values printed in the block 'Set Calibration'
##################################################
# abias = mpu.abias # Get the master accelerometer biases
# gbias = mpu.gbias # Get the master gyroscope biases
# magScale = mpu.magScale # Get magnetometer soft iron distortion
# mbias = mpu.mbias # Get magnetometer hard iron distortion

# print("|.....MPU9250 in 0x69 Biases.....|")
# print("Accelerometer", abias)
# print("Gyroscope", gbias)
# print("Magnetometer SID", magScale)
# print("Magnetometer HID", mbias)
# print("\n")

##################################################
# Set Calibration  - Use from the second time/execution                              
##################################################
mpu.abias = [-0.08004239710365854, 0.458740234375, 0.2116996951219512]
mpu.gbias = [0.8958025676448171, 0.45292551924542684, 0.866773651867378]
mpu.magScale = [1.0104166666666667, 0.9797979797979799, 1.0104166666666667]
mpu.mbias = [2.6989010989010986, 2.7832417582417586, 2.6989010989010986]

##################################################
# Show Values                                    #
##################################################
while True:
   
    print("|.....MPU9250 in 0x69 Address.....|")
    print("Accelerometer", mpu.readAccelerometerMaster())
    print("Gyroscope", mpu.readGyroscopeMaster())
    print("Magnetometer", mpu.readMagnetometerMaster())
    print("Temperature", mpu.readTemperatureMaster())

    magnet = mpu.readMagnetometerMaster()
    print(90 - math.atan2(magnet[0], magnet[1]) * 180 / math.pi)

    time.sleep(1)
  1. Variation in values

It is common for the values to vary very little in decimal places even when the sensor is 'stopped', don't worry about it. It is interesting that you enter a Full Scale Range (FSR) value for the accelerometer (AFS_2G, AFS_4G, AFS_8G or AFS_16G) and for the gyroscope (GFS_250, GFS_500, GFS_1000 or GFS_2000) according to what your application needs. Note that the higher the FSR value you set, the greater the representation error (since there are a limited number of bits to represent the values). Likewise, the lower the FSR you put in, there will be less representation errors, but the sensor range is limited to a lower range.

Share later if you managed to run correctly, it may be important for other people who use lib :)

Hi @jefmenegazzo

Thanks for replying so early.

I have updated the code with the following as per your indications.

import time
import math
from mpu9250_jmdev.registers import *
from mpu9250_jmdev.mpu_9250 import MPU9250

mpu = MPU9250(
    address_ak=AK8963_ADDRESS,
    address_mpu_master=MPU9050_ADDRESS_69,
    address_mpu_slave=None,
    bus=1,
    gfs=GFS_1000,
    afs=AFS_8G,
    mfs=AK8963_BIT_16,
    mode=AK8963_MODE_C100HZ,
)

mpu.configure()
mpu.calibrate()
mpu.configure()
count = 0

while True:
    print(f"T+{count}")
    print("Accelerometer", mpu.readAccelerometerMaster())
    print("Gyroscope", mpu.readGyroscopeMaster())
    print("Magnetometer", mpu.readMagnetometerMaster())
    print("Temperature", mpu.readTemperatureMaster())
    magnet = mpu.readMagnetometerMaster()
    print(90 - math.atan2(magnet[0], magnet[1]) * 180 / math.pi)
    time.sleep(1)

Which still results into very different outputs

Calibrating 0x69 - AK8963stro-py $ python gyro.py 
Calibrating 0x69 - MPU6500
T+0
Accelerometer [-0.20703125, -1.586669921875, -7.0]
Gyroscope [0.00705718994140625, -0.10395050048828125, 0.3746032714843749]
Magnetometer [0.3842335771422301, -0.26008066107742706, 0.48456832519332504]
Temperature 24.354599095456315
-34.093350546568814
T+1
Accelerometer [-0.196533203125, -1.5869140625, -7.0]
Gyroscope [-0.11501312255859375, 0.07915496826171875, 0.1609802246093749]
Magnetometer [-0.3842335771422301, 1.1270161980021862, -0.16152277506444168]
Temperature 24.546290472339532
135.2081701043849
T+2
Accelerometer [-0.1962890625, -1.58935546875, -7.0]
Gyroscope [0.00705718994140625, 0.10967254638671875, 0.2525329589843749]
Magnetometer [-0.7684671542844526, 0.7802419832322881, 0.16152277506444168]
Temperature 24.450444783897925
242.9150279871158
T+3
Accelerometer [-0.19384765625, -1.58740234375, -7.0]
Gyroscope [-0.05397796630859375, -0.25653839111328125, -0.05264282226562511]
Magnetometer [-1.729051097140028, 1.3004033053871422, 0.6460911002577667]
Temperature 24.546290472339532
143.0535135824202
T+4
Accelerometer [-0.199462890625, -1.59423828125, -7.0]
Gyroscope [0.19016265869140625, -0.28705596923828125, -0.2967834472656251]
Magnetometer [-0.3842335771422301, 1.1270161980021862, -0.8076138753222084]
Temperature 24.450444783897925
133.52317032931552
T+5
Accelerometer [-0.20166015625, -1.59228515625, -7.0]
Gyroscope [0.00705718994140625, -0.10395050048828125, 0.09994506835937489]
Magnetometer [0.3842335771422301, -0.26008066107742706, -0.16152277506444168]
Temperature 24.737981849222752
44.3545018316897
T+6
Accelerometer [-0.2060546875, -1.579345703125, -7.0]
Gyroscope [0.00705718994140625, -0.13446807861328125, 0.008392333984374889]
Magnetometer [-1.3448175199977976, -0.08669355369247106, -0.6460911002577667]
Temperature 24.59421331656034
183.68846407101896

The board is laying flat on the bread-board which itself is flat relative to the horizon, the MPU is facing up (to the sky).
Throughtout, the board remained still and did not move at all, yet as you can see, the values change once again dramatically :/

My aspiration is to be able to use the magnetometer to drive a platform to point to a specific azimuth (angle relative to magnetic north) so I do not need (I suppose) insane frequency of updates, as the rotation would be very slow anyway.

The gyro would eventually give me elevation from the horizon.

Of course for the purpose of this exercise I would probably set the bias once and only re-calibrate if I moved significantly (geographically) for better accuracy.

That said, can one not just do

mpu.configure()
mpu.calibrate()
mpu.configure()

every time?
I do not mind the few seconds of calibration each time.

Thank you very much.

Hi I have same problem:
Magnetometer data are unstable when board fixed and stationary

My code:

import sys
sys.path.append("")

import time
from mpu9250_jmdev.registers import *
from mpu9250_jmdev.mpu_9250 import MPU9250

mpu = MPU9250(
    address_ak=AK8963_ADDRESS, 
    address_mpu_master=MPU9050_ADDRESS_68, # In 0x68 Address
    address_mpu_slave=None, 
    bus=1, 
    gfs=GFS_250, 
    afs=AFS_2G, 
    mfs=AK8963_BIT_16, 
    mode=AK8963_MODE_C100HZ)

mpu.configure() # Apply the settings to the registers.

mpu.abias = [-0.030694580078125, -0.0044921875, -0.016857910156250044]
mpu.gbias = [2.8245925903320312, -0.4629135131835937, 0.298309326171875]
mpu.magScale = [0.9777777777777777, 1.0864197530864197, 0.9462365591397849]
mpu.mbias = [-0.5376717032967032, 91.79280086233211, -35.160976610195355]

while True:
   
    print("|.....MPU9250 in 0x68 Address.....|")
    print("Accelerometer", mpu.readAccelerometerMaster())
    print("Gyroscope", mpu.readGyroscopeMaster())
    magnet = mpu.readMagnetometerMaster()
    magnet_value = 90 - math.atan2(magnet[0], magnet[1]) * 180 / math.pi
    print("Magnetometer", magnet_value)
    print("\n")

    time.sleep(2)

Output(The board is laying flat on the bread-board which itself is flat relative to the horizon, the MPU is facing up to the sky):

|.....MPU9250 in 0x68 Address.....|
Accelerometer [-0.0003112792968750014, -0.00014648437500000035, 0.99610595703125]
Gyroscope [-0.14667510986328125, -0.0864028930664063, -0.107574462890625]
Magnetometer 209.1340319795019


|.....MPU9250 in 0x68 Address.....|
Accelerometer [-0.0015319824218750014, -0.0038085937500000003, 1.00660400390625]
Gyroscope [0.15850067138671875, -0.0635147094726563, -0.008392333984375]
Magnetometer 250.2606246436067


|.....MPU9250 in 0x68 Address.....|
Accelerometer [0.0035949707031249986, -0.00014648437500000035, 1.00367431640625]
Gyroscope [0.12798309326171875, 0.2111434936523437, -0.061798095703125]
Magnetometer -90.0


|.....MPU9250 in 0x68 Address.....|
Accelerometer [-0.0020202636718750014, 0.0020507812499999997, 0.99927978515625]
Gyroscope [0.02880096435546875, 0.020408630371093694, 0.128936767578125]
Magnetometer 50.802180455092845


|.....MPU9250 in 0x68 Address.....|
Accelerometer [0.0011535644531249986, -0.00039062500000000035, 1.00147705078125]
Gyroscope [-0.09326934814453125, 0.1195907592773437, 0.083160400390625]
Magnetometer 258.725962634373


|.....MPU9250 in 0x68 Address.....|
Accelerometer [0.0011535644531249986, 9.765624999999965e-05, 1.00074462890625]
Gyroscope [-0.00934600830078125, 0.1729965209960937, 0.083160400390625]
Magnetometer -29.134031979501188


|.....MPU9250 in 0x68 Address.....|
Accelerometer [0.0033508300781249986, -0.0006347656250000003, 1.00074462890625]
Gyroscope [0.09746551513671875, -0.0024795532226563055, 0.029754638671875]
Magnetometer 24.913733259067243


|.....MPU9250 in 0x68 Address.....|
Accelerometer [0.0004211425781249986, 0.0032714843749999997, 1.00660400390625]
Gyroscope [-0.18482208251953125, 0.2035140991210937, 0.045013427734375]
Magnetometer 251.93332729404548

Same here. I havent had time to pet the project using this since to try new things but problem remains.