HMC 6343

Hello,

Testing this magnetometer with a sparkfun redboard (ie Uno). Wired it up as directed in the hook up guide and used the basic sketch provided. I do get data back but the heading seems to vary 5-10 degrees. Better the more isolated I keep the chip from other electronics. Tried to implement the filter to even out the values somewhat and does not seem different. I got the filter code from the advanced sketch.

Does anyone see any mistakes in the code below, or have other suggestions?

Thanks

Victor

// Libraries for I2C and the HMC6343 sensor

#include <Wire.h>

#include “SFE_HMC6343.h”

SFE_HMC6343 compass; // Declare the sensor object

void setup()

{

// Start serial communication at 115200 baud

Serial.begin(115200);

// Give the HMC6343 a half second to wake up

delay(500);

// Initialize the HMC6343 and verify its physical presence

if (!compass.init())

{

Serial.println(“Sensor Initialization Failed\n\r”); // Report failure, is the sensor wiring correct?

}

}

void loop()

{

// Read, calculate, and print the heading, pitch, and roll from the sensor

compass.readHeading();

printHeadingData();

// Read, calculate, and print the acceleration on the x, y, and z axis of the sensor

compass.readAccel();

printAccelData();

// Write the filter value (used for weighted averages of sensor reads) to the EEPROM of the HMC6343

// FILTER_LSB register can be set between 0x00 and 0x0F

// It averages the last X sensor readings (filter register value) with the latest reading

// Example: if set to 4 (instead of default 0), it would average the last 4 readings with the latest reading

// for sensor values such as heading with the last 4 for a total of a second average (5Hz)

compass.writeEEPROM(FILTER_LSB, 4); // 0x00-0x0F, default is 0x00

delay(10); // 10ms before sensor can accept commands after writing to the EEPROM

// To actually enable the filter, the filter bit must be set in OPMode1 register: 0bxx1xxxxx

compass.writeEEPROM(OP_MODE1, 0x31); // Enable filter (default OPMODE1 + filter enable bit set)

//compass.writeEEPROM(OP_MODE1, 0x11); // Default, filter disabled (0bxx010001)

delay(10);

// Wait for two seconds

delay(2000); // Minimum delay of 200ms (HMC6343 has 5Hz sensor reads/calculations)

}

// Print both the raw values of the compass heading, pitch, and roll

// as well as calculate and print the compass values in degrees

// Sample Output:

// Heading Data (Raw value, in degrees):

// Heading: 3249 324.90°

// Pitch: 28 2.80°

// Roll: 24 2.40°

void printHeadingData()

{

Serial.println(“Heading Data (Raw value, in degrees):”);

Serial.print("Heading: ");

Serial.print(compass.heading); Serial.print(" "); // Print raw heading value

Serial.print((float) compass.heading/10.0);Serial.write(176);Serial.println(); // Print heading in degrees

Serial.print("Pitch: ");

Serial.print(compass.pitch); Serial.print(" ");

Serial.print((float) compass.pitch/10.0);Serial.write(176);Serial.println();

Serial.print("Roll: ");

Serial.print(compass.roll); Serial.print(" ");

Serial.print((float) compass.roll/10.0);Serial.write(176);Serial.println();

Serial.println();

}

// Print both the raw values of the compass acceleration measured on each axis

// as well as calculate and print the accelerations in g forces

// Sample Output:

// Accelerometer Data (Raw value, in g forces):

// X: -52 -0.05g

// Y: -44 -0.04g

// Z: -1047 -1.02g

void printAccelData()

{

Serial.println(“Accelerometer Data (Raw value, in g forces):”);

Serial.print("X: ");

Serial.print(compass.accelX); Serial.print(" "); // Print raw acceleration measurement on x axis

Serial.print((float) compass.accelX/1024.0);Serial.println(“g”); // Print x axis acceleration measurement in g forces

Serial.print("Y: ");

Serial.print(compass.accelY); Serial.print(" ");

Serial.print((float) compass.accelY/1024.0);Serial.println(“g”);

Serial.print("Z: ");

Serial.print(compass.accelZ); Serial.print(" ");

Serial.print((float) compass.accelZ/1024.0);Serial.println(“g”);

Serial.println();

}

You should calibrate the magnetometer in its final resting place. Here are two procedures, in order of increasing quality and accuracy:

http://www.bot-thoughts.com/2011/04/qui … on-in.html

http://sailboatinstruments.blogspot.com … ation.html

Yes I get the calibration issue when the sensor is finally in “it’s resting place.”

My question is how to get the filter function built into the HMC 6343 to work properly. So far the code I am using doesn’t seem to have worked.

To put jremington’s post into more simple term for you: Have you calibrated the magnetometer yet?

Filtering won’t help if the values are wrong. My approach in such cases is to fix the real problem first.

The magnetometer has it’s own calibration routine described in the datasheet and the library has code to enter and exit the calibration mode. I will take the unit to the boat where I plan to use it, and calibrate this weekend.

The reason I am trying to get the filtering operating is at the suggestion of sparkfun. He looked at my code and thought it was OK, but I wondered if someone else could spot an error.

I do understand the concept of having the raw data as accurate and consistent as possible, and that averaging makes the numbers smoother at the expensive accuracy etc.

I appreciate the suggestions.

Went through the calibration routine described in the datasheet. Decided to do at home and repeat later with final installation at the boat. At first it seemed to make things a lot worse. I eventually realized that while in calibration mode the unit needs to be rotated first counter clockwise (ie not clockwise) and than up for 360 deg as well. That seemed to accomplish calibration. Still not sure how much the filtering code is doing but seems now to be within several degrees which is likely OK.

The project is a simple heading based autopilot for my 32ft boat. It is a trawler style at speeds around 6-7 knots most of the time. Next step is to figure out how to mount a pot on the steering somewhere so I can have rudder position. H bridge and some code should get me something that works after that.