Saturday, July 5, 2014

Basic: HMC5883L (Digital Compass)

Hi, everyone. I am actually waiting for the time for breakfast. I'm writing this post to take my mind off the meal. So, this time, it's about a digital compass; HMC5883L which I bought from GI Electronic.


When I first played around with it, it was quite complicated, but soon enough, I manage to understand most of the important part of it. I wrote a library to make it even simpler to use, which can be found here or here.

Introduction

This module is actually a digital compass, which probably means that you've understand what it should do. It is a compass, which measures the magnetic strength around it in 3 axis; X, Y and Z. This module is using I2C communication. It is a famous type of communication and I really like it as it basically uses only 2 wires, SDA and SCL, and multiple devices could be connected on the same pin at the same time.

Connection

In the following diagram, notice that the pins listed aren't really accurate as the sketch is using a product by Adafruit, not the one sold by GI Electronic. The pins are equivalent as:

VIN = VCC
GND = GND
3vo = -
SDA = SDA
SCL = SCL
RDY = DRDY




Code

The following code simply prints the output or the degree based on X and Y axis.

#include <HMC5883L.h>
#include <Wire.h>

HMC5883L compass;

void setup(){
  Serial.begin(19200);
  compass.init();
}

void loop(){
  if(compass.available()) {
    Serial.println(compass.getHeading());
  }

  delay(100);
}

Important Note

By observing the serial monitor, turn the digital compass until the value move closer to 0 or 360. When you manage to get that value, you are actually finding the magnetic north. However, relying on the magnetic north alone is unwise especially when it comes to navigational use. At long distance, 1 degree difference could end up quite far. Be sure to deduct or add the declination angle according to where you are situated at to get the true north.

Look for your declination angle here: http://magnetic-declination.com/

About the library


Constructor (HMC5883L)
  • Prototype:
    • HMC5883L::HMC5883L(int address = 30);
  • Description:
    • Create the HMC5883L object and set the address of the module.
  • Arguments:
    • address: The address of the module with default value of 30 or 0x1E.
  • Returns:
    • None
  • Usage:
    • Outside any function. (Global)


init
  • Prototype:
    • void HMC5883L::init();
  • Description:
    • Begin the data transmission and selecting the continuous measurement mode.
  • Arguments:
    • None
  • Returns:
    • Void
  • Usage:
    • Inside setup() function.

available

  • Prototype:
    • bool HMC5883L::available();
  • Description:
    • Check if the data is available.
  • Arguments:
    • None
  • Returns:
    • true: if data is available.
    • false: if data is not available.
  • Usage:
    • Inside if block.

getHeading

  • Prototype:
    • double HMC5883L::getHeading();
  • Description:
    • Get the angle from North calculated between X and Y axis.
  • Arguments:
    • None
  • Returns:
    • Angle calculated between X and Y axis.
  • Usage:
    • Inside if block after ensuring data availability.

getAngleXY

  • Prototype:
    • double HMC5883L::getAngleXY();
  • Description:
    • Get the angle from North calculated between X and Y axis.
  • Arguments:
    • None
  • Returns:
    • Angle calculated between X and Y axis.
  • Usage:
    • Inside if block after ensuring data availability.

getAngleYZ

  • Prototype:
    • double HMC5883L::getAngleYZ();
  • Description:
    • Get the angle from North calculated between Y and Z axis.
  • Arguments:
    • None
  • Returns:
    • Angle calculated between Y and Z axis.
  • Usage:
    • Inside if block after ensuring data availability.

getAngleXZ

  • Prototype:
    • double HMC5883L::getAngleXZ();
  • Description:
    • Get the angle from North calculated between X and Z axis.
  • Arguments:
    • None
  • Returns:
    • Angle calculated between X and Z axis.
  • Usage:
    • Inside if block after ensuring data availability.