CMPS14 - How does calibration work?

I’ve got a few issues with calibrating my CMPS14. I’ll start out by asking if someone can explain how the CMPS14 “calibrates”? (Maybe this is a general question for all electronic compasses.) If I can understand it, maybe I won’t need a subsequent post about my issues.

Calibration involves an instrument that measures a quantity that may have an error in its measured value, that is corrected by using the instrument to measure a KNOWN quantity, and then using the error term to derive a correction factor. For instance, if it’s an electronic thermometer, we would put the thermometer in a chamber that has a known temperature, measure the temp with the thermometer, and save the error in degrees, and apply a correction in all future measurements using this offset.

So what is CMPS14 (BNO080) calibration? Reading the literature and manuals, I see all kinds of statements like “make a couple random motions”, “background calibration”, “rotate in each axis by at least 180 degrees”, etc. No where do I see a well-defined calibration procedure, that has a start and end, and involves pointing the device in a known direction!!! How can this work? How can this device calibrate without a known direction?? I can only conclude that this is not calibration in a strict sense, but is some kind of internal compensation of some unknown quantity.

How does “background calibration” work without a known reference? Is this somehow compensating for local magnetic disturbances? What is the time scale of this? I assume the “profile” is saved in non-volatile memory and then when the device is re-booted, the background calibration continues where it left off?

1 Like

Since I’ve gotten zero replies at this point, I’ll share what I’ve been able to figure out after hours and hours of experiments. What may be glaringly obvious to others, was not to me! For references, I used the CMPS14 manual on Robotshop, and the BNO080 manual.

The term “background” calibration means that some kind of internal adjustment is occuring, that improves the accuracy. This is obviously not a “traditional” foreground calibration, where you intentionally point the compass in one KNOWN DIRECTION (or 4 directions), and send commands when the directions are achieved. It appears that when in “background calibration” mode, the actual calibration is initiated by moving the CMPS14 at large angles over all axis of rotation. It appears that if the device is relatively still, or is only rotated in one axis, it doesn’t do anything. The term “background” kind of applies to the fact that you can continue to poll the device for reports while you are calibrating. If you poll the calibration status (0x24) while calibrating, you can see the status change from 0->3 as you achieve a good cal by swinging the device around in a figure 8 pattern.

So now that we understand (sort of :slight_smile: background calibration, how specifically do we code this? A big question I had was, “Should I leave background calibration on all the time?” Depends on your application. The background cal can be used to recalibrate the unit when it goes to a different location. When you change locations, there may be different local magnetic interference, which I assume the cal takes care of. From this logic, it might makes sense to leave it on all the time, with the knowledge that all you have to do when you take the unit to a new hiking spot, is figure 8 it for 10 seconds to re-calibrate, and you are good to go. However, suppose you use the CMPS14 on a quadcopter, where the “figure 8” may not occur intentionally, and you do not want this to happen because it may change the relative directional calibration. In this case it would make sense to turn calibration off after the figure 8, and keep the calibration procedure under your control.

Steps to calibrate (I’m only using as a compass):

  1. in code, enable cal
    SendCommand(0x98);
    SendCommand(0x95);
    SendCommand(0x99);
    SendCommand(0x87);

  2. Do a real deep, twisty figure 8 for 10 seconds, while monitoring the cal status by sending 0x24. Do this until you get a “3” back for your parameters of interest. I look for magnetometer and system to reach 3

  3. in code, store the cal. This saves the “profile” to non-volatile memory. The unit can be powered down, and back up again, and will retain the cal:
    SendCommand(0xF0);
    SendCommand(0xF5);
    SendCommand(0xF6);

  4. Depending on your application, turn off the cal:
    SendCommand(0x98);
    SendCommand(0x95);
    SendCommand(0x99);
    SendCommand(0x80);

RANDOM NOTES:
I don’t use the accelerometer or gyroscope, so the above procedure needs to be expanded if you want to use these. There are specific enable and disable bits for each device, and different calibation motions. See the BNO080 manual and the CMPS14 manual. You can define each piece of the cal, and in your UI, put up the appropriate user prompts.

To erase the cal, in code:
SendCommand(0xE0);
SendCommand(0xE5);
SendCommand(0xE2);
If you are polling with 0x24, you will see all the values go to zero, and the compass direction may make a large shift back to the uncalibrated state.

Bit 4 of the cal register is to enable auto save. I have not messed with that. The word “periodic” scares me.

The BNO080 manual is really dense, and extremely complicated. So what has happened is various vendors have “wrapped” the device in either hardware or software to allow easier operation. The CMPS14 is wrapped with a microcontroller, and the result is the “API” you see in the CMPS14 manual. Other vendors wrap a naked BNO080 with software, like Arduino libraries or Python libraries.

I’m using the device with a C++ app that runs on Windows that communicates via USB->Serial.

1 Like

Hi @Randy7 !

Too bad that no one replied to your first post, but I am glad that you were able to find the answer :slight_smile:

There is a newer chip out, the BNO086. Interestingly, the data sheet shows this:

  • BNO086 only

    • 14-bit accelerometer fusion
    • Lower idle power
    • Interactive calibration

That last feature looks interesting!

1 Like

I seem to be up and running with the above cal procedure, although I suspect things might be better by calibrating each device (gyroscope, accelerometer, magnetometer) individually.

BNO08X Sensor Calibration Procedure (mouser.com)

This would involve setting and resetting bits 0-2 and performing each of the procedures in the above document.

1 Like

Here is a complete calibration procedure to put a “stake in the ground”. This procedure calibrates each internal device (magnetometer, accelerometer, gyroscope), individually. The ambiguity of this device’s calibration that is available on the internet drives me nuts. Feel free to comment and correct. Disclaimers: I’m using the CMPS14 for boat navigation. My goal was to get an accurate heading from the compass. I don’t directly need the gyroscope or accelerometer, although perhaps they are being used for the heading result. I tried to write the following procedure generically, I’m using C, but you can apply this to other languages. I run this procedure in a thread, monitoring the heading and cal status constantly. Cal status is monitored by sending 0x24 and checking the bits of the returned byte.

Key:
SendCommandTriplet(a,b,c) Sends 3 bytes, checking for 0x55 after each byte send
SendCommand(x) Sends single byte, checking for 0x55 to be returned
See the CMPS14 document here on Robotshop for how to physically move the device

So to calibrate:

// start with the magnetometer
SendCommandTriplet(0x98,0x95,0x99)
SendCommand(0x81)

Flip the CMPS14 as described in document…

// do the accelerometer
SendCommandTriplet(0x98,0x95,0x99)
SendCommand(0x82)

Set the CMPS14 on all sides as described in document…

// do the gyroscope
SendCommandTriplet(0x98,0x95,0x99)
SendCommand(0x84)

Hold the CMPS14 still as described in document…

// turn off the cal
SendCommandTriplet(0x98,0x95,0x99)
SendCommand(0x80)

// write the “profile” to flash
SendCommandTriplet(0xF0,0xF5,0xF6)

Note I turn off the cal after finishing. I do not know the implications of leaving the cal on all the time, so I turn it off. If you perform an “interactive”, intentional calibation, with reasonably well defined movements, wouldn’t it be better to stop potentially ambiguous motion from creating a suboptimal calibration?

Oddities:
If you perform a factory cal reset by using:
SendCommandTriplet(0xE0,0xE5,0xE2)

The device will reset, but enter cal mode. In other words, if you have turned off the cal, this willl turn it back on again. Seems odd to me.

While you are calibrating the magnetometer, if you monitor the cal status, the accelerometer cal status will change also. Seems odd to me.

This procedure seems to work well. If I factory reset the cal, the heading on one of my CMPS14s (I have 2) is off by about 45 degrees, so the factory cal is not very good.

1 Like

Thank you for sharing this with us!

Still struggling with calibration of this little devil. I use this unit in a boat. I would like to have a permanent mounting of the CMPS14 on the hull of the boat. This involves screwing the unit down to a flat surface. However, as I pointed out in the previous post, I question if “turning off background calibration” really works. I went ahead and screwed my CMPS14s down (I have 2 of them) AFTER calibrating them by hand using the suggested motions. I constantly monitor the status of the calibration. Over the course of a couple weeks each unit has gone out of calibration on its own a couple of times. Why?

Does turning off calibration via sending 0x98,0x95,0x99,0x80 survive a power down??? It seems not.

When monitoring the cal status, I see the mag and system number go from 3->2 and back to 3, and have seen it go from 3->0. This implies that the background calibration is not off. The fluctuating values can be seen after hand calibration, and the above sequence, in addition to powerdown->powerup.

I can only conclude that it is impossible to really stop the background cal, so I am going to plan B, which is to velcro the units down (instead of screws) so when the CMPS14 cal value goes to 0, or I see the heading values way out of wack, I don’t have to get out the screwdriver. BTW, I don’t think sending a cal off command at first communication with the unit will work, because if I apply power, there could be a time delay between power up and the time I send the cal off command.

This is rather annoying. Why can’t I REALLY turn off calibration?

Hi Randy,
Did you figure out calibration?
I’m also trying to use the CMPS14 on a boat. When calibration status reaches “3”, it’s very accurate. The problem I’m having is getting calibration status to 3. Like you, I have seen it go from 0 to 2 with specific motions (sides of box, figure 8, etc) but I haven’t figured out the sequence to get it to 3. Sometimes it happens, most of the time it does not get there.
Are you using serial mode? Because the register for calibration in i2c mode is different (0x1E).
It sounds like turning off automatic calibration doesn’t work, so not sure if it would help me to manually calibrate.
It also seems that gyro and accelerometers also need to be reasonably calibrated for tilt compensation to work.

Can’t say I know much more about calibration than my earlier post. Different sequences seem to work. The document says to set it 180 degrees apart for each of the 3 axes. That has worked for me. Also, deep wide, twisty figure 8’s work.

I am using serial mode.

Yes, turning off cal does not seem to work. I’ve seen my cal go bad (2->0) and have to re-calibrate. Does not happen often though. I assume the device has some sort of non-volatile memory in it.

FWIW, I’ve implemented a piecewise linear fit calibration on top of the low level cal (twisty). I have the software take data at 8 angles in the great circle and fit a line between the data points. I’ve found that that is needed to get the CMPS14 accurate, and also this makes my 2 CMPS14’s to agree. I have 2 CMPS14’s, one on my trolling motor and the other on the boat hull.

Wish they would come out with a CMPS15 with the calibration mess straightened out.

Hi Randy,

do you have some code available? Sounds quite interesting what you are doing.