fake QMC5883l - calibration offsets between thousands and hundreds

I have a magnetic compass which has written HMC5883l but is actually QMC.
**First->**I am trying to calibrate this compass and the offsets i am getting are very high in [1206 - 400] range both for x and y axis.
Second-> after calibrating when i run the magnetic degrees function and rotate the object which has compass on it the degree reading is never between [20-199]. I am rotating in a full 360. i am getting 1-20 degree output but after that the reading jumps to 300.
I have attached both of the code files calibration and compass.
Can anyone help me?

compass.txt (1011 Bytes)

calibrate_compass.txt (873 Bytes)

I see your problem. To calibrate the magnetometer, you should also print out the Z axis. Then you can do an elliptical estimation to determine your hard-iron and soft iron distortions.

Read this:

Try do your calibrations using this method. Also, don't forget to convert your units into nT to ensure these steps work.

If you want, you can print out your x,y,z measurements in nT, copy the serial monitor and post it as a Text data. I will show you then what I mean.

the offsets i am getting are very high in [1206 - 400] range both for x and y axis.

The offset values don't matter, as long as after calibration, the (x,y) values trace out a nice circle centered on the origin when you rotate the compass through a full circle.

Your results might look something like this, before and after, and hopefully even better:

The 3D calibration method linked in reply #1 is by far the best.

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

The free IMU software recommended in this blog , I couldn’t find the .exe file of it. Can you help me with that.
Thanks Alot.

So, I would strongly recommend you use the Magneto 1.2 software on that tutorial that you are reading.

Here is the link for the download:

Use this link to find you Total intensity (Col: F, Row: MF) to put in the magneto 1.2 software. This is in nT! That is why you really need to make sure that you output nT data.

This value will be inputted in the software as such:

If you want to, you can read this aswell:

Basically this part is important for you:

Serial.print(mx, 10); Serial.print(" "); Serial.print(my, 10); Serial.print(" "); Serial.println(mz, 10);

After this you let the serial monitor run, rotate at all directions and do it for around 5 min for good results. Then just pull out your USB and go to the serial monitor and CTRL-A, CTRL-C and CTRL-V into notepad, save it and finished.

If you are completely lost with everything, you can also use MotionCal:
I used it once aswell, but I do prefer the Magneto 1.2 software.

The offer for you to send me your data is still on the table. I can plot this very quickly for you so that you can visualize your hard-iron and soft-iron distortions. Or if you have MATLAB, I can send you the script, it will plot it and also do the Magnetic calibrations for you. I programmed the Magneto 1.2 code into the MATLAB script because Magneto 1.2 does not give a visual representation of the measurements.

These are the outputs I have got. Thanks alot. <3

I think you did it wrong. You need to rotate it completely. Plus you need to convert your values to nT. Otherwise these values are all false. Please redo the rotations, you need to rotate everywhere not only a flat rotation.

Also, you need to get rid of the timestamp if you want to use the Magneto 1.2.

1 Gauss is 100'000nT.

P.S I know the axis are wrong. I haven't finished since I saw the error anyway.





you really need to make sure that you output nT data.
World Magnetic Model Calculator

Why do you say that?

For a compass, the units of the magnetometer measurements, or the overall scale, are completely irrelevant because the ratios of the axial measurements are used to determine direction.

For best accuracy in the Magneto correction, choose the "norm" of the data so that the diagonal elements of the correction matrix are about 1.

In reply #5, these elements are shown as 0.005742, 0.005782 and 0.007330

@jremington that's a good question and when you ask it then I have to be very careful with the answer. You are definitely the expert in this and if it is wrong, please let me know.

As I understand the calibration process, the hard-iron distortions can be fixed by placing the sphere on the 0-axes.

The soft-iron distortion is the shape of the sphere. The Total Intensity is then a constant and, as you mentioned, won't matter if you need to calculate the heading. However, the magnetic values that you will get are then scaled wrong. The raw magnetic measurements won't make sense. I like to have everything perfectly correct.


Here is a test I did, the first one, I set as just 1 and the second I set at around 48'000.

mA_inv =

   1.0e-04 *

    0.1993    0.0004    0.0036
    0.0004    0.1958   -0.0044
    0.0036   -0.0044    0.2042

mA_inv =

    0.9605    0.0021    0.0173
    0.0021    0.9437   -0.0211
    0.0173   -0.0211    0.9837

To another issue:
If you look at the picture in reply #6, you will see that the sphere is not round. The Z axis has stayed "nearly" constant throughout the measurement. I do not know if the elliptical fitting estimation will therefore be wrong, but I suppose it will.

Also, as i already mentioned, I don't know if the timestamp will be ignored by the software. My MATLAB script ignores it.


However, the magnetic values that you will get are then scaled wrong. The raw magnetic measurements won't make sense.

The units and scale factor of the magnetometer data are of course essential if you are measuring the absolute strengths of magnetic fields.

For 3D orientation and compass applications, the units and scale are irrelevant, as the measurements are always normalized to vector magnitude = 1.

If the Magneto procedure fails to scale the raw measurements ellipsoid to a sphere of radius 1, then the approximation used for the correction has failed. In that case the 3D orientation or compass application will give erroneous results.