top of page

Safari browser sometimes has issues displaying images...

I.e: *you have to click on the images to see them...

​

For a better browsing experience on Brainy-Bits

Please use Chrome, Edge or Firefox browser.

  • Writer's pictureBrainy-Bits

Using the HMC5883L 3-Axis Compass module with an Arduino



OVERVIEW


The HMC5883L 3-Axis Compass module can measures magnetic fields in three directions: X, Y, and Z.


It can also be used as a simple compass to find the earth’s magnetic north.


In this tutorial we will only use 2 of the axis: X and Y.


We will see how to extract the analog information of both of these axis with an Arduino and then use the information to light up some WS2812 RGB LED when we move the sensor.


There are libraries available for this sensor that will enable you to tap into more capabilities.

 

PARTS USED


WS2812 RGB Stick

Arduino UNO


HMC5883L 3-Axis Compass Module


These are Amazon affiliate links...

They don't cost you anything and it helps me keep the lights on

if you buy something on Amazon. Thank you!

 

CONNECTIONS




The 3-axis sensor is connected to 3.3V, GND, A4 and A5 from the Arduino.


*The sensor will also accept 5V voltage if you want to.


Both WS2812 RGB sticks uses 5V and GND from the Arduino that we split using a breadboard.


We then connect them to digital pin 2 and 3.

 

THE CODE


We will use the Wire and FastLED libraries in our code.


The Wire library is used to communicate with the sensor and the FastLED is used to control the WS2812 RGB sticks.

Since we are using 2 RGB sticks, we will create two instances that we can control using FastLED.


As you can see in the code, we are reading the analog X and Y values of the sensor and then by using the MAP function we are lighting up the LEDs.


As always, please check out the tutorial video to have more information.


/* Start of Code */

#include "FastLED.h"
#include <Wire.h>

#define NUM_LEDS 8 // Number of LEDs per Stick
#define DATA_PIN_X 2 // Pin 2 connected to RGB X
#define DATA_PIN_Y 3 // Pin 3 connected to RGB Y

CRGB leds_X[NUM_LEDS];
CRGB leds_Y[NUM_LEDS];

/* The I2C address of the module */
#define HMC5803L_Address 0x1E

/* Register address for the X Y and Z data */
#define X 3
#define Y 7
#define Z 5

void setup() 
{
Serial.begin(9600); 
Wire.begin();
FastLED.addLeds<NEOPIXEL,DATA_PIN_X>(leds_X, NUM_LEDS);
FastLED.addLeds<NEOPIXEL,DATA_PIN_Y>(leds_Y, NUM_LEDS);

/* Initialise the module */ 
Init_HMC5803L();
}

void loop() 
{
/* Read each sensor axis data and output to the serial port */
Serial.print(HMC5803L_Read(X));
Serial.print(" ");
Serial.print(HMC5803L_Read(Y));
Serial.print(" ");
Serial.println(HMC5803L_Read(Z));

int xvalue = HMC5803L_Read(X);
int numLedsToLight = map(xvalue, -280, 600, 0, NUM_LEDS);
FastLED.clear();
for(int led = 0; led < numLedsToLight; led++) { 
if(led < 4)leds_X[led] = CRGB::Green;
if(led >=4 & led < 7)leds_X[led] = CRGB::Orange;
if(led >=7)leds_X[led] = CRGB::Red;
}

int yvalue = HMC5803L_Read(Y);
int numLedsToLight_1 = map(yvalue, -330, 330, 0, NUM_LEDS);
for(int led = 0; led < numLedsToLight_1; led++) { 
if(led < 4)leds_Y[led] = CRGB::Green;
if(led >=4 & led < 7)leds_Y[led] = CRGB::Orange;
if(led >=7)leds_Y[led] = CRGB::Red;
}
FastLED.setBrightness(50);
FastLED.show();

/* Wait a little before reading again */
delay(10);
}


/* This function will initialise the module and only needs to be run once
after the module is first powered up or reset */
void Init_HMC5803L(void)
{
/* Set the module to 8x averaging and 15Hz measurement rate */
Wire.beginTransmission(HMC5803L_Address);
Wire.write(0x00);
Wire.write(0x70);

/* Set a gain of 5 */
Wire.write(0x01);
Wire.write(0xA0);
Wire.endTransmission();
}


/* This function will read once from one of the 3 axis data registers
and return the 16 bit signed result. */
int HMC5803L_Read(byte Axis)
{
int Result;

/* Initiate a single measurement */
Wire.beginTransmission(HMC5803L_Address);
Wire.write(0x02);
Wire.write(0x01);
Wire.endTransmission();
delay(6);

/* Move modules the resiger pointer to one of the axis data registers */
Wire.beginTransmission(HMC5803L_Address);
Wire.write(Axis);
Wire.endTransmission();

/* Read the data from registers (there are two 8 bit registers for each axis) */ 
Wire.requestFrom(HMC5803L_Address, 2);
Result = Wire.read() << 8;
Result |= Wire.read();

return Result;
}

/* End of Code */


 

TUTORIAL VIDEO




 

DOWNLOAD


Copy the above Sketch code in your Arduino IDE software to program your Arduino.


You can download the FastLED library here and extract it to your Arduino IDE Library folder.

3,656 views0 comments

Recent Posts

See All

All my content is and will always be Free.

​

If you feel that my Videos / Tutorials are helping, and you would like to contribute...

 You can toss some coins in the Tip Jar via PayPal.

​

Select amount then click the “Donate” button.

bottom of page