How to get data from the accelerometer sensor for Windows Phone 8

[ This article is for Windows Phone 8 developers. If you’re developing for Windows 10, see the latest documentation. ]

 

This topic walks you through creating an accelerometer app that gives you a numeric display and a graphical representation of the accelerometer data.

Note

In addition to the APIs described in this topic from the Microsoft.Devices.Sensors namespace, you can also program the phone’s sensors by using the similar classes in the Windows.Devices.Sensors namespace.

This topic contains the following sections.

 

Accelerometer overview

The accelerometer measures the forces applied to the device at a moment in time. These forces can be used to determine in which direction the user is moving the device. The acceleration value is expressed as a 3-dimensional vector representing the acceleration components in the X, Y, and Z axes in gravitational units. The orientation of the acceleration is relative to the device such that -1g is applied in the Z-axis when the device is face up on a level table and -1g is applied to the Y-axis when the device is placed perpendicular to the table top.

The accelerometer sensor detects the force of gravity along with any forces resulting from the movement of the phone. The combined motion API, accessed using the Motion class, uses multiple device sensors to separate the gravity vector from the device acceleration and allows you to easily determine the current attitude (yaw, pitch, and roll) of the device.

Creating the accelerometer app

The following steps show you how to create an accelerometer app.

To create an accelerometer app

  1. In Visual Studio, create a new **Windows Phone App ** project. This template is in the Windows Phone category.

  2. This app requires references to the assemblies containing the sensor APIs and the XNA Framework because accelerometer data is passed in the form of an XNA Framework Vector3 object. From the Project menu, click Add Reference…, select Microsoft.Devices.Sensors and Microsoft.Xna.Framework, and then click OK.

  3. In the MainPage.xaml file, place the following XAML code in the Grid element named “ContentPanel”. This code creates two buttons, one to start acquisition of data from the accelerometer and one to stop it. Also created are three TextBlock elements that will be used to display the numeric readings and three Line elements that will be used to graphically represent the reading data. Finally, this code adds a status TextBlock element that will be used to display the current status of the app.

    <Button Content="Start" Height="72" HorizontalAlignment="Left" Margin="20,10,0,0" Name="startButton" VerticalAlignment="Top" Width="160" Click="startButton_Click" />
    <Button Content="Stop" Height="72" HorizontalAlignment="Right" Margin="0,10,20,0" Name="stopButton" VerticalAlignment="Top" Width="160" Click="stopButton_Click"/>
    <TextBlock Height="30" HorizontalAlignment="Left"  Margin="20,100,0,0" Name="xTextBlock" Text="X: 1.0" VerticalAlignment="Top" Foreground="Red" FontSize="28" FontWeight="Bold"/>
    <TextBlock Height="30" HorizontalAlignment="Center"  Margin="0,100,0,0" Name="yTextBlock" Text="Y: 1.0" VerticalAlignment="Top" Foreground="Green" FontSize="28" FontWeight="Bold"/>
    <TextBlock Height="30" HorizontalAlignment="Right"  Margin="0,100,20,0" Name="zTextBlock" Text="Z: 1.0" VerticalAlignment="Top"  Foreground="Blue" FontSize="28" FontWeight="Bold"/>
    <Line x:Name="xLine" X1="240" Y1="350" X2="340" Y2="350" Stroke="Red" StrokeThickness="4"></Line>
    <Line x:Name="yLine" X1="240" Y1="350" X2="240" Y2="270" Stroke="Green" StrokeThickness="4"></Line>
    <Line x:Name="zLine" X1="240" Y1="350" X2="190" Y2="400" Stroke="Blue" StrokeThickness="4"></Line>
    <TextBlock Height="30" HorizontalAlignment="Center" Margin="6,571,6,0" Name="statusTextBlock" Text="TextBlock" VerticalAlignment="Top" Width="444" />
    
  4. Now open the MainPage.xaml.cs code-behind page and add using directives for the sensors and the XNA Framework namespaces to other using directives at the top of the page.

    using Microsoft.Devices.Sensors;
    using Microsoft.Xna.Framework;
    
  5. Declare a variable of type Accelerometer at the top of the MainPage class definition.

    public partial class MainPage : PhoneApplicationPage
    {
      Accelerometer accelerometer;
    
  6. In the page’s constructor, check to see whether the device on which the app is running supports the accelerometer sensor. Not all devices support all sensors, so you should always check before you use the sensor. Replace the existing page constructor with the following code.

    // Constructor
    public MainPage()
    {
      InitializeComponent();
    
      if (!Accelerometer.IsSupported)
      {
        // The device on which the application is running does not support
        // the accelerometer sensor. Alert the user and disable the
        // Start and Stop buttons.
        statusTextBlock.Text = "device does not support accelerometer";
        startButton.IsEnabled = false;
        stopButton.IsEnabled = false;
      }
    }
    
  7. Add a handler for the click events for the Start button. Depending on how you added the XAML code above, Visual Studio may have added this handler for you. If so, remove any code from inside the handler. If the handler was not added automatically, copy and paste the following empty function into the MainPage class definition.

    private void startButton_Click(object sender, RoutedEventArgs e)
    {
    
    }
    
  8. In the Start button click handler, check to see whether the accelerometer object is null, which it will be until it is initialized. If the accelerometer is null, initialize it using the constructor. Next, set how fast you would like to receive data from the accelerometer by setting the TimeBetweenUpdates property. The default value is 2 milliseconds. Next, set a handler for the CurrentValueChanged event. Paste the following code inside the empty Start button click handler..

      if (accelerometer == null)
      {
       // Instantiate the Accelerometer.
        accelerometer = new Accelerometer();
        accelerometer.TimeBetweenUpdates = TimeSpan.FromMilliseconds(20);
        accelerometer.CurrentValueChanged +=
            new EventHandler<SensorReadingEventArgs<AccelerometerReading>>(accelerometer_CurrentValueChanged);
      }
    
  9. Now, start the accelerometer using the Start()()() method. It is possible for the call to Start to fail, so you should put this call in a try block. In the catch block, you can alert the user that the accelerometer could not be started. Paste this code into the Start button click handler after the previous code section.

      try
      {
        statusTextBlock.Text = "starting accelerometer.";
        accelerometer.Start();
      }
      catch (InvalidOperationException ex)
      {
        statusTextBlock.Text = "unable to start accelerometer.";
      }
    
  10. Now, implement the CurrentValueChanged event handler. This method will be called by the system with new accelerometer data at the frequency you specified with TimeBetweenUpdates. The handler receives an AccelerometerReading object containing the accelerometer data. This handler is called on a background thread that does not have access to the UI. So, this event handler uses the Dispatcher.Invoke method, which calls the specified code on the UI thread. Dispatcher.Invoke is used to call the UpdateUI, which will be defined in the next step, and passes the AccelerometerReading object.

    void accelerometer_CurrentValueChanged(object sender, SensorReadingEventArgs<AccelerometerReading> e)
    {
      // Call UpdateUI on the UI thread and pass the AccelerometerReading.
      Dispatcher.BeginInvoke(() => UpdateUI(e.SensorReading));
    }
    
  11. Implement the UpdateUI method that will show the accelerometer data to the user. This method first updates the status TextBlock to indicate that data is being received. Next, the three TextBlock objects are updated to display the numeric values of the acceleration on each of the sensor’s axes. Finally, the Line objects are updated to graphically illustrate the acceleration.

    private void UpdateUI(AccelerometerReading accelerometerReading)
    {
      statusTextBlock.Text = "getting data";
    
      Vector3 acceleration = accelerometerReading.Acceleration;
    
      // Show the numeric values.
      xTextBlock.Text = "X: " + acceleration.X.ToString("0.00");
      yTextBlock.Text = "Y: " + acceleration.Y.ToString("0.00");
      zTextBlock.Text = "Z: " + acceleration.Z.ToString("0.00");
    
      // Show the values graphically.
      xLine.X2 = xLine.X1 + acceleration.X * 200;
      yLine.Y2 = yLine.Y1 - acceleration.Y * 200;
      zLine.X2 = zLine.X1 - acceleration.Z * 100;
      zLine.Y2 = zLine.Y1 + acceleration.Z * 100;
    }
    
  12. The final step is to implement the Stop button click handler that will allow the user to stop acquisition of data from the accelerometer. Once again, if the editor added this handler automatically, replace its contents with the following.

    private void stopButton_Click(object sender, RoutedEventArgs e)
    {
      if (accelerometer != null)
      {
        // Stop the accelerometer.
        accelerometer.Stop();
        statusTextBlock.Text = "accelerometer stopped.";
      }
    }
    

Testing the app with the accelerometer emulator

If you have a physical Windows Phone device, you can simply build the app, deploy it to the device, and wiggle the device around to watch the accelerometer data change. If you are using Windows Phone Emulator, you will need to open its accelerometer simulator to test the app.

To use the accelerometer emulator

  1. Choose Windows Phone Emulator from the Select Target for Windows Phone projects list in the Standard toolbar in Visual Studio.

  2. Press F5 or click Start Debugging on the Debug menu.

  3. Wait for the emulator to start and for the accelerometer app to load.

  4. In the emulator toolbar, click the Additional Tools button, which has the icon of two arrows pointing to the right.

  5. Select the Accelerometer tab in the Additional Tools window.

  6. Click the Start button in the accelerometer app that you created in the main emulator window.

  7. Move the pink dot around the Additional Tools window to change the orientation of the virtual phone and observe the changing data in the main emulator window.