CMPS12 Compass - How to delete the calibration profile

The CMPS12 is a great compass. When I am running it on an arduino, I get great, solid, continuous results. But mounted on a robot, it boots up at 358 degrees EVERY time. I have tried to delete the cal profile to see if it needs to recalibrate for the bot, but am unsuccessful. Here is the code:

void calibrate() {

Wire.beginTransmission(CMPS12_ADDRESS);
Wire.write(0xE0);
delay(25);

Wire.beginTransmission(CMPS12_ADDRESS);
Wire.write(0xE5);
delay(25);

Wire.beginTransmission(CMPS12_ADDRESS);
Wire.write(0xE2);
Wire.endTransmission();
delay(25);

}
with reset numbers from the data sheet. This is a the way the CMPS11 was calibrated, but with the CMPS12 write numbers.

Calibration register reads a “3” [fully calibrated] all the time, even after the above function is run.

The chip is mounted above the bot, but it was mounted right on the Arduino board without problems. I can’t find example code except for the one sketch by James Henderson [2014].

Does anyone have access to more info on this chip?

Thanks

hello,

you have forgotten the write to the command register 0x00i and close the connection after each request send
the following function works:

void CMPS12Class::CMPS12_eraseProfil()
{
Wire.beginTransmission(_address);
Wire.write(0x00);
Wire.write(0xE0);
_last_status = Wire.endTransmission();

  delay(20); //  20ms delay after each of the three bytes send
  Wire.beginTransmission(_address);  
  Wire.write(0x00);
  Wire.write(0xE5);
  _last_status = Wire.endTransmission();
   
  delay(20); //  20ms delay after each of the three bytes send
  Wire.beginTransmission(_address);  
  Wire.write(0x00);  
  Wire.write(0xE2);
  _last_status = Wire.endTransmission();  
  
  delay(20); //  20ms delay after each of the three bytes send

Perfect. Thank you for the info.

Additional Question: Can this be used to read the registers as well [the only way I have found to read register 30 was to read all the registers]

For example: would this work?

begin transmission
write command register
write register needed
endTransmission
delay
read register

Thanks

Hello

below a piece of code the reade properly the register
hope it will help you

cheers

// Read a 16-bit register low byte high and then low byte
uint16_t BH1720Class::BH1720_readReg16BitHL(uint8_t reg)
{
  uint16_t value;
  
  Wire.beginTransmission(_address);
  Wire.write(reg);
  _last_status = Wire.endTransmission();
  if (_last_status > 0) return _last_status;

  _last_nb_receive = Wire.requestFrom(_address, (uint8_t)2);
  if (_last_nb_receive != 2) {_last_status=WIRE_REQUEST_ERROR; return _last_status;}
    
  uint8_t msb = Wire.read(); // value high byte
  uint8_t lsb = Wire.read(); // value low byte

  value  = (((uint16_t)msb) << 8) | lsb;
  
  return value;
}


double BH1720Class::BH1720_getLux()
{
  uint16_t lux = BH1720_readReg16BitHL(_address);
  if (_last_status >0) return (double)_last_status;
  
  delay (120);  // The result of continuously measurement mode is updated.( 120ms.typ at H-resolution mode)
  
  return (double)lux/1.2; // H-Resolution Mode: 1lux resolution 120ms
}

sorry with the good piece of code :slight_smile:

// Read an 8-bit register
uint8_t CMPS12Class::CMPS12_readReg(uint8_t reg)
{
  uint8_t value=0;

  Wire.beginTransmission(_address);
  Wire.write(reg);
  _last_status = Wire.endTransmission();
  if (_last_status > 0) return _last_status;

  _last_nb_receive = Wire.requestFrom(_address, (uint8_t)1);
  if (_last_nb_receive != 1) {_last_status=WIRE_REQUEST_ERROR; return _last_status;}
  value = Wire.read();

  return value;
}