Quickstart: Determining pitch, roll, and yaw with the inclinometer (C#)

You can use the inclinometer to determine pitch, roll, and yaw with an app written in C#.

Some 3-D game apps require an inclinometer as an input device. One common example is the flight simulator, which maps the three axes of the inclinometer (X, Y, and Z) to the elevator, aileron, and rudder inputs of the aircraft.

Roadmap: How does this topic relate to others? See: Roadmap for Windows Runtime apps using C# or Visual Basic.

Objective: After completing this quickstart you will understand how to use the inclinometer to detect changes in movement.

Prerequisites

You should be familiar with XAML, Visual C#, and events.

The device or emulator that you're using must support an inclinometer.

Time to complete: 20 minutes.

Instructions

1. Open Microsoft Visual Studio

Open an instance of Microsoft Visual Studio.

2. Create a new project

Create a new project, choosing a Blank App from the Visual C#/Store Apps project types.

3. Replace the C# code

Open your project's MainPage.xaml.cs file and replace the existing code with the following.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

using Windows.UI.Core;
using Windows.Devices.Sensors;


namespace App1
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        private Inclinometer _inclinometer;

        // This event handler writes the current inclinometer reading to 
        // the three text blocks on the app's main page.

        private async void ReadingChanged(object sender, InclinometerReadingChangedEventArgs e)
        {
            await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                InclinometerReading reading = e.Reading;
                txtPitch.Text = String.Format("{0,5:0.00}", reading.PitchDegrees);
                txtRoll.Text = String.Format("{0,5:0.00}", reading.RollDegrees);
                txtYaw.Text = String.Format("{0,5:0.00}", reading.YawDegrees);
            });
        }

        public MainPage()
        {
            this.InitializeComponent();
            _inclinometer = Inclinometer.GetDefault();
 

            if (_inclinometer != null)
            {
                // Establish the report interval for all scenarios
                uint minReportInterval = _inclinometer.MinimumReportInterval;
                uint reportInterval = minReportInterval > 16 ? minReportInterval : 16;
                _inclinometer.ReportInterval = reportInterval;

                // Establish the event handler
                _inclinometer.ReadingChanged += new TypedEventHandler<Inclinometer, InclinometerReadingChangedEventArgs>(ReadingChanged);
            }
        }
    }
}

You'll need to rename the namespace in the previous snippet with the name you gave your project. For example, if you created a project named InclinometerCS, you'd replace namespace App1 with namespace InclinometerCS.

4. Replace the XAML code

Open the file MainPage.xaml and replace the original contents with the following XML.

<Page
    x:Class="App1.MainPage"
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App1"
    xmlns:d="https://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid x:Name="LayoutRoot" Background="#FF0C0C0C">
        <TextBlock HorizontalAlignment="Left" Height="21" Margin="0,8,0,0" TextWrapping="Wrap" Text="Pitch: " VerticalAlignment="Top" Width="45" Foreground="#FFF9F4F4"/>
        <TextBlock x:Name="txtPitch" HorizontalAlignment="Left" Height="21" Margin="59,8,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Width="71" Foreground="#FFFDF9F9"/>
        <TextBlock HorizontalAlignment="Left" Height="23" Margin="0,29,0,0" TextWrapping="Wrap" Text="Roll:" VerticalAlignment="Top" Width="55" Foreground="#FFF7F1F1"/>
        <TextBlock x:Name="txtRoll" HorizontalAlignment="Left" Height="23" Margin="59,29,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Width="50" Foreground="#FFFCF9F9"/>
        <TextBlock HorizontalAlignment="Left" Height="19" Margin="0,56,0,0" TextWrapping="Wrap" Text="Yaw:" VerticalAlignment="Top" Width="55" Foreground="#FFF7F3F3"/>
        <TextBlock x:Name="txtYaw" HorizontalAlignment="Left" Height="19" Margin="55,56,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Width="54" Foreground="#FFF6F2F2"/>

    </Grid>
</Page>

You'll need to replace the first part of the class name in the previous snippet with the namespace of your app. For example, if you created a project named InclinometerCS, you'd replace x:Class="App1.MainPage" with x:Class="InclinometerCS.MainPage". You should also replace xmlns:local="using:App1" with xmlns:local="using:InclinometerCS".

5. Build, deploy and run the app

Press F5 or select Debug > Start Debugging to build, deploy, and run the app.

Once the app is running, you can change the accelerometer values by moving the device or using the emulator tools.

6. Stop the app

  1. Press ALT+Tab to return to Visual Studio.
  2. Press Shift+F5 or select Debug > Stop Debugging to stop the app.

Summary

The previous example demonstrates how little code you'll need to write in order to integrate inclinometer input in your app.

The app establishes a connection with the default inclinometer in the MainPage method.

_inclinometer = Inclinometer.GetDefault();

The app establishes the report interval within the MainPage method. This code retrieves the minimum interval supported by the device and compares it to a requested interval of 16 milliseconds (which approximates a 60-Hz refresh rate). If the minimum supported interval is greater than the requested interval, the code sets the value to the minimum. Otherwise, it sets the value to the requested interval.

uint minReportInterval = _accelerometer.MinimumReportInterval;
uint reportInterval = minReportInterval > 16 ? minReportInterval : 16;
_accelerometer.ReportInterval = reportInterval;

The new inclinometer data is captured in the ReadingChanged method. Each time the sensor driver receives new data from the sensor, it passes the values to your app using this event handler. The app registers this event handler on the following line.

_inclinometer.ReadingChanged += new TypedEventHandler<Inclinometer, 
InclinometerReadingChangedEventArgs>(ReadingChanged);

These new values are written to the TextBlocks found in the project's XAML.

<TextBlock HorizontalAlignment="Left" Height="21" Margin="0,8,0,0" TextWrapping="Wrap" Text="Pitch: " VerticalAlignment="Top" Width="45" Foreground="#FFF9F4F4"/>
 <TextBlock x:Name="txtPitch" HorizontalAlignment="Left" Height="21" Margin="59,8,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Width="71" Foreground="#FFFDF9F9"/>
 <TextBlock HorizontalAlignment="Left" Height="23" Margin="0,29,0,0" TextWrapping="Wrap" Text="Roll:" VerticalAlignment="Top" Width="55" Foreground="#FFF7F1F1"/>
 <TextBlock x:Name="txtRoll" HorizontalAlignment="Left" Height="23" Margin="59,29,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Width="50" Foreground="#FFFCF9F9"/>
 <TextBlock HorizontalAlignment="Left" Height="19" Margin="0,56,0,0" TextWrapping="Wrap" Text="Yaw:" VerticalAlignment="Top" Width="55" Foreground="#FFF7F3F3"/>
 <TextBlock x:Name="txtYaw" HorizontalAlignment="Left" Height="19" Margin="55,56,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Width="54" Foreground="#FFF6F2F2"/>

Inclinometer class

Inclinometer Sample

Roadmap for creating apps using C#, C++, or VB