I am trying to get the magnetic field data from my iphone 6 by using CoreMotion.
I had no problems accessing the raw data with the following code:
if available {
motionMangager.magnetometerUpdateInterval = updateInterval
motionMangager.startMagnetometerUpdatesToQueue(queue, withHandler: {
(data, error: NSError!) -> Void in
println("x: \(data.magneticField.x), y: \(data.magneticField.y), z: \(data.magneticField.z)")
})
}
BUT: I need the derived data by using an device motion instance.
So I did the following:
if motionMangager.deviceMotionAvailable {
motionMangager.magnetometerUpdateInterval = updateInterval
motionMangager.startDeviceMotionUpdatesUsingReferenceFrame(CMAttitudeReferenceFrameXArbitraryZVertical, toQueue: queue, withHandler: {
(deviceMotion: CMDeviceMotion!, error: NSError!) -> Void in
// If no device-motion data is available, the value of this property is nil.
if let motion = deviceMotion {
println(motion)
var accuracy = motion.magneticField.accuracy
var x = motion.magneticField.field.x
var y = motion.magneticField.field.y
var z = motion.magneticField.field.z
println("accuracy: \(accuracy.value), x: \(x), y: \(y), z: \(z)")
}
else {
println("Device motion is nil.")
}
})
}
And here is the problem:
I am always getting zero for the field coordinates x, y and z. The accuracy as well is -1. According to the Apple Documentation an accuracy of -1 means "CMMagneticFieldCalibrationAccuracyUncalibrated" means "the device does not have a magnetometer"... But no! It is an iPhone 6...
So what am I doing wrong? I tried all four CMAttitudeReferenceFrame. Please I need help. Any ideas?
Ok.. I solved it.
The reason for the zeros were an uncalibrated magnetometer! But that does not mean that there is no magnetometer like stated in the apple docs. Anyway I did never expected that.
I just needed to add the functionality of compass calibration. And that is fairly easy to add:
(See: https://developer.apple.com/library/ios/documentation/CoreMotion/Reference/CMMotionManager_Class/)
So now it is like: When I am getting zeros and -1 for accuracy than the alert asking for calibration pops up. After a move it vanishes and I am getting proper values.