Compass Sensor API (Universal Windows Platform)

This document provides a reference for the Compass Sensor API available for Universal Windows Platform (UWP) applications. The compass sensor provides data about the device's orientation relative to magnetic north.

Overview

The compass sensor is a hardware sensor that measures the magnetic field. UWP applications can access this data through the Windows.Devices.Sensors namespace, specifically using the Compass class.

Availability

The compass sensor is not available on all devices. Your application should always check for sensor availability before attempting to access its data. It is typically found on devices with integrated magnetic sensors, such as smartphones, tablets, and some laptops.

Getting Started

To use the compass sensor, you need to:

  1. Get an instance of the Compass class.
  2. Register for data change events or read data manually.
  3. Handle sensor reading errors gracefully.

1. Getting a Compass Instance

You can get the default compass sensor using the static GetDefault() method. If no compass sensor is available, this method will return null.


using Windows.Devices.Sensors;

// Get the default compass sensor.
Compass compass = Compass.GetDefault();

if (compass == null)
{
    // Compass sensor is not available on this device.
    // Handle this case appropriately (e.g., disable compass-related features).
    System.Diagnostics.Debug.WriteLine("Compass sensor not found.");
}
else
{
    // Compass sensor is available. Proceed to use it.
    System.Diagnostics.Debug.WriteLine("Compass sensor found.");
}
        

2. Handling Data Changes

The Compass class provides an event, ReadingChanged, that fires whenever new compass data is available. You should register a handler for this event to receive real-time updates.


// In your class that manages the compass sensor:

private Compass _compass;
private TypedEventHandler<Compass, CompassReadingChangedEventArgs> _readingChangedHandler;

public void InitializeCompass()
{
    _compass = Compass.GetDefault();

    if (_compass != null)
    {
        // Set the desired reporting interval.
        // A lower interval means more frequent updates, but consumes more power.
        uint minReportInterval = _compass.MinimumReportInterval;
        uint reportInterval = minReportInterval > 16 ? minReportInterval : 16; // Aim for ~60 FPS
        _compass.ReportInterval = reportInterval;

        // Register for the ReadingChanged event.
        _readingChangedHandler = new TypedEventHandler<Compass, CompassReadingChangedEventArgs>((sender, args) =>
        {
            var reading = args.Reading;
            // Process the compass reading here
            ProcessCompassReading(reading);
        });
        _compass.ReadingChanged += _readingChangedHandler;
    }
}

private void ProcessCompassReading(CompassReading reading)
{
    // Access compass data properties
    double headingMagneticNorth = reading.HeadingMagneticNorth;
    DateTime timestamp = reading.Timestamp.DateTime;

    // You can also get True North if available and accuracy permits
    if (reading.HeadingTrueNorth != null)
    {
        double headingTrueNorth = reading.HeadingTrueNorth.Value;
        // Use headingTrueNorth
    }

    // Update your UI or perform calculations
    System.Diagnostics.Debug.WriteLine($"Magnetic North: {headingMagneticNorth:F2} degrees");
}

// Don't forget to unregister the event handler when your page or class is disposed.
public void UninitializeCompass()
{
    if (_compass != null && _readingChangedHandler != null)
    {
        _compass.ReadingChanged -= _readingChangedHandler;
        _readingChangedHandler = null;
        _compass = null;
    }
}
        

3. Reading Data Manually

Alternatively, you can read the compass data on demand using the GetCurrentReading() method. This is useful if you only need the compass data at specific times rather than continuously.


if (_compass != null)
{
    CompassReading currentReading = _compass.GetCurrentReading();
    if (currentReading != null)
    {
        double headingMagneticNorth = currentReading.HeadingMagneticNorth;
        // Process headingMagneticNorth
        System.Diagnostics.Debug.WriteLine($"Current Magnetic North: {headingMagneticNorth:F2} degrees");
    }
}
        

Compass Properties

The CompassReading object provides the following key properties:

Property Type Description
HeadingMagneticNorth double The heading relative to magnetic north, in degrees. Ranges from 0 to 360.
HeadingTrueNorth double? The heading relative to true north, in degrees. This property is nullable because true north calculation requires additional data (e.g., location) and might not always be available or accurate.
Timestamp DateTimeOffset The timestamp of the reading.

Accuracy and Reporting Interval

The Compass class offers properties to manage sensor behavior:

Power Considerations

Lower reporting intervals provide more frequent updates but consume more battery power. Always set the ReportInterval to a value that balances the needs of your application with power efficiency.

Error Handling

Sensor operations can sometimes fail. While the ReadingChanged event and GetCurrentReading() method typically return valid data or null, it's good practice to consider potential issues:

UWP XAML Example (Conceptual)

Here's a conceptual snippet of how you might display compass data in XAML:


<TextBlock x:Name="CompassHeadingTextBlock" Text="Compass Heading: N/A"/>
        

And the corresponding C# code-behind to update it:


// Inside your ProcessCompassReading method:
// Assuming CompassHeadingTextBlock is a TextBlock defined in XAML

private void ProcessCompassReading(CompassReading reading)
{
    double headingMagneticNorth = reading.HeadingMagneticNorth;
    CompassHeadingTextBlock.Text = $"Compass Heading: {headingMagneticNorth:F2}°";

    if (reading.HeadingTrueNorth != null)
    {
        double headingTrueNorth = reading.HeadingTrueNorth.Value;
        // You could display True North separately or combine it.
    }
}
        

Related APIs