Arduino mega with HCM5883L

Hi Guys!

Recently i bought NEO M8N gps module with integrated HCM5883L compass. It's hard to find real HMC chip, the most are QMC on single compass module. The good news is, if you Buy NEO M8n module with integranted compass it will be real HMC chip on it.


The most of this modules works with my program prefectly. But nowaday i get some that not work with my code. I am debugging it, and find out, that the module works, got 0x1E i2C address (that meant its HMC) but its measuring wrong. If i do a 360degree turn, it will return only 5, 94,272 values.... I figured out, that its beacuse the wrong calibration.

I used jarzebski's HCM5883L libraray. If i upload the calibration program there are measured numbers at the X axis, but nothing just 0 in Y axis... If i manually offset the Y axis with a random number (100, or 200) then i can read headingdeegrees perfectly! But in this way i cannot calibrate the compass :frowning:

I got 5 piece from this type of GPS+Compass module, and the same problem on all of them.

No measure from Y axis....

How can i solve this, how can i get readings from Y axis?
Maybe the Y axis regitser address different on this model?

EDIT: with the ADAFRUIT libraray the compass works, but i cannot use this library (there is no offset, etc) but its a good starting point to see, how it address the registers...

Do the magnetometer calibration independently, following the tutorials linked below, and add the scaling and offset subtraction into any code you like.

Advanced procedure: Tutorial: How to calibrate a compass (and accelerometer) with Arduino | Underwater Arduino Data Loggers

Simpler approach: Simple Magnetic Calibration | Adafruit SensorLab - Magnetometer Calibration | Adafruit Learning System

Or: How to Calibrate a Magnetometer?

Thank you for the answer!

Sadly its a running project. There was many device sold previously with the use of jarzebski's HCM5883L libraray. I don't want to change, rewrite code becouse this odd working compass. I want unified solution, that i can use with the good working compass, and the odd working compass...

Yesterday i did it to work: in my code i repalce the jarzebski's compass code to Adafruit one, wroted in a calibration function. Now it's working, but now i have two program version. One for each compass type.

I want to know what's the different between this two libraray...
This and This one...

I think it's becaouse the wrong register addressess. Maybe the odd working compass got different register address... Or uses 7bit vs 8bit addresses. But as i see both libraray uses the same register addresses. Dunno whats the different. Why it's work with Adafruit libraray, and why its isnt working with the
jarzebski's, that i used well before...

Maybe the working compass HMC5883L, the not working HMC5883 (without "L")? Is there any differencies?

Hi @jan5650

Honeywell discontinued the HMC5883L awhile ago around 2015/2016. Shortly after, the chip continued to be manufactured as the QMC5883L revsion A by QST.

The QMC5883L revision A functioned identically to the HMC5883L, except that there was a hardware bug in the silicon, which meant (and I kid you not) that the status register didn't work. It's still possible to work with the chip, but some libraries written for the HMC5883L that (not unreasonably) check the status register, require a workaround.

Just to add to the confusion QST then released the QMC5883L revision B, that's internally a completely different device from the HMC5883L/QMC5883L revision A. Revision B operates in accordance with QST's QMC5883L datasheet.

The situation is also complicated by the fact that some vendors still market devices sold with the QMC5883L as the HMC5883L.

A more detailed explanation is provided here:

Yes, i heard from that. I am sure, that this is not a QMC B version, because its have totally different address. Both compass (the working one, and the bad) are answer at "0x1E".

QMC5883 Revision A is new to me. Maybe it will be the key to succes... You wrote:

status register didn't work. It's still possible to work with the chip, but some libraries written for the HMC5883L that (not unreasonably) check the status register, require a workaround.

Maybe thats happening in my case... I can query X Axis, but without a working status register the libraray cannot query the Y axis... It can be?

And the most important quest: how can i workaround this?

Adafruit's library uses different register addresses or why its work?

Ohhh, and one more thing: if i remember good, the chip number:


The QMC5883L revision A devices had the chip number DA5883, whereas the revision B had DB5883.

If your magnetometer's registers respond to the I2C address 0x1E, then it's closer to the HMC5883L, but the library might need to add a delay before reading the results register, instead of polling the status register.

If your magnetometer responds to the I2C address 0x0D then it will require the QMC5883L library instead.

The problem is that changes to this device are undocumented by QST.

Okey, so i got QMC that act like/close to HMC at the most, only the status register won't work...

1. Question
You mentioned, that i need to disable status register acces. I think you mean i need to uncomment the acces line in the libraray itself. But wich line i need to uncomment, can you help me?


2. Question
My sketch already got delay between the measurements like this:

unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interval) {
      previousMillis = currentMillis;
      Vector norm = compass.readNormalize();

Where interval = 500 ms

So if i uncomment the status register access line in the library, and keep this delay methond, then it will be fine?

@jan5650 It looks like the jarzebski library by default runs the HMC5883L in continous mode at 15Hz (66ms period) and doesn't attempt to time the reading of the X, Y, Z axes data registers to status register's RDY flag bit going high. Acutally, jazebski's library doesn't use the status register at all.

In this case, the library should work with a QMC5883L revision A as is, since your 500ms time interval code far exceeds the 66ms continuous sample rate.

Did you see any different between jazebski's and Adafruit's libraray?
Adafruit's version work, jazebski's version not.

I used them both on the same own writed sketch...

I can't see anything obvious and without debugging the jazebski library it's difficult to say what the issue is.