kriswiner / MPU6050

Basic MPU6050 Arduino sketch of sensor function

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

MPU6050IMU.ino accelerometer offset - temperature compensation bit

huirad opened this issue · comments

Hi Kris,

I stumbled over you code when researching MPU6050 accelerometer bias correction.
Thank you very much for sharing

Maybe I spotted kind of a bug - please verify:
When you calculate
accel_bias_reg[2] -= (accel_bias[2]/8);
then you might accidently set the lowest (i.e. temperature compensation) bit even if it has not been set previously.

Best Regards,

Helmut

The line you quote from https://raw.githubusercontent.com/kriswiner/MPU-6050/master/MPU6050IMU.ino can't by itself overwrite the temperature bit. When the bias is written into the bias register there is coding ( temperature bit mask) to preserve the temperature bit when it is set. I am not convinced this always works since i have had some strange results. meaning when I write the bias to the bias register sometimes I still have a fairly large offset. So I usually just send the bias assessment to the main code and subtract it from the scaled data rather than rely on writing to the bias register. But i think the coding as it is is correct. If you still don't think so, can you suggest a correction?

I understand your explanation of bit 0 such that it's only about the temperature compensation.
And the way I read your code, it can happen that you set bit 0 even if it has not been set originally. Your code currently only guarantees that when bit 0 has been set originally, it will be set again when you write it back.

As an example, assume you read accel_bias_reg[2] == 0x0102 from the MPU and you measure accel_bias[2] == 0x08. Then after calculating accel_bias_reg[2] -= (accel_bias[2]/8); you get accel_bias_reg[2] == 0x0101, i.e. you would accidently set the lowest bit. This is not changed when you set up for transmission as data[5] = (accel_bias_reg[2]) & 0xFF; data[5] = data[5] | mask_bit[2];. Still, data[5] would be set to 0x01.
You could avoid this by masking out the lowest bit when deriving data[5] from accel_bias_reg[2], i.e. calling data[5] = (accel_bias_reg[2]) & 0xFE; instead of data[5] = (accel_bias_reg[2]) & 0xFF; Still, of course, you would have to call data[5] = data[5] | mask_bit[2]; afterwards to preserve the original bit 0.

I did not find any documentation about the accelerometer offset registers in the register map which is available for public download ("MPU-6000 and MPU-6050 Register Map and Descriptions Revision 4.2"). Can you give me a hint where to search further when I need more information?
The problem which I currently have is that the offset values which I write to the MPU6050 are not preserved when I power off the device and start it again - I always get the original values after a restart. I wonder if there is a command to store such parameters persistently.

By the way, you find the current state of my trials at bitbucket with most documentation in I2C_RaspberryPi.md. I might move it over to github at some time to consolidate my stuff.

Hi Helmut,

I take your point and thanks for the explicit example. I will try your
suggestion of "and"ing with 0xFE; I think this should work. It might explain
why I have seen inconsistencies in the past when using the bias registers.

Apparently attachments don't show up here. PM me at onehorse@earthlink.net and I will send you the Invensense document that details their recommended calibration procedure.

Attached is a document I got from Invensense; I don't think it is publically
available. It describes their calibration procedure. You will see they "and"
with 0xFF and I just copied their code more or less. But I agree with you,
it is not correct.

Kris

-----Original Message-----
From: Helmut Schmidt [mailto:notifications@github.com]
Sent: July 5, 2015 9:30 PM
To: kriswiner/MPU-6050
Cc: Kris Winer
Subject: Re: [MPU-6050] MPU6050IMU.ino accelerometer offset - temperature
compensation bit (#8)

I understand your explanation of bit 0 such that it's only about the
temperature compensation.
And the way I read your code, it can happen that you set bit 0 even if it
has not been set originally. Your code currently only guarantees that when
bit 0 has been set originally, it will be set again when you write it back.

As an example, assume you read accel_bias_reg[2] == 0x0102 from the MPU and
you measure accel_bias[2] == 0x08. Then after calculating accel_bias_reg[2]
-= (accel_bias[2]/8); you get accel_bias_reg[2] == 0x0101, i.e. you would
accidently set the lowest bit. This is not changed when you set up for
transmission as data[5] = (accel_bias_reg[2]) & 0xFF; data[5] = data[5] |
mask_bit[2];. Still, data[5] would be set to 0x01.
You could avoid this by masking out the lowest bit when deriving data[5]
from accel_bias_reg[2], i.e. calling data[5] = (accel_bias_reg[2]) & 0xFE;
instead of data[5] = (accel_bias_reg[2]) & 0xFF; Still, of course, you would
have to call data[5] = data[5] | mask_bit[2]; afterwards to preserve the
original bit 0.

I did not find any documentation about the accelerometer offset registers in
the register map which is available for public download ("MPU-6000 and
MPU-6050 Register Map and Descriptions Revision 4.2"). Can you give me a
hint where to search further when I need more information?
The problem which I currently have is that the offset values which I write
to the MPU6050 are not preserved when I power off the device and start it
again - I always get the original values after a restart. I wonder if there
is a command to store such parameters persistently.

Reply to this email directly or view it on GitHub
#8 (comment) .
<https://github.com/notifications/beacon/AGY1qrjuCyav0IfQ42Lop4pbje_YodH7ks5
oafvMgaJpZM4FSMUk.gif>

Hi Helmut,

Oh I forgot to comment on your last point. You can always calculate the bias
and store in your microcontroller program for subsequent use. I used to do
this for the magnetometer bias calibration. Alternatively you could add an
EEPROM or SPI flash memory to your circuit. See, for example,

https://www.tindie.com/products/onehorse/spi-flash-memory-add-ons-for-teensy
-3x/,

at my Tindie store.

There is no way I know of to store the bias values on the MPU9250 itself.

Kris

-----Original Message-----
From: Helmut Schmidt [mailto:notifications@github.com]
Sent: July 5, 2015 9:30 PM
To: kriswiner/MPU-6050
Cc: Kris Winer
Subject: Re: [MPU-6050] MPU6050IMU.ino accelerometer offset - temperature
compensation bit (#8)

I understand your explanation of bit 0 such that it's only about the
temperature compensation.
And the way I read your code, it can happen that you set bit 0 even if it
has not been set originally. Your code currently only guarantees that when
bit 0 has been set originally, it will be set again when you write it back.

As an example, assume you read accel_bias_reg[2] == 0x0102 from the MPU and
you measure accel_bias[2] == 0x08. Then after calculating accel_bias_reg[2]
-= (accel_bias[2]/8); you get accel_bias_reg[2] == 0x0101, i.e. you would
accidently set the lowest bit. This is not changed when you set up for
transmission as data[5] = (accel_bias_reg[2]) & 0xFF; data[5] = data[5] |
mask_bit[2];. Still, data[5] would be set to 0x01.
You could avoid this by masking out the lowest bit when deriving data[5]
from accel_bias_reg[2], i.e. calling data[5] = (accel_bias_reg[2]) & 0xFE;
instead of data[5] = (accel_bias_reg[2]) & 0xFF; Still, of course, you would
have to call data[5] = data[5] | mask_bit[2]; afterwards to preserve the
original bit 0.

I did not find any documentation about the accelerometer offset registers in
the register map which is available for public download ("MPU-6000 and
MPU-6050 Register Map and Descriptions Revision 4.2"). Can you give me a
hint where to search further when I need more information?
The problem which I currently have is that the offset values which I write
to the MPU6050 are not preserved when I power off the device and start it
again - I always get the original values after a restart. I wonder if there
is a command to store such parameters persistently.

Reply to this email directly or view it on GitHub
#8 (comment) .
<https://github.com/notifications/beacon/AGY1qrjuCyav0IfQ42Lop4pbje_YodH7ks5
oafvMgaJpZM4FSMUk.gif>

Hi Kris,

I meanwhile found out that also hobbyists can register for an Invensense developer account at http://www.invensense.com/developers.
So I did and I found a document MPU HW Offset Registers 1.2.pdf as part of the "Embedded MotionDriver" packages (v5.1.3 as well as 6.12) in the software downloads section.
This document describes the HW offset registers and indeed at the end of this document it is stated that the factory dafaults will be reloaded at each power on.
Maybe that's the document which you mean?

In the example code there they take special care to preserve bit 0 by masking it from the value which is subtracted (note the & ~1)
// Preserve bit 0 of factory value (for temperature compensation)
accel_reg_bias[0] -= (accel_bias[0] & ~1);

I also found some interesting discussions in their forum on accelerometer z-axis offsets which indicate me that I am not alone with the large offset on my MPU6050.

http://www.invensense.com/forum/viewtopic.php?f=3&t=916&p=3457&hilit=offset#p3457
"This is due to the offset of our chip. For the 9150 it's 150mg on the z axis. Based on the setting and 8g full scale range, 150 is corresponding to LSB count 614."
http://www.invensense.com/forum/viewtopic.php?f=3&t=927&p=3415&hilit=offset#p3415
"As you said once the power is reset, all the values should be restored to the default values. Register 0x0A is not configurable."
http://www.invensense.com/forum/viewtopic.php?f=3&t=262&p=1202&hilit=offset#p1202
"I experience an offset on the Z-axis of the accelerometer. It's always around 0.2 - 0.3 G."
"... however the Z-Axis accelerometer has been known to shift offset due to package stress during the assembly process.
... Typically, this shift is permanent and sensitivities are unaffected, so the functionality can be easily calibrated and compensated for in software."

Thank you very much for your help,

Helmut

Hi Helmut,

I have a document on calibrating the MPU6050 and MPU9x50 accel and gyros. It
makes use of the hardware bias registers and I though I copied the relevant
temperature bit masking but I could have mis-transcribed it. The mask with
~1 is equivalent to your suggested "and"ing with 0xFE I believe.

I haven't seen such large offsets but I haven't worked with the MPU6050 or
9150 much in the last year, focusing my attention on the MPU9250. This
latter has offsets typically of ~50 mg or less which are easily eliminated
with simple subtraction of a calculated average bias.

Kris

Kris

-----Original Message-----
From: Helmut Schmidt [mailto:notifications@github.com]
Sent: July 6, 2015 12:13 PM
To: kriswiner/MPU-6050
Cc: Kris Winer
Subject: Re: [MPU-6050] MPU6050IMU.ino accelerometer offset - temperature
compensation bit (#8)

Hi Chris,

I meanwhile found out that also hobbyists can register for an Invensense
developer account at http://www.invensense.com/developers.
So I did and I found a document MPU HW Offset Registers 1.2.pdf as part of
the "Embedded MotionDriver" packages (v5.1.3 as well as 6.12) in the
software downloads section.
This document describes the HW offset registers and indeed at the end of
this document it is stated that the factory dafaults will be reloaded at
each power on.
Maybe that's the document which you mean?

In the example code there they take special care to preserve bit 0 by
masking it from the value which is subtracted (note the & ~1)
// Preserve bit 0 of factory value (for temperature compensation)
accel_reg_bias[0] -= (accel_bias[0] & ~1);

I also found some interesting discussions in their forum on accelerometer
z-axis offsets which indicate me that I am not alone with the large offset
on my MPU6050.

http://www.invensense.com/forum/viewtopic.php?f=3&t=916&p=3457&hilit=offset#
p3457
"This is due to the offset of our chip. For the 9150 it's 150mg on the z
axis. Based on the setting and 8g full scale range, 150 is corresponding to
LSB count 614."
http://www.invensense.com/forum/viewtopic.php?f=3&t=927&p=3415&hilit=offset#
p3415
"As you said once the power is reset, all the values should be restored to
the default values. Register 0x0A is not configurable."

http://www.invensense.com/forum/viewtopic.php?f=3&t=262&p=1202&hilit=offset#
p1202
"I experience an offset on the Z-axis of the accelerometer. It's always
around 0.2 - 0.3 G."
"... however the Z-Axis accelerometer has been known to shift offset due to
package stress during the assembly process.
... Typically, this shift is permanent and sensitivities are unaffected, so
the functionality can be easily calibrated and compensated for in software."

Thank you very much for your help,

Helmut

Reply to this email directly or view it on GitHub
#8 (comment) .
<https://github.com/notifications/beacon/AGY1qj-A0m2i4SPBVgQ9PF89vKKUfixpks5
oasrLgaJpZM4FSMUk.gif>

I just saw that I forgot to close this issue 5 years ago,
Closing it now.