iosobjective-cswiftipadmagnetometer

CMDeviceMotion returns 0 values for magnetic field


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)")
    }
}

Solution

  • 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.