Magnetometer does not work

Bug #928360 reported by Thomas Espersson
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Fix Released
Kalle Vahlman

Bug Description

Issues reported by David KOSTKEVICIUS (STE):

Follow instructions on igloo web site to activate magnetometer

The MEMS kernel driver now continously prints magnetometer output

Problem 1:
According to the data sheet the output should be 16 bit values. The output consists of 32 bit values (8 charachters hex). Why? Neither I, nor the Snowball team, understand what these values mean or how they correlate to the magnetic field.

Problem 2:
The output does not change for some axis when the Snowball is rotated

Problem 3:
Starting an Android compass framework does not produce correct output (Tested by Benn Pörscke)

Revision history for this message
Thomas Espersson (espersson) wrote :

This was tested on the Ubuntu and Android ICS releases

Changed in igloocommunity:
importance: Undecided → High
Revision history for this message
Kalle Vahlman (kvahlman) wrote :

First of all, the sensors are not enabled in any of the u8500_android_defconfigs of IK stable branches, so if Benn didn't enable that before testing it's not really surprising that there was no or incorrect data.

Secondly, for me using the steps at the magnetometer page does work, the values react to changing the orientation of the device. Can we get more details about in what configuration/situation the readout does not work?

But let's break the magnetometer operation down:

What it does is measure the ambient magnetic field in Gauss. According to the table at

the reading should be in the ballpark of 300-600 mG depending where on the globe you are, but will of course also vary due to everything around the device, electrical devices (including itself), the surrounding material etc.

The readings from the magnetometer will have gain that changes with the measurement range (sensitivity).

The values from the sensor are read from two 8-bit registers which store the 16-bit value in 2's complement form:;a=blob;f=drivers/hwmon/lsm303dlh_m.c;hb=refs/heads/st-mems-sensors#l323

and are then indeed printed out as 32-bit hexadecimal values:;a=blob;f=drivers/hwmon/lsm303dlh_m.c;hb=refs/heads/st-mems-sensors#l405

As for the reasoning for the 32-bit vs 16-bit representation, I have no idea. It seems unnecessary, though doesn't really hurt either. Here's an example output with default settings and the device "facing down" (green leds towards the desk), which should mean that the z-axis is pointing roughly towards the center of the earth:

     14b:ffffff6d: 213

So that's x:y:z, from which we see that z-axis has the value 0x213 or 531G. This obviously is few magnitudes greater than expected, but that's because of the gain. For the default settings, the gain for z-axis is 950 so we can calculate:

 513G / 950 = 0.54G = 540mG

which seems to fit nicely to the value suggested by the wikipedia page for the latitude of roughly 61° which is where the values were recorded.

The y value above is ffffff6d which indicates that it is negative. As the datasheet states, the values are stored in two's complement form which uses the most significant bit to express negativity:

And finally, here's the libsensors implementation for GB:;a=blob;f=sensors.c;hb=refs/heads/igloo-dev#l340

It converts the values to µTesla which is what the Android API uses (1G == 100µT).

I hope this helps making sense of the data, I will add the explanation to the wiki page too.

Revision history for this message
Thomas Espersson (espersson) wrote :

A patch is needed to make sure that the sensors are enabled default.

Changed in igloocommunity:
assignee: nobody → Kalle Vahlman (kvahlman)
milestone: none → 2012.02
Revision history for this message
Fredrik Olsson (fredrik-olsson-e) wrote :

After measured the X and Y values rotating the device “facing down”. The values if they are plotted are around two points [X:C8, Y:FA0] and [X:FA0, Y:FA0]. The expected result is a centered circle.

Revision history for this message
Kalle Vahlman (kvahlman) wrote :

I wrote a tool to get the min/max range of the reported values for different axis, and the results indicate that there are some differences:

MAX x: 62.09µT, y: 32.42µT, z: 46.00µT
MIN x: -40.47µT, y: -69.57µT, z: -52.53µT

I'm not sure if this is the cause of the mentioned issues but it seems that the disparity might affect calculations. I'm also not sure if this is expected, but it probably is given that in bearing calculations the accuracy is affected by tilting.

I will try to get a plot of the data as well to see how it pans out.

Revision history for this message
Kalle Vahlman (kvahlman) wrote :

Attaching a plot of X/Y data from the magnetometer (with gain adjustment) from me doing a full 360 degrees rotation while the board rests on the desk "normally", the leds up.

The result seems to match the expectation of an origo-centered circle.

Revision history for this message
Kalle Vahlman (kvahlman) wrote :

Doh, damn that automagic scaling in the plot. It's of course not origo-centered.

I wonder what causes this skew...

Revision history for this message
Patrik Klinger (patrik-klinger) wrote :

Kalle, what hardware did you do this test on?

Revision history for this message
Kalle Vahlman (kvahlman) wrote :

Ah, good point, the data is from a V5 board. I can check with a V10 too, since the chip was upgraded in between those.

Revision history for this message
Fredrik Olsson (fredrik-olsson-e) wrote :

After rotating the board 360 degrees the plot does not look like a circle. See attachment

To get the values from the magnetometer I followed the instructions at

Revision history for this message
Kalle Vahlman (kvahlman) wrote :

Righto, should have thought of the chip change as a first thing. Thanks Patrik for pointing out the obvious :)

This seems to be simply a case of having an inverted y/z axis when compared to the earlier version of the chip. So as a simple work-around one can just swap the data ordering when reading.

On the driver side this seems to have been behind a config option but in fact a patch to make that a runtime check has been today pushed to Igloo kernel. So we should be good in the future wrt this issue.

Changed in igloocommunity:
status: New → Fix Committed
Revision history for this message
Fredrik Olsson (fredrik-olsson-e) wrote :

What do you mean with swap the data ordering when reading?

Revision history for this message
Kalle Vahlman (kvahlman) wrote :

When you take the raw data from the device, use the second value for z axis and third for y. So the axis order is xzy not xyz in the data.

Eg, if you read with

        sscanf(buf, "%8x:%8x:%8x",
          (unsigned int*)&m_data[0],
          (unsigned int*)&m_data[1],
          (unsigned int*)&m_data[2]);

instead do

        sscanf(buf, "%8x:%8x:%8x",
          (unsigned int*)&m_data[0],
          (unsigned int*)&m_data[2],
          (unsigned int*)&m_data[1]);

and then continue as usual.

Changed in igloocommunity:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.