I am developing iOS app with compass functionality. I have tried to use CMMagnetometerData
updates which give uncalibrated, but normal results.
After that I tried to get CMDeviceMotion
updates which turned out to give always zero magnetic field with CMMagneticFieldCalibrationAccuracyUncalibrated
accuracy. The only device I have is an iPad, so can't test on others.
May be field is zero because sensor is not calibrated, but I could not find any way to perform calibration.
How to fix that?
UPDATE:
Here is suggested to use startDeviceMotionUpdatesUsingReferenceFrame:toQueue:withHandler:
, however it didn't work for me.
Here is suggested to set showsDeviceMovementDisplay
to true
. However it didn't work either, calibration windows is just not popping up.
Finally, SOLVED. According to my observations:
1) Use startDeviceMotionUpdatesUsingReferenceFrame:toQueue:withHandler:
with referenceFrame
NOT equal to allZeros
or XArbitraryZVertical
.
2) Set showsDeviceMovementDisplay
to true
.
After few zero-value updates with accuracy CMMagneticFieldCalibrationAccuracyUncalibrated
it will normalise.
CODE:
...
motionManager.deviceMotionUpdateInterval = 0.05
motionManager.showsDeviceMovementDisplay = true
motionManager.startDeviceMotionUpdatesUsingReferenceFrame(CMAttitudeReferenceFrame.XArbitraryCorrectedZVertical, toQueue: NSOperationQueue.mainQueue(), withHandler:handleUpdate)
...
private func handleUpdate(data: CMDeviceMotion!, error: NSError!) {
if data != nil {
let field = data.magneticField.field
println("\(field.x), \(field.y), \(field.z)")
}
}
Finally, according to my own observations:
1) Use startDeviceMotionUpdatesUsingReferenceFrame:toQueue:withHandler:
with referenceFrame
NOT equal to allZeros
or XArbitraryZVertical
.
2) Set showsDeviceMovementDisplay
to true
.
After few zero-value updates with accuracy CMMagneticFieldCalibrationAccuracyUncalibrated
it will normalise.