iOS Question [SOLVED with difficulty] Motion object does not give correct magnetic field values


Well-Known Member
Licensed User
Longtime User
I won't call this a bug - yet.

I've done quite a lot of work with motion sensors in B4A - amongst other things developing a pretty sophisticated sensor fusion engine that works a treat.

I'm starting to port it to B4i and am playing around with the Motion object.

I have taken the sample from:

and have goosed it up a bit to include the magnetometer - very simple stuff (zip at bottom):
'Code module
#Region  Project Attributes
    #ApplicationLabel: B4i Example
    #Version: 1.0.0
    'Orientation possible values: Portrait, LandscapeLeft, LandscapeRight AND PortraitUpsideDown
    #iPhoneOrientations: Portrait
    #iPadOrientations: Portrait

#End Region

Sub Process_Globals
    Public App As Application
    Public NavControl As NavigationController
    Private Page1 As Page
    Private mot As Motion
    Private timer1 As Timer
    Private bbStart, bbStop As BarButton
    Private Label1 As Label
    Private lblAccX As Label
    Private lblAccY As Label
    Private lblAccZ As Label
    Private lblMagX As Label
    Private lblMagY As Label
    Private lblMagZ As Label
    Private lblIntensity As Label
    Private lblAttPitch As Label
    Private lblAttRoll As Label
    Private lblAttYaw As Label
    Private MaxX, MaxY, MaxZ As Double
End Sub

Private Sub Application_Start (Nav As NavigationController)
    NavControl = Nav
    timer1.Initialize("timer1", 100)
    bbStart = Page1.TopRightButtons.Get(0)
    bbStop = Page1.TopRightButtons.Get(1)
End Sub

Sub Page1_BarButtonClick (Tag As String)
    If Tag = "Start" Then
        timer1.Enabled = True
        timer1.Enabled = False
    End If
    bbStart.Enabled = Not(timer1.Enabled)
    bbStop.Enabled = timer1.Enabled
End Sub

Sub Timer1_Tick
    Dim attitude() As Double = mot.GetAttitude
    Dim SFE_raw_accel() As Double = mot.GetUserAcceleration
    Dim SFE_raw_magnet() As Double = mot.GetMagnetometer
    lblAttYaw.Text = "yaw: " & NumberFormat(-attitude(0) * 180 / cPI, 1, 2) & Chr(0xB0)
    lblAttPitch.Text = "pitch: " &  NumberFormat(-attitude(1) * 180 / cPI, 1, 2) & Chr(0xB0)
    lblAttRoll.Text = "roll: " &  NumberFormat(attitude(2) * 180 / cPI, 1, 2) & Chr(0xB0)
    MaxX = Max(MaxX, Abs(SFE_raw_accel(0)))
    MaxY = Max(MaxY, Abs(SFE_raw_accel(1)))
    MaxZ = Max(MaxZ, Abs(SFE_raw_accel(2)))
    lblAccX.Text = "x: " & NumberFormat(SFE_raw_accel(0), 1, 2) & " max (" & NumberFormat(MaxX, 1, 2) & ") G"
    lblAccY.Text = "y: " & NumberFormat(SFE_raw_accel(1), 1, 2) & " max (" & NumberFormat(MaxY, 1, 2) & ") G"
    lblAccZ.Text = "z: " & NumberFormat(SFE_raw_accel(2), 1, 2) & " max (" & NumberFormat(MaxZ, 1, 2) & ") G"

        lblMagX.Text = "X: " & NumberFormat(SFE_raw_magnet(0), 1, 4)
        lblMagY.Text = "Y: " & NumberFormat(SFE_raw_magnet(1), 1, 4)
        lblMagZ.Text = "Z: " & NumberFormat(SFE_raw_magnet(2), 1, 4)

        'Calculate actual magnetic field total intensity
        Private Mag_totalintensity As Float = Sqrt(SFE_raw_magnet(0)*SFE_raw_magnet(0) + SFE_raw_magnet(1)*SFE_raw_magnet(1) + SFE_raw_magnet(2)*SFE_raw_magnet(2))

        lblIntensity.Text = "  Intensity: " & NumberFormat(Mag_totalintensity, 1, 2)

    End Try

End Sub

When I run this I get a screen that looks as follows:


Yet when I run a simple little magnetometer app from iTunes I get:


I believe the iTunes app because part of a diagnostics panel in my B4A app - taken at the same time as the other images (with both phones similarly oriented but well apart), in part shows:


Note the 2 red boxed areas:

The top one is the raw magnetometer values (calibrated for device bias) - they reasonably tally with the iTunes app (see little comparison table at bottom).

The lower boxed area compares measured magnetic intensity and inclination (computed from the raw values) with what would be expected by the NOAA model:

Comparison of raw magnetometer values:

goosed B4i: 59.5 64.5 -101.1 giving total intensity of 133.9
iTunes app: -19.8 17.2 46.6 giving total intensity of 53.5
....B4A app: -16.4 18.5 48.3 giving total intensity of 54.2
........NOAA: expected total intensity of 56.9


    4.4 KB · Views: 227
Last edited:


Well-Known Member
Licensed User
Longtime User
Erel - this is not a duplicate post - I am reporting what looks like a bug in the existing Motion object.
Upvote 0


B4X founder
Staff member
Licensed User
Longtime User
Upvote 0


Well-Known Member
Licensed User
Longtime User

This post is titled:

Motion object does not give correct magnetic field values

It is about a potential bug I think I have found in the stock standard Motion object - it has absolutely nothing to do with the second post aside from the fact they are both about the Motion object.

The other post is titled:

Motion object does not give me what I need

It is about requesting from anyone (probably you in reality) some help to get some extra functionality out of the Motion object which will probably take you 5 minutes to answer - you need to install the zip attached to it and have a close look.

I appreciate you are very busy and this could have been confusing at a quick look but they have nothing to do with one another.

Upvote 0


Well-Known Member
Licensed User
Longtime User

If you are actually implementing the values from this link then you are not doing it correctly in my view.

You should be supplying calibrated values - i.e. with the device bias removed as per:

Calibrated is the same as B4A with TYPE_MAGNETIC_FIELD - what you are supplying is the Android equivalent of TYPE_MAGNETIC_FIELD_UNCALIBRATED (which B4A does not natively support BTW).

This could conceivably explain why B4i Motion object results are so out of whack with everything else.
Last edited:
Upvote 0


B4X founder
Staff member
Licensed User
Longtime User
which B4A does not natively support BTW
Lets stay focused. PhoneSensors natively supports all sensors. Only the constants supported by all platforms are listed. Developers can use any other constant value they like.

If you are actually implementing the values from this link then you are not doing it correctly in my view.
As I wrote these are the values returned by GetMagnetometer. It will not be changed.

If you want to access the calibrated values then create a new thread asking how to access the calibrated values. It should be quite simple.
Upvote 0