CMPS11 Calibration

Hi Guys,

I’ve been working a project, which involves using a CMPS11 digital compass. I’m an amateur at programming, so please excuse me for my silly questions.

I’m building a robot, which need to know its heading accurately. I chose I2C communication as the update rate of the signals has to be at least 15hz.

I used this program to read out the orientation:

http://www.robot-electronics.co.uk/htm/cmps11i2c.htm

As far as I know, the “angle full” would give me the heading. For some reasons, It’s not accurate at all, actually, pretty useless. I want to calibrate the compass, but I’m stuck with it. I tried to send the commands in, but it doesn’t seem to work. Can someone help me out and tell me what’s wrong?

#include <Wire.h>

#define ADDRESS 0x60

void setup(){
  Wire.begin();
  Serial.begin(9600);
  }

void loop(){
}

void calibrate(){

  Wire.beginTransmission(ADDRESS);
  Wire.write(0xF0);
  delay(25);

  Wire.beginTransmission(ADDRESS);
  Wire.write(0xF5);
  delay(25);

  Wire.beginTransmission(ADDRESS);
  Wire.write(0xF6);
  Wire.endTransmission();
  delay(25);

}

Regards,

Tamas

You are sending the wrong command (0xF6 instead of 0xF7).

From the web page:

First of all you need to enter the calibration mode by sending a 3 byte sequence of 0xF0,0xF5 and then 0xF7 to the command register, these MUST be sent in 3 separate I2C frames, you cannot send them all at once. There MUST be a minimum of 20ms between each I2C frame. The LED will then extinguish and the CMPS11 should now be rotated in all directions on a horizontal plane, if a new maximum for any of the sensors is detected then the LED will flash, when you cannot get any further LED flashes in any direction then exit the calibration mode with a command of 0xF8.

Thanks for pointing that out. I corrected it, but it still doesn’t work. :frowning:

What do you mean by “doesn’t work”?

I cannot start the calibration. The LED is not flashing as it is supposed to.

Post the code you are actually using. It appears that you never even call calibrate().

#include <Wire.h>

#define ADDRESS 0x60

void setup(){
  Wire.begin();
  Serial.begin(9600);
  }

void loop(){
}

void calibrate(){

  Wire.beginTransmission(ADDRESS);
  Wire.write(0xF0);
  delay(25);

  Wire.beginTransmission(ADDRESS);
  Wire.write(0xF5);
  delay(25);

  Wire.beginTransmission(ADDRESS);
  Wire.write(0xF7);
  Wire.endTransmission();
  delay(25);

}

Even if I’m able to start the process of calibration. How do I send the last command (0xF8) to the compass? I think I should it manually, but how?

Please, always use code tags.

You need to actually call the function calibrate. Do that in setup() by adding this line:

calibrate(); 

I suggest to call calibrate, delay 30-90 seconds while you perform the procedure, then send the 0xF8.

Or, wait for a button press, then send 0xF8 when done calibrating.

Thank you. I put that into the program. It still doesn’t want to start the calibration unfortunately. The program looks like this now:

#include <Wire.h>

#define ADDRESS 0x60

void setup(){
  Wire.begin();
  Serial.begin(9600);
  while(!Serial);
  calibrate();
}

void loop(){
}

void calibrate(){

  Serial.println("Calibration Mode");
  delay(2000);  //2 second before starting
  Serial.println("Start");

  Wire.beginTransmission(ADDRESS);
  Wire.write(0xF0);
  delay(25);

  Wire.beginTransmission(ADDRESS);
  Wire.write(0xF5);
  delay(25);

  Wire.beginTransmission(ADDRESS);
  Wire.write(0xF6);
  delay(20000);

  Wire.beginTransmission(ADDRESS);
  Wire.write(0xF8);
  Wire.endTransmission();
  Serial.println("done");


}

(Btw, 0xF7 command is for horizontal operation only)

Why did you add this line, and what is its purpose?

while(!Serial);

Have you considered removing the potential infinite-loop:

while(!Serial);

If for whatever reason the serial port on your Arduino does not activate then it gets stuck there.

I removed the “while”. Still doesn’t “work”

Do you receive anything on the serial monitor? If so, then it is working. Just not how you expect it to do. And the serial port should have worked or else you couldn’t upload the program to it. Though the baudrate might be set differenly. Since you have not explained what sort of microcontroller this is running on, I would like to know more about this. Evidently by the code it is an arduino of some kind. How have you connected the CMPS11 chip to it? Please show how the wires are connected, and if you have pull up resistors applied to the wires.

Yes I do receive messages on the serial monitor, but that doesn’t necessarily mean it is working properly.

I’m sorry, you are right. I should have mentioned that this is running on an Arduino UNO. You can see how I connected it to the arduino here, and yes I have pull up resistors in circuit:

http://www.robot-electronics.co.uk/htm/ … PS11%20I2C

Tomadevil:
Yes I do receive messages on the serial monitor, but that doesn’t necessarily mean it is working properly.

Correct. But if someone only says “it doesn’t work” without other explanation of what it IS doing, meaning any signs of life, then we have to assume even the worst of conditions are possible. That the microcontroller is dead or damaged, has a power supply failure or short in it’s supply circuit, is in a reset-state, or got itself locked in a program state without ever having done any change to it’s GPIO pins. A full explanation of it’s behaviour is essential in locating the source of an issue. “doesn’t work” doesn’t help.

I’m sorry, you are right. I should have mentioned that this is running on an Arduino UNO. You can see how I connected it to the arduino here, and yes I have pull up resistors in circuit:

http://www.robot-electronics.co.uk/htm/ … PS11%20I2C

Good

Yes I do receive messages on the serial monitor…

Which are? Again, we have to know what it is thinking or doing, or where it takes the wrong action.

First message appers 1-2 sec after that I turned on the Arduino, which is:

“Calibrarion mode”

Two seconds later:

“Start”

Twenty seconds later:

“done”

The flashing LED on the compass module would indicate that the calibration has started, but it is not flashing. It is lit constantly.

It properly works now. I’m able to calibrate it :slight_smile:

For the sake of others with a similar problem, what was the problem and the solution?

The command register and Wire.endTransmission(); were missing of each byte send.

The correct code is the following:

 #include <Wire.h>

#define ADDRESS 0x60

void setup(){
  Wire.begin();
  Serial.begin(9600);
  calibrate();
}

void loop(){
}

void calibrate(){

  Serial.println("Calibration Mode");
  delay(2000);  //2 second before starting
  Serial.println("Start");

  Wire.beginTransmission(ADDRESS);
  Wire.write(0); //command register
  Wire.write(0xF0);
  Wire.endTransmission();
  delay(25);

  Wire.beginTransmission(ADDRESS);
  Wire.write(0); //command register
  Wire.write(0xF5);
  Wire.endTransmission();
  delay(25);

  Wire.beginTransmission(ADDRESS);
  Wire.write(0); //command register
  Wire.write(0xF6);
  Wire.endTransmission();

  delay(20000);

  Wire.beginTransmission(ADDRESS);
  Wire.write(0); //command register
  Wire.write(0xF8);
  Wire.endTransmission();
  Serial.println("done");


}

Thank you for all the help guys :slight_smile: