Calibrating the Compass

,

Over time, the compass sensor can become inaccurate, and this is exacerbated if it is exposed to magnetic fields. Calibration of the device is performed by the user, by moving the phone repeatedly in a figure-eight pattern (see Figure 16.6). The Compass.Calibrate event is raised whenever the OS detects that the heading accuracy is worse than 20 degrees, at which point it is your app’s responsibility to display a dialog to the user with instructions on how to perform the calibration motion.

Image

FIGURE 16.6 CompassView page showing calibration instructions.

The CompassView page includes a StackPanel with the calibration UI, consisting of an image with instructions for performing the figure-eight motion (see Listing 16.8).

As the user performs the calibration motion, the accuracy level is displayed in a TextBlock that is bound to the viewmodel’s HeadingAccuracy property. When the user is satisfied that she has improved the accuracy of the sensor sufficiently, she taps a done button. The button is bound to the viewmodel’s ToggleCalibrationCommand.

LISTING 16.8. Calibration UI XAML (excerpt from CompassView.xaml)


<StackPanel x:Name="stackPanel_Calibration" Visibility="Collapsed"
            Background="{StaticResource PhoneBackgroundBrush}">
    <Image Source="/Sensors/Compass/Images/CalibrateCompass.png"
           HorizontalAlignment="Center"/>
    <TextBlock TextWrapping="Wrap" TextAlignment="Center">
        The compass on your device needs to be calibrated.
        Hold the device in front of you and sweep it through
        a figure eight pattern as shown, until the calibration is complete.
    </TextBlock>
    <StackPanel Orientation="Horizontal" Margin="0,10"
                HorizontalAlignment="Center">
        <TextBlock Text="accuracy is "
                   Style="{StaticResource LabelTextStyle}" />
        <TextBlock Text="{Binding HeadingAccuracy, StringFormat={0}°}"
                   Style="{StaticResource PhoneTextAccentStyle}"
                   FontSize="{StaticResource PhoneFontSizeLarge}"/>
   </StackPanel>
    <Button Content="done"
            Command="{Binding ToggleCalibrationCommand}"
            HorizontalAlignment="Center" />
</StackPanel>


The Calibrate handler in the CompassViewModel sets its VisualState property to a custom enum value Calibrating, as shown:

void HandleCompassCalibrate(object sender, CalibrationEventArgs e)
{
    VisualState = VisualStateValue.Calibrating;
}

The visual state of the page is controlled using a custom VisualStateUtility.VisualState attached property, presented earlier in this chapter. The attached property is bound to the VisualState property of viewmodel, as shown:

<phone:PhoneApplicationPage
    ...
    u:VisualStateUtility.VisualState="{Binding VisualState}">
    ...
</phone:PhoneApplicationPage>

The Calibrating visual state affects the Visibility property of the calibration StackPanel, as shown:

<VisualState x:Name="Calibrating">
    <Storyboard>
        <ObjectAnimationUsingKeyFrames Duration="0"
                    Storyboard.TargetProperty="Visibility"
                    Storyboard.TargetName="stackPanel_Calibration">
            <DiscreteObjectKeyFrame KeyTime="0">
                <DiscreteObjectKeyFrame.Value>
                    <Visibility>Visible</Visibility>
                </DiscreteObjectKeyFrame.Value>
            </DiscreteObjectKeyFrame>
        </ObjectAnimationUsingKeyFrames>
    </Storyboard>
</VisualState>

The ToggleCalibrationCommand is initialized in the viewmodel constructor. When executed it changes the VisualState from Calibrating to NotCalibrating, and vice versa. This hides the calibration UI when the user taps the done button.

public CompassViewModel() : base("compass")
{
    toggleCalibrationCommand
                       = new DelegateCommand(obj => ToggleCalibration());
}

void ToggleCalibration()
{
    VisualState = VisualState == VisualStateValue.Calibrating
                    ? VisualStateValue.NotCalibrating
                    : VisualStateValue.Calibrating;
}

Figure 16.6 shows the calibration UI after having performed the calibration, bringing the accuracy to five degrees.

The compass sensor enables you to easily add heading information to your app, and to build specialized apps that can detect changes in magnetic forces around the device.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.111.30