In the previous two posts (Light sensor and Compass), I’ve shown how to use the sensors in a UWP app. Working with them is very easy and it can enhance the usability of your app. In this post, we willshow how to use another sensor, the Inclinometer.

This sensor is used a lot for games, as it detects the inclination of the device. That way, the user can control the game by tilting the device. Pretty cool, no? It’s note a pure sensor, as you won’t have an inclinometer in your device, but it gets its data from other two sensors, the accelerometer and the gyroscope.

The sensor usage is similar to the other sensors, and it shows three measures, Yaw (the rotation on the Z axis), Pitch (rotation on the X axis) and Roll (rotation on the Y axis):

inclinometer

(source – https://msdn.microsoft.com/en-us/windows/uwp/devices-sensors/sensors)

Playing with a ball in UWP

To show the usage f an inclinometer, we will create a project that can be a starting point for a game. We will draw a ball in the window and, depending on how the user tilts the device, the ball will move faster or slower, to the left and to the right.

We will start creating a new UWP blank app. Change the main element in the main page to a Canvas and add a new Ellipse to it:

[sourcecode language=”xml” padlinenumbers=”true”]
<Canvas Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Ellipse Width="80" Height="80" Fill="Red" x:Name="Ball"/>
</Canvas>
[/sourcecode]

In the constructor of the MainPage, we position the ball and add the code to initialize the inclinometer and set its ReadingChanged event handler:

[sourcecode language=”csharp”]
public MainPage()
{
this.InitializeComponent();
Loaded += (s, e) =>
{
Canvas.SetLeft(Ball, ActualWidth / 2 – 40);
Canvas.SetTop(Ball, ActualHeight – 80);
var inclinometer = Inclinometer.GetDefault();
if (inclinometer == null)
{
return;
}
inclinometer.ReadingChanged += async (s1, e1) =>
{
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
var position = Canvas.GetLeft(Ball);
var newPosition = position + e1.Reading.RollDegrees;
if (newPosition ActualWidth – 80)
newPosition = ActualWidth – 80;
Canvas.SetLeft(Ball, newPosition);
});
};
};
}
[/sourcecode]

As you can see, this time I’m doing all the initialization in the handler of the Loaded event of the page. That’s because ActualWidth and ActualHeight of the page aren’t set before the Loaded event fires, and if I don’t use this handler, the ball would be placed in the wrong place. As we have a Canvas, we position the ball with the attached properties Left and Top. In the code behind, this is done with the static methods Canvas.SetLeft and Canvas.SetTop.

The next step is to get the Inclinometer sensor with GetDefault and set its ReadingChanged handler. It will get the current position of the ball and will set the new position depending on the Roll (number of degrees of tilt in the Y position). That way, if the user tilts more, the ball will move faster. If he tilts less, it will move slower.

With that code in place, we have our moving ball project complete and can run it. If your device has an inclinometer, you can see the ball moving. If it doesn’t have, you can use a Windows Phone and see the same app running there.

image

Conclusions

Using the inclinometer is very simple and you can provide your users a different kind of input with it, you just need to get its reading and move the elements in your app according to the tilt of the device.

The source code for this app is in https://github.com/bsonnino/MovingBall

In the last post, I have shown how to use the light sensor to get light data and offer a better experience for the user. In this post, I will show another sensor available in 2-in-1 devices and tablets: the compass. The compass is a sensor the shows the direction, related to the magnetic north.

On physical compasses, this reading is given by a magnetic needle that is always pointing to the magnetic north. When you turn the compass, it will show you where are you heading to. In computers and smartphones, there is no magnetic needle, but the sensor shows the angle of the device, related to the magnetic north. To use the sensor, we must create a program that does the same three steps of the last post:

  • Get an instance of the sensor with the GetDefault method
  • Set its properties
  • Set a handler for the ReadingChanged

In this post, we will create a program that simulates a physical compass and shows the heading of the device.

Creating a compass simulator in UWP

The first step is to create a blank UWP project. In this project, add images tor the compass background and needle (I got my background from http://www.clipartbest.com/images-of-a-compass and the needle from http://www.clker.com/clipart-compassnorth.html) in the Assets folder.

Then, add the two images to the main window:

[sourcecode language=”xml” padlinenumbers=”true”]
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Image Source="Assets\\Compass.png" HorizontalAlignment="Stretch"
           VerticalAlignment="Stretch" Stretch="Uniform"/>
    <Image Source="Assets\\Compassnorth-Hi.png" HorizontalAlignment="Stretch"
           VerticalAlignment="Stretch" Stretch="Uniform" x:Name="Needle"/>
</Grid>
[/sourcecode]

In the constructor of MainWindow, we must get the compass and set the ReadingChanged event handler:

[sourcecode language=”csharp”]
public MainPage()
{
this.InitializeComponent();
var compass = Compass.GetDefault();
if (compass == null)
{
return;
}
compass.ReadingChanged += async (s, e) =>
{
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
RotateNeedle(e.Reading.HeadingMagneticNorth);
});
};
}
[/sourcecode]

The event handler just calls RotateNeedle, passing the reading angle as parameter. RotateNeedle is very simple:

[sourcecode language=”csharp”]
private void RotateNeedle(double angle)
{
var transform = new RotateTransform() { Angle = angle };
Needle.RenderTransformOrigin = new Windows.Foundation.Point(0.5, 0.5);
Needle.RenderTransform = transform;
}
[/sourcecode]

It just creates a RotateTransform, setting the angle to the reading angle, sets the origin of the rotation on the middle of the needle and then sets the RenderTransform property to this transform.

With this, you have a compass simulator that works both on desktops and smartphones. As you turn the device, the needle will be pointing to the magnetic north and the head will show you the direction.

image

Conclusions

As you can see, working with the compass is very easy, you can easily get the reading of the sensor and change the view, depending on what the user is heading. This is one more tool that you can use to give the user a better experience.

The full source code for the project is in https://github.com/bsonnino/Compass