MAG3110 Magnetometer Hookup Guide

Pages
Contributors: AGlass0fMilk
Favorited Favorite 1

Calibration

All these functions are great... but what if you need to find a portal to The Upside Down? You need a heading! This sensor and library allow you to obtain the magnetic north heading very easily!

Note that this only works when the sensor is level with the z-axis pointing straight up or down. The heading will be relative to the positive x-axis (ie: the x-axis arrow silkscreened on the board points to magnetic north).

magnetic north

To find out how to use the library's calibration, open up the included example sketch, SparkFun-MAG3110-Calibration.ino.

When you run the sketch, you will see unadjusted readings in the Serial output for the first 5 to 10 seconds. During this period, you must rotate the MAG3110 360 degrees while keeping it level!. This allows our sketch to get its bearings.

The reason for calibration is that your surroundings may have static magnetic fields that offset the MAG3110 readings. For example, if you have something magnetic near the sensor this will add an offset to the sensor's readings.

This calibration code will center the x and y-axis readings around 0 or about there. The z-axis is not calibrated with this library. This calibration works by taking a bunch of readings and trying to find the minimum and maximum values for the x and y axes. It then uses these min and max values to calculate an offset and a scaling factor. The calibration code is based off of this code found here.

A Honeywell application note detailing how the heading is calculated can be found here.

language:c
#include <SparkFun_MAG3110.h>

MAG3110 mag = MAG3110(); //Instantiate MAG3110

void setup() {
  Serial.begin(9600);

  Wire.begin();             //setup I2C bus
  Wire.setClock(400000);    // I2C fast mode, 400kHz

  mag.initialize(); //Initialize the MAG3110
}

void loop() {

  int x, y, z;

  if(!mag.isCalibrated()) //If we're not calibrated
  {
    if(!mag.isCalibrating()) //And we're not currently calibrating
    {
      Serial.println("Entering calibration mode");
      mag.enterCalMode(); //This sets the output data rate to the highest possible and puts the mag sensor in active mode
    }
    else
    {
      //Must call every loop while calibrating to collect calibration data
      //This will automatically exit calibration
      //You can terminate calibration early by calling mag.exitCalMode();
      mag.calibrate(); 
    }
  }
  else
  {
    Serial.println("Calibrated!");
  }
  mag.readMag(&x, &y, &z);

  Serial.print("X: ");
  Serial.print(x);
  Serial.print(", Y: ");
  Serial.print(y);
  Serial.print(", Z: ");
  Serial.println(z);

  Serial.print("Heading: ");
  Serial.println(mag.readHeading());

  Serial.println("--------");

  delay(100);
}

Note a few things about the calibration functions.

Setting the MAG3110 to calibration mode (ie: using mag.enterCalMode()) will set it to the highest output data rate and enter active mode. You will need to set your desired ODR and OSR after calibration, and enter standby if you wish. If you just want to simply read values, you can leave these settings alone.

When calibrating, you must call mag.calibrate() every loop cycle. This allows the code to sample the MAG3110 readings and find the minimum and maximum values.

The calibration mode will automatically exit after some time but at least 5 seconds. If this is too long, you can terminate the calibration earlier by calling mag.exitCalMode(). Please note that the calibration may be offset if you do not calibrate enough!

If you have not calibrated the MAG3110, calling mag.readHeading() will only give you 0! Otherwise, it will show values ranging from -180 to +180. When the heading is 0, the x-axis is pointing towards magnetic north (see the diagram from before).

As mentioned before, if you want to manually calibrate the MAG3110 using previously obtained calibration values, you need to do a few things: Save the offsets using mag.readOffset(), and save the scaling floats, mag.x_scale and mag.y_scale. When reloading this calibration, you have to use mag.setOffset() and write the old scaling factors back to mag.x_scale and mag.y_scale. For completeness, update the mag.calibrated value to true as well. Note that as the calibration data becomes outdated, recalibration is recommended.