SparkFun Forums 

Where electronics enthusiasts find answers.

General project discussion / help
Did you make a robotic coffee pot which implements HTCPCP and decafs unauthorized users? Show it off here!
By Valen
#188140
Tomadevil wrote: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.
By Tomadevil
#188147
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.
By jremington
#188172
For the sake of others with a similar problem, what was the problem and the solution?
By Tomadevil
#188198
The command register and Wire.endTransmission(); were missing of each byte send.
The correct code is the following:
Code: Select all
 #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 :)
By Tomadevil
#189149
I know it's been a long time since my last post, but I've not had time to do anything with this module.
I have built a frame to check the accuracy of the compass, but It doesn't want to work properly. When I'm turning the compass to one directon by 90 degree, the sensor show only 20 degree change, then suddenly jumps up to a very high value. It is very annoying. Has anyone had similar problem with their compass or do you guys have any idea what to do?
Image
By elvisß1
#189888
Hi Tomadevil,
the frame is looking really good... but did you make the joints out of metal?
It is a very simple mistake: if there is some metal nearby, the calibration would never work properly.
I have also a CMPS11 it is not very accurate, I will try to calibrate it, but I don't have a test device to measure the accuracy.
In case you solved your problem, plse reply!

Regards, elviß1
By mutant
#195980
Old thread, but hopefully I can help.
If you are testing as shown in the picture, you are testing the compass upside down. The tilt compensation on the 11 does not go that far.
Your frame is great, but only has two degrees of freedom. If you add a third it will make an awesome tool for getting good calibration.
Ignore the comments about the joints. They will have negligible effect. You can always replace steel with copper or brass, both of which have ~zero magnetic impact.
The compass should be accurate to 2% - that's 7.2 degrees. Mine only manages 8 degrees, even after calibration.
By duckman1961
#197341
Hi all, code below which may help someone. This has calibration, default calibration and heading ability.
This CMPS11 IMU in Tasmania has up to +-6 degrees heading error at 30 degree tilt, +-9 degrees at 45 degree tilt, at worst heading, unusual in that it is on approx Easterly heading.
Very good stationary repeat ability <= +- 0.4 degrees.
Very good around the compass rose linearity at worst 6 degrees error (using IMU's 0 degrees as being North).
Above results were with Manual Calibration, which gave slightly better results than the default bias(by 1-2 degrees less tilt error, linearity was about the same).
IMHO this is an over priced IMU for its tilt error performance but has the advantage of having on board fusion, the Adafruit NXP Precision does a better job (tilt error) for the price, but it suffers from a stationary heading (not very stationary) movement of up to +-2 degree.
Regards Kevin



Code: Select all
/*
*     CMPS11 I2C example for Arduino     *
*        By James Henderson, 2014        * 
*     
*     Calibration, Manual and Default    *
*        By Duckman1961, 2017        *
*     
* Heading,Caliibration (manual or default) All need to be either commented or uncommented out to operate (ONLY 1 can be uncommented to operate at any time), then load to board
* Manual Calibration time period to do movements can be altere at line 97
* Video on how to cal, https://www.youtube.com/watch?v=gB3Tt1eQQLQ
*
*/


#include <Wire.h>
#define CMPS11_ADDRESS 0x60  // Address of CMPS11 shifted right one bit for arduino wire library
#define ANGLE_8  1           // Register to read 8bit angle from

unsigned char high_byte, low_byte, angle8;
char pitch, roll;
unsigned int angle16;

void setup(){
  Wire.begin();
  Serial.begin(9600);
 // calibrate();//Uncomment this line to do own calibration, uncomment only 1
//default_calibrate();// Uncomment this line to reset IMU back to default cal data, uncomment only 1
}

void loop()
{
  Heading_loop();// Comment out to do either Cal modes, uncomment  to display heading, uncomment only 1
}



void Heading_loop() //Below gives heading data in Serial Monitor, uncomment in loop() to use
{

  Wire.beginTransmission(CMPS11_ADDRESS);  //starts communication with CMPS11
  Wire.write(ANGLE_8);                     //Sends the register we wish to start reading from
  Wire.endTransmission();
 
  // Request 5 bytes from the CMPS11
  // this will give us the 8 bit bearing, 
  // both bytes of the 16 bit bearing, pitch and roll
  Wire.requestFrom(CMPS11_ADDRESS, 5);       
  
  while(Wire.available() < 5);        // Wait for all bytes to come back
  
  angle8 = Wire.read();               // Read back the 5 bytes
  high_byte = Wire.read();
  low_byte = Wire.read();
  pitch = Wire.read();
  roll = Wire.read();
  
  angle16 = high_byte;                 // Calculate 16 bit angle
  angle16 <<= 8;
  angle16 += low_byte;
    
  Serial.print("roll: ");               // Display roll data
  Serial.print(roll, DEC);
  
  Serial.print("    pitch: ");          // Display pitch data
  Serial.print(pitch, DEC);
  
  Serial.print("    YAW: ");     // Display 16 bit angle with decimal place
  Serial.print(angle16 / 10, DEC);
  Serial.print(".");
  Serial.println(angle16 % 10, DEC);
  
   
  delay(100);                           // Short delay before next loop,(100) 10hz update
}

void calibrate()//Below used to do manual mag/accel calibration, uncomment in setup to use
{

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

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

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

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

  delay(180000);//(ms)Alter this to allow enough time for you to calibrate Mag and Accel

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


}


void default_calibrate()//Below resets factory default cailbration, to use uncomment in setup loop
{

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

  Wire.beginTransmission(CMPS11_ADDRESS);
  Wire.write(0); //command register
  Wire.write(0x6A);
  Wire.endTransmission();
  delay(25);

  Wire.beginTransmission(CMPS11_ADDRESS);
  Wire.write(0); //command register
  Wire.write(0x7C);
  Wire.endTransmission();
  delay(25);

  Wire.beginTransmission(CMPS11_ADDRESS);
  Wire.write(0); //command register
  Wire.write(0xb1);
  Wire.endTransmission();

 
  Serial.println("done");


}