Go Down

Topic: HMCL5883L Library Issues (Read 1 time) previous topic - next topic


Hey Gang!
I am working on building an IMU library based off the chipset found on this board:

I am communicating with these chips of I2C. In an effort to speed my read times, I want my libraries to stream read from the appropriate registers. I have also changed my wire library to operate at 400khz.
I had some success using the Wire.h library, but I recently downloaded the I2C.h library written by Wayne Truchsess.
I want to use this library to save me the hassle of dealing with read/write bits, ack/nack bits etc. This library's "read" function essentially calls for a stream read from the connected device.

My .h file just defines the class as well as the hex register addresses within the HMC5883L.
My .cpp only has two functions : begin() and read(int *). The read function just calls for an I2c.read and stores them into an array of bytes. Then it performs two's complement to stores the corresponding axis data back into an int.

My .ino file creates and instance of the class, calls these two functions, and prints the values read.

Here is my HCM3558L.h :

Code: [Select]
Created By  : Waymond91
Created On  : 9/4/2013
Description : I2C driver for the HMC5883L Magnetometer
Data Sheet  : https://www.cs.washington.edu/education/courses/466/12au/labs/blimp/HMC5883L.pdf

#ifndef HMC5883L_H
#define HMC5883L_H

#include "Arduino.h"
#include <I2C.h>

#define CONFIG_A 0x00
#define CONFIG_B 0x01
#define MODE 0x02
#define XMSB 0x03
#define XLSB     0x04
#define YMSB     0x05
#define YLSB     0x06
#define ZMSB     0x07
#define ZLSB     0x08
#define STATUS   0x09
#define ID_A 0x0A
#define ID_B     0x0B
#define ID_C     0x0C

#define MAG_ADDRESS 0x1E               // 7-bit address of HMC5883 compass

class HMC5883L {
uint8_t begin();
uint8_t read(int *);


Here is my HMC5883L.cpp :

Code: [Select]
#include <I2C.h>
#include <HMC5883L.h>

uint8_t HMC5883L::begin(){
uint8_t status;
status = I2c.write(MAG_ADDRESS,MODE,0x02);

if(status != 0)
Serial.println("Error Starting HMC5883L");
if(status == 0)
Serial.println("HCM5883L Started Succesfully");

return status;

uint8_t HMC5883L::read(int i[]){

uint8_t status, i2c_in[6];

if(I2c.available() == 6){
for(int z = 0; z < 6; z ++){
i2c_in[z] = I2c.receive();

i[0] = (((int)i2c_in[0]) << 8) | i2c_in[1];   
i[1] = (((int)i2c_in[2]) << 8) | i2c_in[3];
i[2] = (((int)i2c_in[4]) << 8) | i2c_in[5];

        return 0;
return 1;

And here is my .ino :

Code: [Select]
#include <I2C.h>
#include <HMC5883L.h>

HMC5883L Comp;

int dr[3],ar[3],mr[3];
long now, last;

void setup(){



void loop(){

void print_vector(int * vector){
for(int i = 0; i <= sizeof(vector); i ++){
Serial.print(vector[i]);Serial.print(" ");

However, when I print the magnetometer vector, it seems that I am consistantly receiving the same junk because the values never change regardless of the IMUs orientation.
Any idea as to what I am doing wrong??? At first I thought it was a variable type error, but now I have no clue.


With this line

Code: [Select]
status = I2c.write(MAG_ADDRESS,MODE,0x02);

your setting your compass chip into idle mode. It this really what you intended to do?

Go Up