HMC5883L Magnetometer & freeIMU library issues

Hi, I'm new here/new to arduino...
I'm trying to use the freeIMU library for accessing the GY-85 sensor stick.
It includes the HMC5883L magnetometer.
I'm having a couple of issues using the library + magneto:

  1. the library is designed to use the SparkFun SEN-10724 sensor stick, which has the same magnetometer, yet it is mounted at a right right angle from the gyros & accel.
    the GY-85 has all sensors mounted along the same axis.
    Here are some pictures to show what I mean:
    https://dlnmh9ip6v2uc.cloudfront.net//images/products/1/0/7/2/4/10724-03b.jpg
    http://img.dxcdn.com/productimages/sku_148436_1.jpg
    Due to this difference in physical orientation, freeIMU is calculating a heading that is 90 degrees off
    (i.e., pointing the PCB's x-axis toward due north shows a heading of 270 degrees instead of 360).
    I've been looking at the freeIMU source code, but I don't see any clear way to fix this...
    Can anyone please help me out with how to make the correction?

  2. I tried running some of the example sketches included with the freeIMU library in order to inspect the raw/heading readings coming from the magnetometer.
    I found that rotating the pcb 180 degrees along the horizontal plane doesn't produce an equal, yet opposite change in readings.
    Example: holding the sensor 'flat' and in the direction of 'due magnetic north' produces a max sensor reading of approx. '470', so I would expect that holding it in the exact opposite 'due south' position should also show a value of '-470', but it doesn't...Instead, it shows a value of around '-290'. This seems to throw off all of the other calculations done by the library. Rotating the pcb to the 'due east' and 'due west' positions displays the same behavior; I would expect the values to be '0' in the oppositely-oriented positions, but they aren't equal.
    So, my questions are:

  • is this behavior normal, or do I possibly have a faulty magnetometer?
    -if it is normal, should I be running some sort of 'dynamic' calibration routine(s) in order to find the min & max values of all axes?
  • does the freeIMU library handle this stuff, or is this something that I'd have to do on my own?

Please help, thanks...

I don't use FreeIMU, but magnetometers and usually also accelerometers do need calibration. Your tests to look at the magnetometer output for due magnetic north and due magnetic south were on the mark, and show that this unit has substantial offsets that must be corrected. These will be different for every axis. There are also likely to be differences in the gain for each axis. My favorite procedure is very well documented at Sailboat Instruments: Improved magnetometer calibration (Part 1)

This page describes procedures for the magnetometer, but they work just as well for the accelerometer if the unit is held still while each data point is collected. It makes a huge difference in the accuracy of the readings to go through this procedure, and it should be performed after the magnetometer is built into its final resting place.

Edit: As far as correcting for chip orientation is concerned, the routine in FreeIMU.cpp where the magnetometer raw values are read is an obvious place to add code to rearrange the axes. Take a look at the last three lines here:

/**
 * Populates raw_values with the raw_values from the sensors
*/
void FreeIMU::getRawValues(int * raw_values) {
  #if HAS_ITG3200()
    acc.readAccel(&raw_values[0], &raw_values[1], &raw_values[2]);
    gyro.readGyroRaw(&raw_values[3], &raw_values[4], &raw_values[5]);
  #else
    accgyro.getMotion6(&raw_values[0], &raw_values[1], &raw_values[2], &raw_values[3], &raw_values[4], &raw_values[5]);
  #endif
  #if HAS_HMC5883L()
    magn.getValues(&raw_values[6], &raw_values[7], &raw_values[8]);
  #endif