Search code examples
iphoneobjective-ciosmagnetometer

Why am I getting 0 degrees from magneticField property the whole time?


I'm trying to get the device's declination from the magnetic North in degrees, by relying solely on the device's magnetometer. This is the code I've written but I just get 0 degrees.. What am I doing wrong ?

CMMotionManager *motionManager;

motionManager = [[CMMotionManager alloc] init];

[motionManager startDeviceMotionUpdates];

CMDeviceMotion *deviceMotion;

deviceMotion = [[CMDeviceMotion alloc] init];

while(!self.stopButtonPressed)
{
    double x = motionManager.deviceMotion.magneticField.field.x;

    double y = motionManager.deviceMotion.magneticField.field.y;

    double degrees = asin(y/sqrt(pow(x, 2.0) + pow(y, 2.0))) * 180.0 / M_PI ;

    int degreesRounded = (int)degrees;

    NSLog(@"Degrees : %i", degreesRounded);
}

Solution

  • It is likely that the simulator doesn't return normal values for these methods, so you will need to test on a real device.

    The CLLocationManager's method, didUpdateHeading: doesn't work on the simulator, so you are probably experiencing something similar here.

    Edit:

    From the docs:

    "The latest sample of device-motion data. (read-only)

    @property(readonly) CMDeviceMotion *deviceMotion

    Discussion If no device-motion data is available, the value of this property is nil. An application that is receiving device-motion data after calling startDeviceMotionUpdates periodically checks the value of this property and processes the device-motion data."

    Check to see if that property of your motion manager is nil. If it is, then you would get 0 for the magnetic field property.

    Edit 2:

    Instead of using startDeviceMotionUpdates, you should be using startMagnetometerUpdatesToQueue:. The docs say this:

    "Magnetometer. Set the magnetometerUpdateInterval property to specify an update interval. Call the startMagnetometerUpdatesToQueue:withHandler: method, passing a block of type CMMagnetometerHandler. Magnetic-field data is passed into the block as CMMagnetometerData objects."

    Docs are here.