Interpreting outputs of digital compass -

Looking for a little guidance and expertise on using the QMC5883 digital compasses. My interpretation of the datasheet () is that the unit returns the magnitude of the sensed field, in the x, y and z directions. I assumed then, that the squareroot of the sums of the squares of these values would represent the magnitude of the ambient B field.

In the field, I expected that when holding the unit approximately in the same position, the magnitude to be generally invariant to rotation - however that appears to be absolutely not the case: in-place rotation of the sensor can produce variations in the computed magnitude over an enormous range, of around four thousand (the unit is 18bit), while the noise with the unit approximately stationary is around 50.

I've been running barebones code (once from GitHub - dthain/QMC5883L: Driver for QMC5883L chip found in many GY-271 boards., and a different library from GitHub - mprograms/QMC5883LCompass: QMC5883L Compass is a Arduino library for using QMC5583L series chip boards as a compass. Supports: - Getting values of XYZ axis. - Calculating Azimuth. - Getting 16 point Azimuth bearing direction (0 - 15). - Getting 16 point Azimuth bearing Names (N, NNE, NE, ENE, E, ESE, SE, SSE, S, SSW, SW, WSW, W, WNW, NW, NNW) - Smoothing of XYZ readings via rolling averaging and min / max removal. - Optional chipset modes), and an example code showing calls to the library is shown below.

#include <Wire.h>
#include <MechaQMC5883.h>

MechaQMC5883 qmc;

void setup() {
  Wire.begin();
  Serial.begin(9600);
  qmc.init();
  qmc.setMode(Mode_Continuous,ODR_200Hz,RNG_2G,OSR_256);
}

void loop() {
  int x,y,z;
  qmc.read(&x,&y,&z);

  Serial.print(x);
  Serial.print(",");
  Serial.print(y);
  Serial.print(",");
  Serial.print(z);
  Serial.print(",");
  Serial.print(sqrt(pow(x,2)+pow(y,2)+pow(z,2)));
  Serial.println();
  delay(10);
}

Is anyone able to correct my understanding of the way this unit works? I assumed I could compute the magnitude of the ambient magnetic field with the square root of the sums of the squares of the x, y and z components, but this appears to not be the case. Does anyone have a suggestion on how I SHOULD compute the magnitude of the B field, with this kind of unit?

Many thanks

Apologies, it's 16 bit.. I dont know why I put 18 bit.

And a component datasheet is found at QMC5883L Datasheet PDF - Datasheet4U.com

Magnetometers generally don't work properly out of the box and must be calibrated to use as a compass. At the very least, one usually has to remove a large offset from each axis. Note: only the relative values of the horizontal components of the Earth's magnetic field are required for orientation, so don't worry about absolute magnitude.

Calibration options (same procedure for accelerometers and magnetometers)
Simple calibration procedure

Best calibration procedure.

Sensitive magnetometers as used for a compass have a soft iron disk to magnify the magnetic field.
This disk can be accidentally magnetized if brought too near to powerful magnets, then the device
needs to be demagnetized.

Even so the device needs calibrating to subtract the effects of soft and hard magnetic materials on the same
PCB (SMT resistors and caps may contain steel endcaps for instance), and in the housing (screws/bolts).

Soft materials distort the earth's field, hard materials hold permanent magnetism.

Calibration seeks to determine both effects and compensate, which is why its complicated and tricky to do,
but needs doing.

Many thanks to you both.
I think one of the libraries I was using to self-calibrate wasnt calibrating the device in Z, and I do need that. In either case, calibration makes a huge difference as you both suggest.