Calibrating CMPS14

sailgene

Member
Hi all. I've had some limited success in getting my CMPS14 to return various headings, mostly using Serial communication. I've tried both 8 and 16 bit resolutions and can get readings of 0 - 255 for 8-bit and 0 - 3650 for 16-bit. The problem is the headings are far from accurate (20 to 40 degrees off).

The data sheet (attached) discusses calibration (I2C mode) but I do not understand the documentation. Page 6 reads: "To achieve background calibration the user just needs to turn the functionality on and perform the required simple movements." I've tried sending the "setup bytes" 0x98, etc., with 20 millisecond pauses. But I don't understand the rest of the documentation stating, "remembering to pick up the response byte OK (0x55) after each byte". "You can then pass the setup byte to the command register, it takes the form: "

Bit 7Bit 6Bit 5Bit 4Bit 3Bit 2Bit 1Bit 0
Calibration Config
1​
xxPeriodicxGyroAccelMag
Auto Save

I'm embarrassed to admit that this goes over my head by several feet. Has anyone dealt with calibrating this particular compass module? If so, do you have any working code that I could use? Thanks so much. Meanwhile, I will keep plugging away at it.
 

Attachments

Flenser

Senior Member
But I don't understand the rest of the documentation stating, "remembering to pick up the response byte OK (0x55) after each byte"
From the robot electronics pdf https://www.robot-electronics.co.uk/files/cmps14.pdf
Their CMPS14 module supports communication by either I2C or serial with I2C being the default if the mode pin is left open.
In the section "I2C Mode" it gives the instruction for a 20ms delay after each byte"
In the section "Serial Mode" it gives the instruction "to pick up the response byte OK (0x55) after each byte"
So if the mode pin is left open then you are using I2C and you ignore the instrucions about the OK (0x55) response byte.
 

Flenser

Senior Member
calibrating this particular compass module
The cmps14.pdf document also says in the section "Calibration of the CMPS14":
"The CMPS14 is shipped with a static factory calibration, but the module is able to automatically update its calibration with algorithms running in the background if desired. To achieve background calibration the user just needs to turn the functionality on and perform the required simple movements."

My understanding is that to turn the automatic calibration on you need to send the series of command bytes that Hippy posted in your other thread here https://picaxeforum.co.uk/threads/picaxe-vs-arduino-support.32757/post-342640

These instructions are given for the movements you need to take for calibration in the section "Changing the calibration configuration":
Gyro – calibrated by the CMPS14 being in a stationary state.
Accelerometer – calibrated by tilting the module to roughly 45 and 90 degrees on one axis. (As there are three axes I would interpret this as meaning to tilt the module to roughly 45 and 90 degrees in line with each axis, doing this one axis at a time for each of the three axes.)
Magnetometer – a few random movements easily calibrates the CMPS14

You can check the calibration state of the three sensors by reading byte 0x1E which has 2 bits for the calibration state of each sensor from 0 for un-calibrated through to 3 for fully calibrated.
The format of this calibration byte is given in the section "Changing the calibration configuration" which also has a warning that there is a bug in the value reported for the gyro calibration.
If you turn on the automatic calibration and then code a loop that continually reads byte 0x1E and writes it to the PE terminal you can watch how the calibration alters as you perform the calibration actions.

Disclaimer: This is all my interpretation of the cmps14.pdf document. I've never used this module and I don't own one to test that what I've described actually works.
 

hippy

Ex-Staff (retired)
Disclaimer: This is all my interpretation of the cmps14.pdf document. I've never used this module and I don't own one to test that what I've described actually works.
I am in the same position but your analysis is the same as mine.

It would seem very few PICAXE users have used the CMPS14 and none of them have ever calibrated the module and, if they have, haven't posted the code to do that. Unless someone who has comes along it will be a matter of figuring it out.

We can all read the datasheet, try to figure out what it means, how to do it on a PICAXE, but we will have to rely on 'sailgene' to try it and provide feedback, details of what results are obtained.

@sailgene : Please can you let us know the PICAXE chip you have and post the code you are using to report the directional results you are reading.

From https://picaxeforum.co.uk/threads/compass-interface.31617/#post-328135 my suggested serial code for interfacing to a CMPS14 is as follows ...
Code:
#Picaxe 08M2
#Terminal 4800

Symbol TX_PIN    = C.?
Symbol RX_PIN    = C.?

Symbol direction = w1 ; b3:b2
Symbol dir.lsb   = b2
Symbol dir.msb   = b3 

High TX_PIN
Pause 2000
Do
  SetFreq M32
  Pause 100
  SerOut TX_PIN, T9600_32, ( $13 )
  SerIn RX_PIN, T9600_32, dir.msb, dir.lsb
  SetFreq MDEFAULT
  Pause 100
  SerTxd( "Direction=", #direction, CR, LF )
  Pause 1000
Loop
I moved the 'High TX_PIN' to before the DO loop and added a start-up pause of two seconds but otherwise it's as per original.

I am guessing the code being used is based on that. If not it would be helpful if 'sailgene' could try the same with whatever they have, reporting what results they get as the module is turned clockwise a few times for N, E, S and W readings.

I would guess turning on auto-calibration for direction as I presumed it might be for I2C will be as follows, placed immediately before the DO loop, after 'High TX_PIN' -
Code:
SetFreq M32
Pause 100
SerOut TX_PIN, T9600_32, ( $98 ) :  SerIn RX_PIN, T9600_32, b0 : Pause 200
SerOut TX_PIN, T9600_32, ( $95 ) :  SerIn RX_PIN, T9600_32, b0 : Pause 200
SerOut TX_PIN, T9600_32, ( $99 ) :  SerIn RX_PIN, T9600_32, b0 : Pause 200
SerOut TX_PIN, T9600_32, ( $91 )
SetFreq MDEFAULT
Pause 100
It's not clear if the 0x55 "OK" comes back as soon as the command is received or when it completes, but we won't continue unless something comes back and we 'Pause 200' @ 32MHz, which is 20ms+ at 4MHz anyway so it should be ready for the next command.

To check on calibration status I would guess, immediately before or after 'SerTxd( "Direction=" ... )' -
Code:
SetFreq M32
Pause 100
SerOut TX_PIN, T9600_32, ( $24 )
SerIn RX_PIN, T9600_32, b0
SetFreq MDEFAULT
Pause 100
SerTxd( "Calibration = ", #b0, " - " )
b0 = b0 & 3
Select Case b0
  Case 0 : SerTxd( "Uncalibrated", CR, LF )
  Case 3 : SerTxd( "Calibrated", CR, LF )
  Else   : SerTxd( "Partially calibrated", CR, LF )
End Select
But I am not sure that will ever complete if we aren't doing full calibration, only auto-calibrating direction.
 

sailgene

Member
Hi Hippy. For whatever it's worth, and with a few modifications to your code, I was able to receive a response: "Calibration = 0". So the good news is I can still talk with the module but the bad news is I'm still perplexed on coding to turn on the calibration function.... Feel free to move on the bigger and better questions for others and I'll keep plugging away.

Code:
SetFreq M8
INIT:
SERTXD ("BEGIN", CR, LF)
PAUSE 1000
HIGH C.1
Pause 100
SerOut C.1, T9600_8, ($24)
SerIn [16000], C.2, T9600_8, b0
Pause 100
SerTxd( "Calibration = ", #B0, " - " )
b0 = b0 & 3
Select Case b0
  Case 0 : SerTxd( "Uncalibrated", CR, LF )
  Case 3 : SerTxd( "Calibrated", CR, LF )
  Else   : SerTxd( "Partially calibrated", CR, LF )
End Select
 

hippy

Ex-Staff (retired)
For whatever it's worth, and with a few modifications to your code, I was able to receive a response: "Calibration = 0".
Did it not work without those modifications ?

In-lining pin numbers is fair enough; it's the added timeout to the SERIN which most interests me. If it doesn't work without that it may simply be reporting the initial value of 'b0' which would be zero. And if it's not working that suggests some issue with what's being sent or lack of data received. That could be an issue if we need to do a full calibration of the module.

I would suggest trying this code, record the values when pointed at N, E, S and W -
Code:
#Terminal 9600

Symbol TX_PIN     = C.1
Symbol RX_PIN     = C.2

Symbol FREQ       = M8
Symbol BAUD       = T9600_8

Symbol reserveW0  = w0 ; b1:b0
Symbol direction  = w1 ; b3:b2
Symbol dir.lsb    = b2
Symbol dir.msb    = b3

Symbol calibrated = b4

#Macro InitWithResponse( stp, cmd )
  SerOut TX_PIN, BAUD, ( cmd ) : SerIn RX_PIN, BAUD, b0 : Pause 200
  If b0 <> $55 Then
    SerTxd( "Failed to get OK in step ", #stp, CR, LF )
    End
  End If
#EndMacro

Init:
  SetFreq FREQ
  High TX_PIN
  Pause 4000

#rem
  SerTxd( "Calibrating", CR, LF )
  InitWithResponse( 1 , $98 )
  InitWithResponse( 2 , $95 )
  InitWithResponse( 3 , $99 )
  SerOut TX_PIN, BAUD, ( $91 )
#endrem

MainLoop:
  SerTxd( "Started", CR, LF )
  Do
    ; Read calibration status
    SerOut TX_PIN, BAUD, ( $24 )
    SerIn  RX_PIN, BAUD, calibrated
    ; Read direction
    SerOut TX_PIN, BAUD, ( $13 )
    SerIn  RX_PIN, BAUD, dir.msb, dir.lsb
    ; Report results
    SerTxd( "Calibrated = ", #calibrated, ", Direction=", #direction, CR, LF )
    Pause 2000
  Loop
After you have got that working, remove or comment-out the #REM and #ENDREM, re-run the test, and after a few turns of the module, again record N, S, E and W readings.
 

Flenser

Senior Member
And if it's not working
Hippy, there does not seem to be anything from the most recent code in posts #5 & #6 that we can use to determine if the code is actually doing anything.

If sailgene can go back to his original code from post #1 where he was getting changing headings reported then we have code that does seem to be successfully reading the cmps14 registers. If that original code is posted to the forum then 1) we can see what worked and 2) we can suggest modifications to that code to test things like whether 0x55 response byte is always returned.
 

sailgene

Member
Did it not work without those modifications ?

In-lining pin numbers is fair enough; it's the added timeout to the SERIN which most interests me. If it doesn't work without that it may simply be reporting the initial value of 'b0' which would be zero. And if it's not working that suggests some issue with what's being sent or lack of data received. That could be an issue if we need to do a full calibration of the module.

I would suggest trying this code, record the values when pointed at N, E, S and W -
Code:
#Terminal 9600

Symbol TX_PIN     = C.1
Symbol RX_PIN     = C.2

Symbol FREQ       = M8
Symbol BAUD       = T9600_8

Symbol reserveW0  = w0 ; b1:b0
Symbol direction  = w1 ; b3:b2
Symbol dir.lsb    = b2
Symbol dir.msb    = b3

Symbol calibrated = b4

#Macro InitWithResponse( stp, cmd )
  SerOut TX_PIN, BAUD, ( cmd ) : SerIn RX_PIN, BAUD, b0 : Pause 200
  If b0 <> $55 Then
    SerTxd( "Failed to get OK in step ", #stp, CR, LF )
    End
  End If
#EndMacro

Init:
  SetFreq FREQ
  High TX_PIN
  Pause 4000

#rem
  SerTxd( "Calibrating", CR, LF )
  InitWithResponse( 1 , $98 )
  InitWithResponse( 2 , $95 )
  InitWithResponse( 3 , $99 )
  SerOut TX_PIN, BAUD, ( $91 )
#endrem

MainLoop:
  SerTxd( "Started", CR, LF )
  Do
    ; Read calibration status
    SerOut TX_PIN, BAUD, ( $24 )
    SerIn  RX_PIN, BAUD, calibrated
    ; Read direction
    SerOut TX_PIN, BAUD, ( $13 )
    SerIn  RX_PIN, BAUD, dir.msb, dir.lsb
    ; Report results
    SerTxd( "Calibrated = ", #calibrated, ", Direction=", #direction, CR, LF )
    Pause 2000
  Loop
After you have got that working, remove or comment-out the #REM and #ENDREM, re-run the test, and after a few turns of the module, again record N, S, E and W readings.
So the above code returned calibration "status" numbers running from 142 down to 12 as I rotated the module. The headings that came up appeared to be typical (in the ballpark but ranging from 10 to 30 degrees off as before). I then removed the #REM and #ENDREM lines to include that portion of code. In both cases, the same results. Weird calibration numbers (mostly the "142") versus a 0 or 3. I also re-ran the calibration status code you suggested and again, it returned a "0" - Uncalibrated. I'll attach my original "working" code to the following post.
 

sailgene

Member
Hippy, there does not seem to be anything from the most recent code in posts #5 & #6 that we can use to determine if the code is actually doing anything.

If sailgene can go back to his original code from post #1 where he was getting changing headings reported then we have code that does seem to be successfully reading the cmps14 registers. If that original code is posted to the forum then 1) we can see what worked and 2) we can suggest modifications to that code to test things like whether 0x55 response byte is always returned.
Here is the original code that worked, but with poor accuracy:

Code:
#Picaxe 08M2
#Terminal 4800
INIT:
PAUSE 2000
SETFREQ M8
SYMBOL DIR.LSB = B2
SYMBOL DIR.MSB = B3
Symbol direction = w1
SERTXD ("BEGIN", CR, LF)
PAUSE 2000
Do
    HIGH C.1
    PAUSE 100
  SerOut C.1, T9600_8, ($13)        'ASK CMPS14 FOR 16 BIT BEARING IN REGISTER 0X13
  SerIn [16000], C.2, T9600_8, DIR.MSB, DIR.LSB 'GIVE TIME FOR CMPS14 TO RESPOND AND PLACE 2 BIT RESPONSE IN VARIABLES B3 AND B2
  direction = direction / 10
SERTXD ( " COURSE: ", #direction, CR, LF)
PAUSE 2000
Loop
 

hippy

Ex-Staff (retired)
So the above code returned calibration "status" numbers running from 142 down to 12 as I rotated the module.
The numbers seem legitimate though I can't explain what you are seeing -
Code:
                      Bit Fields
Value    Binary     All Gyr Acc Mag

 142    10001110    10  00  11  10
  12    00001100    00  00  11  00
When you say the numbers ran from 142 down to 12; is that the order they appeared in or did they run from 12 up to 142 ? What were the other numbers ? I would be expecting to see a 77 in there -
Code:
                    All Gyr Acc Mag
  77    01001101    01  00  11  01
I then removed the #REM and #ENDREM lines to include that portion of code. In both cases, the same results. Weird calibration numbers (mostly the "142")
That's good news because first it means the calibration commands are being accepted, are returning 0x55, and, once accepted, the 142 indicates that partial calibration is being achieved.

What were the actual numbers and did they go down as well as up. From what you have reported I would have expected to see only increasing values 12, 77, 142, 207 -
Code:
                    All Gyr Acc Mag
 207    11001111    11  00  11  11
But maybe the 'all' calibration bits never reach '11', even if the 'mag' is calibrated'.

To make it easier to understand what we have I suggest changing the results report to this -
Code:
b0 = calibrated
SerTxd( "Calibrated = ", #calibrated, " " )
SerTxd( #bit7, #bit6, " ", #bit5, #bit4, " " )
SerTxd( #bit3, #bit2, " ", #Bit1, #bit0, " " )
SerTxd( "Direction=", #direction, CR, LF )


The headings that came up appeared to be typical (in the ballpark but ranging from 10 to 30 degrees off as before).
What were the actual numbers you were seeing ? How different were the readings on the second and subsequent rotations from the first ? What were those readings ?

Diagnosing what's going on from a distance is much harder than looking over someone's shoulders, doing it oneself. One really needs to be able to see exactly what one would see oneself so the more detail and actual values you can provide the better.

Do you have a second CMPS14 you can test with, compare against ? It may well be this is just a misbehaving module.

Did you make any attempts to calibrate the module yourself ?
 

hippy

Ex-Staff (retired)
Hippy, there does not seem to be anything from the most recent code in posts #5 & #6 that we can use to determine if the code is actually doing anything.
I was working on the principle that if the numbers are as one might expect, in the right ball park, then the code and module are working, even if some results are not how they might be expected to be.

I can't see anything wrong with the original code as posted in #10 other than there is a timeout on SERIN which could have resulted in previous readings being re-reported if the module did not respond, and dividing the direction by 10 loses some details in the raw value which may or may not be important.

My code in #6 is pretty much the same, is what I would use if I have a CMPS14 and was trying to figure out why I wasn't getting what would be expected.

Assuming the #6 code was run 'as is' with the #REM-ENDREM removed, the results reported would indicate to me that things are working, the module is wired correctly, is responding as expected, any issue being in what is getting returned as calibrated status and direction; "works but isn't correct". The challenge then in figuring out why ?
 

sailgene

Member
The numbers seem legitimate though I can't explain what you are seeing -
Code:
                      Bit Fields
Value    Binary     All Gyr Acc Mag

142    10001110    10  00  11  10
  12    00001100    00  00  11  00
When you say the numbers ran from 142 down to 12; is that the order they appeared in or did they run from 12 up to 142 ? What were the other numbers ? I would be expecting to see a 77 in there -
Code:
                    All Gyr Acc Mag
  77    01001101    01  00  11  01

That's good news because first it means the calibration commands are being accepted, are returning 0x55, and, once accepted, the 142 indicates that partial calibration is being achieved.

What were the actual numbers and did they go down as well as up. From what you have reported I would have expected to see only increasing values 12, 77, 142, 207 -
Code:
                    All Gyr Acc Mag
207    11001111    11  00  11  11
But maybe the 'all' calibration bits never reach '11', even if the 'mag' is calibrated'.

To make it easier to understand what we have I suggest changing the results report to this -
Code:
b0 = calibrated
SerTxd( "Calibrated = ", #calibrated, " " )
SerTxd( #bit7, #bit6, " ", #bit5, #bit4, " " )
SerTxd( #bit3, #bit2, " ", #Bit1, #bit0, " " )
SerTxd( "Direction=", #direction, CR, LF )


What were the actual numbers you were seeing ? How different were the readings on the second and subsequent rotations from the first ? What were those readings ?

Diagnosing what's going on from a distance is much harder than looking over someone's shoulders, doing it oneself. One really needs to be able to see exactly what one would see oneself so the more detail and actual values you can provide the better.

Do you have a second CMPS4 you can test with, compare against ? It may well be this is just a misbehaving module.

Did you make any attempts to calibrate the module yourself ?
In answer to your question about what numbers I saw (and I totally agree this is almost impossible without looking over my proverbial shoulder), here is a copy of the sertext output. Of note, the module was 1st pointed at magnetic north, then pivoted to east, then to south, then west and then back to north (I've added the direction to a line where the pivot occured). As show, the courses are 16-bit and would need to be divided by 10 to get an actual heading:

Calibrating

Started

Calibrated = 142, Direction=2987 NORTH

Calibrated = 142, Direction=2989

Calibrated = 142, Direction=2994

Calibrated = 142, Direction=3121

Calibrated = 142, Direction=3345

Calibrated = 142, Direction=22

Calibrated = 142, Direction=378

Calibrated = 142, Direction=812

Calibrated = 142, Direction=1105 EAST

Calibrated = 142, Direction=1214

Calibrated = 142, Direction=1214

Calibrated = 142, Direction=1202

Calibrated = 142, Direction=1475

Calibrated = 78, Direction=1704

Calibrated = 78, Direction=1820 SOUTH

Calibrated = 78, Direction=2004

Calibrated = 78, Direction=2073

Calibrated = 14, Direction=2074

Calibrated = 14, Direction=2075

Calibrated = 14, Direction=2076

Calibrated = 14, Direction=2689 WEST

Calibrated = 14, Direction=2696

Calibrated = 14, Direction=2696

Calibrated = 14, Direction=2697

Calibrated = 78, Direction=2552

Calibrated = 78, Direction=2556

Calibrated = 78, Direction=2556

Calibrated = 78, Direction=2496

Calibrated = 78, Direction=2496

Calibrated = 78, Direction=2616

Calibrated = 142, Direction=2957

Calibrated = 142, Direction=3207 NORTH AGAIN

Calibrated = 142, Direction=3164

Calibrated = 142, Direction=3156

Calibrated = 142, Direction=3158
 

sailgene

Member
In answer to your question about what numbers I saw (and I totally agree this is almost impossible without looking over my proverbial shoulder), here is a copy of the sertext output. Of note, the module was 1st pointed at magnetic north, then pivoted to east, then to south, then west and then back to north (I've added the direction to a line where the pivot occured). As show, the courses are 16-bit and would need to be divided by 10 to get an actual heading:

Calibrating

Started

Calibrated = 142, Direction=2987 NORTH

Calibrated = 142, Direction=2989

Calibrated = 142, Direction=2994

Calibrated = 142, Direction=3121

Calibrated = 142, Direction=3345

Calibrated = 142, Direction=22

Calibrated = 142, Direction=378

Calibrated = 142, Direction=812

Calibrated = 142, Direction=1105 EAST

Calibrated = 142, Direction=1214

Calibrated = 142, Direction=1214

Calibrated = 142, Direction=1202

Calibrated = 142, Direction=1475

Calibrated = 78, Direction=1704

Calibrated = 78, Direction=1820 SOUTH

Calibrated = 78, Direction=2004

Calibrated = 78, Direction=2073

Calibrated = 14, Direction=2074

Calibrated = 14, Direction=2075

Calibrated = 14, Direction=2076

Calibrated = 14, Direction=2689 WEST

Calibrated = 14, Direction=2696

Calibrated = 14, Direction=2696

Calibrated = 14, Direction=2697

Calibrated = 78, Direction=2552

Calibrated = 78, Direction=2556

Calibrated = 78, Direction=2556

Calibrated = 78, Direction=2496

Calibrated = 78, Direction=2496

Calibrated = 78, Direction=2616

Calibrated = 142, Direction=2957

Calibrated = 142, Direction=3207 NORTH AGAIN

Calibrated = 142, Direction=3164

Calibrated = 142, Direction=3156

Calibrated = 142, Direction=3158
Hippy, I then tried using your new code suggestion (sertexting bits 7 through 0) and here is the output (I stopped and started with each new direction):

Calibrating

Started

Calibrated = 142 10 00 11 10 Direction=3064 NORTH

Calibrated = 142 10 00 11 10 Direction=3061

Calibrated = 142 10 00 11 10 Direction=3064

Started

Calibrated = 142 10 00 11 10 Direction=1195 EAST

Calibrated = 142 10 00 11 10 Direction=1197

Calibrated = 142 10 00 11 10 Direction=1204

Started

Calibrated = 14 00 00 11 10 Direction=1804 SOUTH

Calibrated = 14 00 00 11 10 Direction=1804

Calibrated = 14 00 00 11 10 Direction=1804

Started

Calibrated = 78 01 00 11 10 Direction=2401 WEST

Calibrated = 78 01 00 11 10 Direction=2401

Calibrated = 14 00 00 11 10 Direction=2401
 

hippy

Ex-Staff (retired)
It is very odd.. The first set of numbers suggests it thinks its north is somewhere around actual north north east. The second set seems to show only partial calibration of the magnetometer being achieved. That partial calibration (two lsb) seems consistent but shows the 'all' bits (two msb) aren't purely reflective of the other bits, 142 '10 00 11 10' dropping to 14 '00 00 11 10' at the end.

At this point I would test with another CMPS14 to try and determine if it's a module issue or a systemic issue.
 

Flenser

Senior Member
saigene, so the Acc & Mag figures are reporting a stable calibration level but the System calibration figure is varying a lot. The system calibration figure is not discussed in the cmps14.pdf manual so I don't have anything to suggest.

There is a lot of discussion about using the CMP14 or BMO080/85 to control the direction of tractors in this thread on the AgOpenGPS forum but some people report no problems with the heading while others do.

Some things that were reported as affecting the magnetometer which you can check:
- "It can operate in this mode with a 3v3 input but the magnetic heading might be significantly offset from headings produced with higher voltage inputs." Are you running your module from 5v?
- "need to take care of placement to avoid disturbances, gets true north heading" What metal is there near your CMPS14? I read another post that the direction was effected by an M4 bolt 8cm from the CPMS14 module. Are your CMPS14 and/or the PICAXE connected or very close to a breadboard? (which has metal in it)
- It was also reported that the magnetometer can be effected by electrical currents and one person posted this experience using it on his tractor "I once had my lights pull the heading way off course". I don't imagine that your setup is close to large currents but I include this FYI for completeness.
- This comment "I never succed to have magnetometer to an other status than “Unreliable” despide repeating the calibration procedure" did get this reply "I got medium and high. It did require a bit of lively driving around!" so you could try going for a walk carrying the CMPS14 to see whether runing the autocalibration for a longer period of time improves the direction readings.
 

sailgene

Member
saigene, so the Acc & Mag figures are reporting a stable calibration level but the System calibration figure is varying a lot. The system calibration figure is not discussed in the cmps14.pdf manual so I don't have anything to suggest.

There is a lot of discussion about using the CMP14 or BMO080/85 to control the direction of tractors in this thread on the AgOpenGPS forum but some people report no problems with the heading while others do.

Some things that were reported as affecting the magnetometer which you can check:
- "It can operate in this mode with a 3v3 input but the magnetic heading might be significantly offset from headings produced with higher voltage inputs." Are you running your module from 5v?
- "need to take care of placement to avoid disturbances, gets true north heading" What metal is there near your CMPS14? I read another post that the direction was effected by an M4 bolt 8cm from the CPMS14 module. Are your CMPS14 and/or the PICAXE connected or very close to a breadboard? (which has metal in it)
- It was also reported that the magnetometer can be effected by electrical currents and one person posted this experience using it on his tractor "I once had my lights pull the heading way off course". I don't imagine that your setup is close to large currents but I include this FYI for completeness.
- This comment "I never succed to have magnetometer to an other status than “Unreliable” despide repeating the calibration procedure" did get this reply "I got medium and high. It did require a bit of lively driving around!" so you could try going for a walk carrying the CMPS14 to see whether runing the autocalibration for a longer period of time improves the direction readings.
I HAVE been running the module off of 5v and so experimenting with a lesser voltage might not be a bad idea. The module is close to my monitor which I understand can have some magnetism - but my standard compass does not seem to be affected. I am using a breadboard and the module is about 6 inches (15 cm for you guys) away. Still unsure how to turn on the calibration function - for all of the suggested coding, unable to get the "3" response indicating it is calibrated.

One other point: I was told by a sales person from Devantech that, "Serial does not have a command register". I think he was implying that I needed to use I2C communication for the purpose of Calibration. But the "Get Calibration State" command is under the Serial commands section.

The confusion continues. Wish I had a bigger brain but on the other hand, where would be the fun in that? I will experiment with lowering the voltage and moving the module farther away from the monitor. I anything improves, I will report.
 

Flenser

Senior Member
I HAVE been running the module off of 5v and so experimenting with a lesser voltage might not be a bad idea.
I was not clear enough. You should continue to run you module of 5v. The CMPS14 module has a 3.3v regulator on it and if you try to run the module of 3.3v then the regulator will not be able to provide 3.3V, the operating voltage of the module will be lower than 3.3v, and the magnetometer is reported to not able to work well when the voltage is lower than 3.3v.

The module is close to my monitor which I understand can have some magnetism - but my standard compass does not seem to be affected.
The magentometer is very sensitive, much more sensitive than a standard compass. A powerful way to debug problems is to design your tests to isolate one possible cause at a time. so as a first test I suggest moving the PICAXE+CMPS14 outside, well away from any electronic equipment like monitors, computers, fridges, etc to see how big an effect it has, if any. If there is still a problem getting a good direction then a second test would be to try connecting the CMPS14 to the breadboard with longer jumper wires and moving it away from any electronic equipment.

Still unsure how to turn on the calibration function
Enabling the automatic calibration was what we intended to do using the code to send the sequence of bytes 0x98, 0x95, 0x99 & 0x91 that we got from the manual.
The directions being reported shows that the total system calibration value appears to be changing so, as I understand the manual, the automatic calibration appears to be enabled.

for all of the suggested coding, unable to get the "3" response indicating it is calibrated
The only thing I'm certain about from the manual is that 0 is uncalibrated. The manual does not go into detail about the other values and I do not understand whether these values always have to end up at 3 or if in some circumstances they can max out at 2, or even 1.
 

hippy

Ex-Staff (retired)
One other point: I was told by a sales person from Devantech that, "Serial does not have a command register". I think he was implying that I needed to use I2C communication for the purpose of Calibration. But the "Get Calibration State" command is under the Serial commands section.
The first byte sent using SERTXD is effectively taken as what would be written to the command register, at least indicates the action to be performed.

This works for reading the 8 and 16-bit direction, turning on auto-calibration. That is described on page 7 of the datasheet. We are sending the bytes as instructed, getting the 0x55 responses as expected, and reading a calibration value which reflects calibration status. Everything appears to be correct in how we are using the module over serial, it's just that the results aren't what we would expect or desire..

The module is close to my monitor which I understand can have some magnetism
One quick test which hopefully won't be too inconvenient is to move your hardware to the other side of the monitor, and see what the effects are upon heading. We are currently seeing the module treating north north east as its north; if it starts showing north north west as its north that would tend towards indicating the monitor is affecting things.

There is a lot of discussion about using the CMP14 or BMO080/85 to control the direction of tractors in this thread on the AgOpenGPS forum but some people report no problems with the heading while others do.
I found similar threads of tractor users saying the same things, some reporting perfect results, others not so good.

I did find this - https://xdevs.com/doc/CEVA/BNO080-BNO085-Sesnor-Calibration-Procedure.pdf - which indirectly provides some useful details - the 'sesnor' typo in the name is theirs so don't correct that -

"The magnetometer calibration process will calibrate for the unique magnetic field affecting the environment in which the calibration process takes place. This includes components that affect the magnetic field in the headset itself (soft iron effects) like batteries, and objects that affect the magnetic field around the user (hard iron effects) like metallic furniture or speakers".

"Ideally the calibration process would be performed several feet away from high magnetic interferers like tables with magnetic components, desktop PC towers, monitors, etc".

"Enable Magnetic Field output (the magnetometer requires 50Hz report rate to get proper calibration)"

"Perform the magnetometer calibration motions. Rotate the device ~180° and back to the beginning position in each axis (roll, pitch, yaw) as shown in Figure 1. The speed of the rotation should be approximately ~2 seconds per axis but it does not need to be perfect. Continue rotations until the Magnetic Field Status bit reads 2 or 3 (medium or high accuracy)".

So, beyond confirming it can be affected by small magnetic influences, there is the issue of the calibration process perhaps not being followed, that we shouldn't be turning it full circle but perhaps clockwise from north to south then anti-clockwise south to north, and perhaps also needing to tilt and roll as well.

We also don't have that "50Hz report rate" as far as I can see. There's no configuration to set that so I guess it means reading it 20 times a second rather than once a second as we are doing. I will provide some code which can do that in a subsequent post.

But the good news is that getting %10 (2) in the magnetometer calibration status, "medium accuracy", is pretty good if we aren't calibrating correctly. That we aren't could then explain why things are going out of kilter. Or maybe we need to turn auto-calibration off once initially done ?
 

hippy

Ex-Staff (retired)
This is the modification I would make to the claibration procedure -
Code:
Init:
  SetFreq FREQ
  High TX_PIN
  Pause 4000

Calibration:
  SerTxd( "Calibrate now", CR, LF )
  InitWithResponse( 1 , $98 )
  InitWithResponse( 2 , $95 )
  InitWithResponse( 3 , $99 )
  SerOut TX_PIN, BAUD, ( $91 )
  For b0 = 1 To 30   ; Allow 30 seconds in which to calibrate
    For b1 = 1 To 20 ; 20 times per second
      Pause 39       ; Approx 19.5ms delay at 8MHz
      ; Read calibration status
      SerOut TX_PIN, BAUD, ( $24 )
      SerIn  RX_PIN, BAUD, calibrated
    Next
  Next
#Rem
  InitWithResponse( 4 , $98 )
  InitWithResponse( 5 , $95 )
  InitWithResponse( 6 , $99 )
  SerOut TX_PIN, BAUD, ( $80 )
#EndRem

MainLoop:
  SerTxd( "Started", CR, LF )
Start the code running then you have 30 seconds in which to provide the calibration movements.

Over a period of two seconds in each case, turn clockwise north to south then anti-clockwise south to north, tilt it forward and back to flat, tilt it up and back to flat, tilt it left and back to flat, right then back to flat, then wait for "Started".

Check the reported directions and they should hopefully be more accurate, or at least more repeatable. The calibrated report should hopefully show '?? ?? ?? 11'.

If not then try again with the #REM and #ENDREM removed. This turns off auto-calibration once calibrated so subsequent movements shouldn't affect calibration and what it determines and reports.
 

Flenser

Senior Member
Hippy,

Some more info for you about the CMPS14.

From reading the AgOpenGPS thread I have this understanding:
  • Hillcrest Labs make the BNO055, BNO080 & BNO085 which has an internal ARM processor that provides its responses in Hillcrest’s Sensor Hub Transport SHTP protocol.
  • The CMPS14 is a separate Devantech product.

This next paragraph is a post from the AgOpenGBS thread that describes the CMPS14:

I had a discussion with Robot-Electronics support (manufacturer of CMPS14) about how CMPS works & use BNO080.
They answered me, so know we had a clear idea of how CMPS14 works and differences with BNO08x (see emails at the end of the post).
As @Alan.Webb and I were assuming, BNO080 of CMPS14 is configured to output Rotation Vector Report and the PIC16F18325 microcontroler of CMPS14 just convert quaternion into Eular Angle and makes them available to the host via a standard I2C bus (so you don’t have to deal with Hillcrest Lab SHTP protocol trought I2C).

Adafruit sells the BNO085 product (that replaced the BNO080) and these next two paragraphs are from this Adafruit page https://www.adafruit.com/product/4754

Please note, the BNO085 is the 'upgrade fix' to BNO080 - it is completely back-compatible with the BNO-080 and, in addition, fixes an SPI timeout bug that made SPI difficult to use. The '085 is the same price and you can use any existing '080 code so we are only going to carry the '085!

The BNO085 by the motion sensing experts at CEVA Hillcrest Laboratories takes the familiar 3-axis accelerometers, gyroscopes, and magnetometers and packages then alongside an Arm Cortex M0 processor running CEVA's SH-2 firmware that handles the work of reading the sensors, fusing the measurements into data that you can use directly, and packaging that data and delivering it to you. If the name and description of the BNO085 sounds strikingly similar to those of the BNO055 by Bosch Sensortec, there is a good reason why: they're the same thing, but also they're not. Thanks to a unique agreement between Bosch and CEGA, the BNO085 uses the same hardware as the BNO055 but very different firmware running on it.

I've found these three documents that apply to the BNO080/85 product:
  • BNO080_Datasheet_v1.3.pdf. I didn't look further for a BNO085 version as we need to use the CMPS14.pdf doco.
  • SH-2-Reference-Manual-v1.2.pdf. This describes the protocol for communicating with the BNO080/85 chip. It is not the same as the protocol described in CMPS14.pdf for communicating with the CMPS14 module.
  • Sensor-Calibration-Procedure-v1.1.pdf. This is the same document you linked to that describes a more detailed calibration procedure for the BNO080/85 than is given in CMPS14.pdf. Autocalibration is a BNO080/85 feature so if we have enabled autocalibration then I assume that the procedure given in this document can be used for the CMPS14.
 

hippy

Ex-Staff (retired)
I've found these three documents that apply to the BNO080/85 product:
Thanks, and not faulting that, considering my PDF is 'Hillcrest', but I am no longer sure how much anything 'Hillcrest' applies to what we have here. They describe the SH-2 protocols but that is very different to what the CMPS14 uses and what we have working.

I'm guessing from the post you found and its details, the CMPS14 module is BNO080 to ARM then SH2 to a PIC then UART/I2C to the PICAXE or whatever else. That makes it all a bit convoluted.

And also an acknowledgement I'd got 'CMPS4' rather than 'CMPS14' into my head so have updated previous uses of that in posts to avoid confusion, and sorry if there was any caused.
 

Flenser

Senior Member
I am no longer sure how much anything 'Hillcrest' applies to what we have here. They describe the SH-2 protocols but that is very different to what the CMPS14 uses and what we have working.
I agree. My intention was to alert anyone reading this post that what we discover online about the base BNO080 chip may not be able to be applied directly when using the CMPS14 module.

I'm guessing from the post you found and its details, the CMPS14 module is BNO080 to ARM then SH2 to a PIC then UART/I2C to the PICAXE or whatever else. That makes it all a bit convoluted.
Hippy, think of it this way:
The BNO080 provides the raw output of the MEMS 3-axis accelerometers, gyros and magnetometers. I imagine that converting these raw measurements into something that is easy for humans to understand might require some extra education and/or training so Hillcrest included an on-chip ARM processor and got their engineers to write the software that does this conversion and delivers it to an external computer via the SH2 protocol. There is a _lot_ of stuff that you can get via SH2 so Devantech identified a market that would be interested in a simpler interface and created their CMPSnn modules with a PIC microcontroller programmed to fetch a subset of the data available from the BNO080 and output it using the simpler interface documented in CMPS14.pdf.

and I draw the following analogy with the PICAXE chips (where I've assumed on the basis of no evidence at all that the PICAXE firmware is written in C):
PIC chips run a binary machine code. This is a hard for humans to use to program the chips so Microchip provide a C compiler to convert programs written in C to machine code. The C language is a bit low level to use for some markets, like teaching high school students about programming and using microcontrollers for the first time, so Rev-Ed wrote the PICAXE firmware which provdides PICAXE BASIC as a much simpler interface to use for programming PIC microcontrollers.[/QUOTE]
 
Last edited:
Top