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:
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