Weird magnetometer values
#1
While reading the data from the magnetometer I have noticed weird/inconsistent values between a BH edition and CE edition.

Weird: Laying the phone on a table and turning it 360 degrees I would've expected the reported values to be in an interval [-MAX, MAX]
But as it turns out the values never cross 0.
I assume I'm picking up magnetic fields induced by flowing currents inside the pinephone itself?

Inconsistent: Doing the same kind of measurements in the same environment (same room, same position on the table) I get different readings for the v1.1 and the v1.2 phones.
I assume changes in the PCB could be the reason for this discrepancy.

Does anyone have an idea of what might be going wrong here?

See this issue.
If some of you could provide some readouts from the script I linked in the gitlab issue I would be much obliged :)

Background: I thought about making a compass app, but for that I would need to be able to find the north/south pole
#2
Hi!

Good to know that someone else is interested in this. I tried to make a compass app a few weeks ago, and I had this same problem.
My understanding is that smartphone magnetometers must be calibrated on a per-device (per-model?) basis before of 'hard-iron' and 'soft-iron' errors in their measurement of the local magnetic field caused by, as you suggest, components inside the phone (e.g. the speaker).
I found this write-up to be a useful overview, in case you've not already seen it: https://appelsiini.net/2018/calibrate-magnetometer/

The other problem for me was that, as far as I know, the required infrastructure for exposing the magnetometer to desktop applications is not yet in place: the deal-breaker for me was that there is no way to set the sampling_frequency parameter and read the measurements from sysfs within a Flatpak sandbox (e.g. using iio-sensor-proxy, see this issue: https://gitlab.freedesktop.org/hadess/ii...issues/310).

I wasn't quite sure how this should be handled: where this calibration should occur, how it should be exposed to the user etc, and could find very little documentation on how iOS and Android do this. I think I remember reading somewhere that Android downloads the required corrections from the device manufacturer, but I can't seem to find that now. I also remember reading about some accelerometer / gyroscope based calibration methods, but for these to work applications would need access to raw accelerometer data, which presents privacy and security issues (e.g. applications being able to discern passwords from the motion of the device as the password is keyed in). So it's a rather large problem.

Are you finding that the output from each independent phone is consistent? My experiments seemed to show rather different results, even with the same device in the same environment. My suspicion was this might be due to the magnetometer being highly sensitive to tilting the phone around the x-axis

Will be very interesting to collect some data across a wider range of Pinephones.

Here are my measurements:


Code:
# x/y plane
Name:   xmin    x: -2802.27    y: 4123.20   z: 9620.60    length: 10835.56
Name:   xmax    x: -302.80     y: 4138.27   z: 9524.13    length: 10388.75
Name:   ymin    x: -1413.07    y: 2990.67   z: 9529.93    length: 10087.64
Name:   ymax    x: -1567.20    y: 5338.53   z: 9590.67    length: 11087.69
Name:   zmin    x: -338.00     y: 3828.40   z: 9479.00    length: 10228.51
Name:   zmax    x: -2717.73    y: 4546.93   z: 9661.47    length: 11018.38
Global minima/maxima:
xmin -2802.27 xmax -302.80 ymin 2990.67 ymax 5338.53 zmin 9479.00 zmax 9661.47

# y/z plane
Name:   xmin    x: -2812.00    y: 3180.40   z: 15048.87   length: 15636.20
Name:   xmax    x: -2397.07    y: 3781.07   z: 9513.33    length: 10514.08
Name:   ymin    x: -2656.67    y: 1377.07   z: 12491.73   length: 12845.14
Name:   ymax    x: -2725.60    y: 7144.00   z: 12698.20   length: 14822.61
Name:   zmin    x: -2397.07    y: 3781.07   z: 9513.33    length: 10514.08
Name:   zmax    x: -2746.13    y: 4196.40   z: 15287.93   length: 16089.50
Global minima/maxima:
xmin -2812.00 xmax -2397.07 ymin 1377.07 ymax 7144.00 zmin 9513.33 zmax 15287.93

# z/x plane
Name:   xmin    x: -4849.87    y: 4144.40   z: 12575.93   length: 14101.47
Name:   xmax    x: 1688.13     y: 3943.07   z: 12336.13   length: 13060.54
Name:   ymin    x: -2746.27    y: 3737.87   z: 9621.40    length: 10681.06
Name:   ymax    x: -3903.60    y: 4235.07   z: 10374.47   length: 11866.06
Name:   zmin    x: -1763.73    y: 4138.40   z: 9349.20    length: 10375.19
Name:   zmax    x: -1364.80    y: 4194.40   z: 15432.20   length: 16050.19
Global minima/maxima:
xmin -4849.87 xmax 1688.13 ymin 3737.87 ymax 4235.07 zmin 9349.20 zmax 15432.20
#3
Thanks for the reply and the measurements.
The links also do look very interesting!

To answer your last question: I believe the readings are consistent within a device (just checked with the BH).
Although I have to say that in general the values are kinda jumpy (which is why I made the script using running averages) and overall the sensor appears to be pretty sensitive. I get changes of a few 100 if I move the mouse closer to the phone (?).

EDIT:
When I thought about how to make the measurements I made it more complicated than it needs to be (separate rotations and using a "reference orientation").
Just "waving" the phone randomly makes a lot of sense actually and the "soft iron" corrected plot is a lot what you would expect to measure (basically a sphere).

As for the calibration: Currently, I think we would need to calibrate each device independently and save the calibration data (the weighted/scaled offsets) somewhere.
It's a bit hacky but I would've read the sensor values directly from /sys.
From what I understood iio-sensor-proxy does currently not work, because only magnetometers which have a "in_rot_from_north_magnetic_tilt_comp" entry in sysfs are supported.

If I understand correctly there would be 2 possible ways to fix this. Either fix the driver to include the entry (including "online" calibration - otherwise we can't possible know what to put in "in_rot_from_north_magnetic_tilt_comp") or do the calibration in iio-sensor-proxy and support polling/non calibrated magnetometers.
#4
After reading the blogpost I realized that I don't need some of the data it was capturing
and allowed it to be a bit simpler.

Could you rerun the script (and turn the phone around a bit - don't need the independent rotations now)?

Thanks in advance.

And as this was your forum post: Welcome ;)
#5
Sure, no problem at all. Here are the results with the new script:

Code:
Starting measurements. Press Ctrl-C to quit
x -1668.26 y -318.32 z 2896.34      ^C
Offsets: x -1779.0 y 4310.0 z 12712.0
Weights: x 0.9473381294964028 y 1.0268247036805989 z 1.030359937402191
Finished
Global minima/maxima:
xmin -5254.00 xmax 1696.00 ymin 1104.00 ymax 7516.00 zmin 9517.00 zmax 15907.00
#6
Thanks a lot.
I have included your measurements into the gitlab issue.
One question: Are you on BH or on the CE?

So far the values do vary quite a lot between each device so I guess calibration will need to be performed per device.
I will have a look to see if I can implement something for iio-sensor-proxy.
#7
Should have said, sorry. I'm on the CE.
Good luck working with iio-sensor-proxy! I'd love to help but unfortunately I don't know enough about the IIO subsystem or the kernel in general.
#8
How much variation do you expect between runs? This is for a BH:

mobian@mobian:/sys/bus/iio/devices/iio:device3$ cat sampling_frequency
80
mobian@mobian:/sys/bus/iio/devices/iio:device3$ python3 ~/src/magnetometer_test/magnetometer.py
Starting measurements. Press Ctrl-C to quit
x 502.22 y 72.19 z -2621.09 ^C
Offsets: x -5566.0 y -2614.0 z -885.0
Weights: x 0.9695375849222003 y 1.0616750659947205 z 0.9740202553940995
Finished
Global minima/maxima:
xmin -8608.00 xmax -2524.00 ymin -5392.00 ymax 164.00 zmin -3913.00 zmax 2143.00
mobian@mobian:/sys/bus/iio/devices/iio:device3$ python3 ~/src/magnetometer_test/magnetometer.py
Starting measurements. Press Ctrl-C to quit
x 573.87 y -1594.59 z -2108.91 ^C
Offsets: x -5616.0 y -2810.0 z -957.5
Weights: x 0.9826456049860305 y 1.0367913832199547 z 0.9824872414719312
Finished
Global minima/maxima:
xmin -8718.00 xmax -2514.00 ymin -5750.00 ymax 130.00 zmin -4060.00 zmax 2145.00

An interesting 'soft iron' element in the phone is the battery - I wonder if they vary enough to need recalibration on battery change?
#9
(07-27-2020, 11:31 AM)migmatite Wrote: Should have said, sorry. I'm on the CE.
Good luck working with iio-sensor-proxy! I'd love to help but unfortunately I don't know enough about the IIO subsystem or the kernel in general.
I also don't know much about the IIO subsystem, basically starting from zero :)
But: Learning is fun! :P

(07-27-2020, 12:54 PM)wibble Wrote: How much variation do you expect between runs?

<snip>

An interesting 'soft iron' element in the phone is the battery - I wonder if they vary enough to need recalibration on battery change?

About the variation between runs: Not sure. For me it seems to be within a 10% range (just estimating).
Mh need to investigate the effect of different battery charge levels.
Thanks for posting your results and the food for thought!
#10
(07-28-2020, 07:53 AM)devrtz Wrote: Mh need to investigate the effect of different battery charge levels.
I was thinking of when you swap the battery for a different one, not at different states of charge for the same battery. I noticed the stock battery was magnetic when looking at magnets as a catch for a flip cover, or as a way of holding docked things to the back. it's the first time I've noticed a phone battery being significantly magnetic, and a quick run round a few other phone batteries shows they aren't. I don't have a replacement Samsung-compatible battery to try.


Possibly Related Threads…
Thread Author Replies Views Last Post
  How to apply thermal zones values jojuma 3 2,557 04-13-2022, 12:15 PM
Last Post: Fish

Forum Jump:


Users browsing this thread: 1 Guest(s)