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);
}
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.