Go Down

Topic: Looking for help with HMC5883L compass from other users (Read 24861 times) previous topic - next topic


Hey all,
I just got an order of Honeywell's new HMC5883L compass IC's in the mail the other day and am working on a breakout pcb.  I've run across an odd problem and was wondering if anyone else using the chip is experiencing the same problem.  Once the board was fully assembly I tried testing it and was unable to communicate via I2C.  I checked the board over several times and everything looked good.  I started troubleshooting and Wire.endTransmission was returning the code for Slave not Acknowledging Address.  I decided to run the I2C buss scanner sketch from Todbot and it returned an address of 0x1C, the datasheet says the 7 bit address should be 0x1E.  I did a quick Google search and saw someone experimenting with the chip and they were using the 0x1E address.  The chip has a top code marking of L883 so it appears to be the correct IC.  I know the 0x1C address works because I am able to read the 3 ID registers starting at address 0x0A and they are correct according to the datasheet.  I was just wondering if anyone else was having this issue and if others wouldn't mind verifying their chip's top marking with respect to mine.  I'm going to contact Honeywell on Monday to let them know of the discrepancy.


NO answer, just a thought: The difference between 1C and 1E is 2. I2C Chips have often a few datalines to change the address. Could it be that there is an adress pin accidentaly (dis)connected so it misses bit 2. ??

Code: [Select]

0x1E = 0001 1110
0x1C = 0001 1100 
0x02 = 0000 0010
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)


Interesting point robtillaart, that would explain it but it would have to be internal to the chip because this one doesn't have an external address select pin.  I also found 3 out of the 4 system registers have different power default settings as compared to the datasheet.  I did a little write up here... http://www.dsscircuits.com/articles/the-mysterious-hmc5883l.html


I found this code somewhere. Can't remember where (sorry for not acknowledging the contributor :smiley-red:  )

#define HMC5883_WriteAddress 0x1E //  i.e 0x3C >> 1
#define HMC5883_ModeRegisterAddress 0x02
#define HMC5883_ContinuousModeCommand 0x00
#define HMC5883_DataOutputXMSBAddress  0x03

int regb=0x01;
int regbdata=0x40;

int outputData[6];

void setup()

    Wire.begin();       //Initiate the Wire library and join the I2C bus as a master


void loop() {

    int i,x,y,z;
    double angle;


    Wire.beginTransmission(HMC5883_WriteAddress); //Initiate a transmission with HMC5883 (Write address).
    Wire.send(HMC5883_ModeRegisterAddress);       //Place the Mode Register Address in send-buffer.
    Wire.send(HMC5883_ContinuousModeCommand);     //Place the command for Continuous operation Mode in send-buffer.
    Wire.endTransmission();                       //Send the send-buffer to HMC5883 and end the I2C transmission.

    Wire.beginTransmission(HMC5883_WriteAddress);  //Initiate a transmission with HMC5883 (Write address).
    Wire.requestFrom(HMC5883_WriteAddress,6);      //Request 6 bytes of data from the address specified.


    //Read the value of magnetic components X,Y and Z

    if(6 <= Wire.available()) // If the number of bytes available for reading be <=6.
            outputData=Wire.receive();  //Store the data in outputData buffer

    x=outputData[0] << 8 | outputData[1]; //Combine MSB and LSB of X Data output register
    z=outputData[2] << 8 | outputData[3]; //Combine MSB and LSB of Z Data output register
    y=outputData[4] << 8 | outputData[5]; //Combine MSB and LSB of Y Data output register

    angle= atan2((double)y,(double)x) * (180 / 3.14159265) + 180; // angle in degrees


  Refer the following application note for heading calculation.
  atan2(y, x) is the angle in radians between the positive x-axis of a plane and the point
  given by the coordinates (x, y) on it.

  This sketch does not utilize the magnetic component Z as tilt compensation can not be done without an Accelerometer


NW  |  NE
SW  |  SE


    //Print the approximate direction

    Serial.print("You are heading ");
    if((angle < 22.5) || (angle > 337.5 ))
    if((angle > 22.5) && (angle < 67.5 ))
    if((angle > 67.5) && (angle < 112.5 ))
    if((angle > 112.5) && (angle < 157.5 ))
    if((angle > 157.5) && (angle < 202.5 ))
    if((angle > 202.5) && (angle < 247.5 ))
    if((angle > 247.5) && (angle < 292.5 ))
    if((angle > 292.5) && (angle < 337.5 ))

    Serial.print(": Angle between X-axis and the South direction ");
    if((0 < angle) && (angle < 180) )
    Serial.println(" Deg");


I am having a different problem reading the HMC8553. I can read and write registers when I read  in the data I get constants of 0X0F00 on the X & Z axis's the Y axis appears to be working with values that change with orientation. I'm using the above code to talk to it.


Looks like it is a gain issue. Probably not helped by having the sensor a couple inches away from my CRT  :smiley-roll:


Have you checked the power on default states of the config and mode registers and compared them to the datasheet?  I decided to mount a second IC today and this one uses the correct address, however it looks like the default register don't match up with the datasheet.  You can read about it here and see my values, there is a also a test sketch that reads all the registers.


I found this code somewhere. Can't remember where (sorry for not acknowledging the contributor

Looks like that code comes from Seeedstudio.  Actually the code is for a HMC5883 that Seeedstudio has on one of their compass boards, the problem is though it's for a HMC5883 not an HMC5883L.  Apparently the two chips are different.  They are the same physical size and pin count but the HMC5883 uses additional pins (similar to the HMC5843) as compared to the HMC5883L.  I zoomed in on the picture at Seeedstudio and the top marking code was M883 while mine is L883.  Interestingly enough I assembled another board and the address issue is resolved and I can now access all the registers with the correct address.  Unfortunately the data registers contain invalid data.  The default states of the Config registers are still not the same as the datasheet.  However, after some searching around I pulled the datasheet for the HMC5883 and it's default register state more closely matches my default register state. I have a sneaking suspicion there was a mix up somewhere along the production cycle.


Oops I forgot to update this thread in case anyone was interested.  There was no explanation from Honeywell as to why the address was different (probably something damaged during the reflow process).  The gentleman from Honeywell informed me that the power on default register values in the datasheet are wrong and the numbers I am seeing are correct and will be reflected in the next revision of the datasheet.  As for the inconsistencies with the data read for X, Y and Z that was due to mislabeled caps in my bin.  Who would've thought using 220 pF caps instead of 220nF would make such a difference! :smiley-yell:
Everything is working now.  Also in case anyone is interested, it looks like the HMC5883L doesn't suffer from the same problem with voltage dropout/capacitor selection like the HMC5843 did.


Would you share a working code? I'm still getting only 0xFF and 0x00 from it.


LOL! I think I was using your library! Let check.


Yup...I'm using your code.  Put a scope on the SETP pin and see what the signal looks like.  You should see nice clean 100ms pulses.


This is what I'm getting when scoping SETP. Does it look similar to your?


Yup, that's what I see also.  You'll see an inverted signal of that on the other side of that capacitor as well.

Go Up