HMC6343 Calibration

I am currently reading values from the HMC6343

The reading north seems to be accurate, but then one i start rotating, when it says south at 180 degrees, its not where south is ect.

I wish to calibrate the chip and i am wondering if there is a defualt setting if for some reason i mess up the calibration, is their some kind of reset for the chip?

As well as,

Once in calibration mode i found some code for it, but im not sure on the timing, you are sappose to rotate in the Y then in the Z but for how long and when do you switch?

Any insight would help.


You should read the datasheet:

Particularly the part about user calibration:

User Hard-Iron Calibration

The HMC6343 provides a user calibration routine with the 0x71 command permitting entry into the calibration mode and the 0x7E command to exit the calibration mode.

After entering the calibration mode, rotate the device reasonably steady for 360 degrees about the Y (Left - Right) axis and then 360 degrees about Z (Up - Down) axis. During the first rotation, maintain the Y axis at Level as much as possible. Maintain the Z axis upright as much as possible during the second rotation and until the exit calibration command is issued. The first rotation can also be done by rotating 360 degrees about X (Fore -Aft) axis. Then exit calibration.

The calibration routine collects these readings to correct for hard-iron distortions of the magnetic field. These hard-iron effects are due to magnetized materials nearby the HMC6343 part that in a fixed position with respect to the end user platform. An example would be the magnetized chassis or engine block of a vehicle in which the compass is mounted onto. Upon exiting the calibration mode, the resulting magnetometer offsets are updated.

I have read the data sheet,

just wondering if there is some kinda time frame, so you know its collected the right data at the right time, type of thing.

and my big thing is if there is reset values, default settings for the calibration values.

i guess ill just run the calbration code i got and hope for the best? haha

here is the code i am using:

#include <Wire.h>

int compassAddress = 0x32 >> 1;  // From datasheet compass address is 0x32 for write operations, 
                                 // or 0x33 for read operations.
                                 // shift the address 1 bit right, the Wire library only needs the 7
                                 // most significant bits for the address

int heading = 0;  // variable to hold the heading angle
int tilt = 0;     // variable to hold the tilt angle
int roll = 0;     // variable to hold the roll angle

byte responseBytes[6];  // for holding the sensor response bytes

void setup() 
  delay(500);  //Wait at least 500 milli-seconds for device initialization
  Wire.begin();        // join i2c bus (address optional for master) 
  Serial.begin(9600);  // start serial communication at 9600bps 

void loop() 
  readSensor();  // read data from the HMC6343 sensor
  // Note that heading, tilt and roll values are in tenths of a degree, for example
  // if the value of heading is 1234 would mean 123.4 degrees, that's why the result
  // is divided by 10 when printing.
  Serial.print("Heading: ");
  Serial.print(heading / 10, DEC); 
  //Serial.print(" Tilt: ");
  //Serial.print(tilt / 10, DEC);
 //Serial.print(" Roll: ");
  //Serial.println(roll / 10, DEC);
  delay(200);                   // wait for half a second 
void readSensor() 
  // step 1: instruct sensor to read echoes 
  Wire.beginTransmission(compassAddress);  // transmit to device
                           // the address specified in the datasheet is 66 (0x42) 
                           // but i2c adressing uses the high 7 bits so it's 33 
  Wire.send(0x50);         // Send a "Post Heading Data" (0x50) command to the HMC6343  
  Wire.endTransmission();  // stop transmitting 
  // step 2: wait for readings to happen 
  delay(2);               // datasheet suggests at least 1 ms 
  // step 3: request reading from sensor 
  Wire.requestFrom(compassAddress, 6);  // request 6 bytes from slave device #33 
  // step 4: receive reading from sensor 
  if(6 <= Wire.available())     // if six bytes were received 
    for(int i = 0; i<6; i++) {
      responseBytes[i] = Wire.receive();
  heading = ((int)responseBytes[0]<<8) | ((int)responseBytes[1]);  // heading MSB and LSB
  tilt = (((int)responseBytes[2]<<8) | ((int)responseBytes[3]));  // tilt MSB and LSB
  roll = (((int)responseBytes[4]<<8) | ((int)responseBytes[5]));  // roll MSB and LSB

   void calibration()
		 Serial.println("Entering Calibration mode...");		 

		 Serial.println("Rotate in the Y Axis.");		 
		 Serial.println("Rotate in the Y Axis.");		 


		 Serial.println("Exiting Calibration");
		 delay(2000) ;

didnt seem to do much when i ran it…numbers seem to be coming up around the same

didnt change my heading is just 0...ah crap..

Calibration data is stored in EEPROM at offsets 0x0e thru to 0x13. If you write zero's to these offsets you should be back to factory defaults as far as calibration goes.

Ah excellent

Thanks for the help everyone

Gonna keep on trying, hopefully i can get this thing to start giving me proper readings.