.net, C# tip, Visual Studio, Xamarin

How to detect nearby Bluetooth devices with .NET and Xamarin.Android

I’m working on an Xamarin.Android app at the moment – for this app, I need to detect what Bluetooth devices are available to my Android phone (so the user can choose which one to pair with).

For modern versions of Android, it’s not as simple as just using a BroadcastReceiver (although that is part of the solution). In this post I’ll write about the steps needed to successfully use the Bluetooth hardware on your Android phone with .NET.

One thing to note – I can test detecting Bluetooth devices by deploying my code directly onto an Android device, but I can’t use the Android emulator as it doesn’t have Bluetooth support.

As usual I’ve uploaded my code to GitHub (you can get it here).

Update AndroidManifest.xml with Bluetooth and Location permissions

First I had to make sure that my application told the device what hardware services it needed to access. For detecting and interacting with Bluetooth hardware, there are four services to add to the application AndroidManifest.xml:

  • Bluetooth
  • Bluetooth Admin
  • Access Coarse Location
  • Access Fine Location

When the application loads on the Android device for the first time, the user will be challenged to allow the application permission to use these hardware services.

I’ve pasted my AndroidManifest.xml file below – yours will look slightly different, but I’ve highlighted the important bit in red.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          android:versionCode="1"
          android:versionName="1.0"
          package="Bluetooth_Device_Scanner.Bluetooth_Device_Scanner">
  <uses-sdk android:minSdkVersion="23" android:targetSdkVersion="27" />
  <application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
  </application>
  <uses-permission android:name="android.permission.BLUETOOTH" />
  <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
</manifest>

 

List the Bluetooth devices which the Android device has already paired with

This part is very straightforward – remember the code below will list to console only the Bluetooth devices which have already been detected and paired with the Android device. It will not list other devices which haven’t already been paired with each other (I write about this later in the article).

Obviously you’d probably want to write the output to a UI component rather than write to the console, but for this article I wanted to cut this down to only the Bluetooth interactions and not focus on UI interactions.

if (BluetoothAdapter.DefaultAdapter != null && BluetoothAdapter.DefaultAdapter.IsEnabled)
{
    foreach (var pairedDevice in BluetoothAdapter.DefaultAdapter.BondedDevices)
    {
        Console.WriteLine(
            $"Found device with name: {pairedDevice.Name} and MAC address: {pairedDevice.Address}");
    }
}

There’s not much more to say about this – I can put this pretty much anywhere in the C# code and it’ll just work as expected.

List new Bluetooth devices by creating a BluetoothDeviceReceiver class that extends BroadcastReceiver

Next I wanted to list the Bluetooth devices that haven’t been paired with the Android device. I can do this by creating a receiver class, which extends the ‘BroadcastReceiver’ base class, and overrides the ‘OnReceive’ method – I’ve included the code for my class below.

using System;
using Android.Bluetooth;
using Android.Content;
 
namespace Bluetooth_Device_Scanner
{
    public class BluetoothDeviceReceiver : BroadcastReceiver
    {
        public override void OnReceive(Context context, Intent intent)
        {
            var action = intent.Action;
            
            if (action != BluetoothDevice.ActionFound)
            {
                return;
            }
 
            // Get the device
            var device = (BluetoothDevice)intent.GetParcelableExtra(BluetoothDevice.ExtraDevice);
 
            if (device.BondState != Bond.Bonded)
            {
                Console.WriteLine($"Found device with name: {device.Name} and MAC address: {device.Address}");
            }
        }
    }
}

This receiver class is registered with the application and told to activate when the Android device detects specific events – such as finding a new Bluetooth device. Xamarin.Android does this through something called an ‘Intent’. The code below shows how to register the receiver to trigger when a Bluetooth device is detected.

// Register for broadcasts when a device is discovered
_receiver = new BluetoothDeviceReceiver();
RegisterReceiver(_receiver, new IntentFilter(BluetoothDevice.ActionFound));

When the Android device finds a new Bluetooth device and calls the OnReceive method, the class checks that the event is definitely the right one (i.e. BluetoothDevice.ActionFound).

Then it checks that the devices are not already paired (i.e. ‘Bonded’) and again my class just writes some details to the console about the Bluetooth device that its found.

But we’re not quite done yet – there’s one more very important piece of code which is necessary for modern versions of Android.

Finally – check permissions are applied at runtime

This is the bit that is sometimes missed in other tutorials, and that’s possibly because this is only needed for more recent versions of Android, so older tutorials wouldn’t have needed this step.

Basically even though the Access Coarse and Fine Location permissions are already specified in the AndroidManifest.xml file, if you’re using later than version 23 of the Android SDK, you need to also check that the permissions are correctly set at runtime. If they aren’t, you need to add code to prompt the user to grant these permissions.

There’s lots more about this topic on the Xamarin blog here.

I’ve pasted my MainActivity class below. This class:

  • Checks permissions,
  • Prompts the user for any permissions that are missing,
  • Registers the receiver to trigger when Bluetooth devices are detected, and
  • Starts scanning for Bluetooth devices.
using Android;
using Android.App;
using Android.Bluetooth;
using Android.Content;
using Android.Content.PM;
using Android.OS;
using Android.Support.V4.App;
using Android.Support.V4.Content;
 
namespace Bluetooth_Device_Scanner
{
    [Activity(Label = "Bluetooth Device Scanner", MainLauncher = true)]
    public class MainActivity : Activity
    {
        private BluetoothDeviceReceiver _receiver;
 
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
 
            SetContentView(Resource.Layout.activity_main);
 
            const int locationPermissionsRequestCode = 1000;
 
            var locationPermissions = new[]
            {
                Manifest.Permission.AccessCoarseLocation,
                Manifest.Permission.AccessFineLocation
            };
 
            // check if the app has permission to access coarse location
            var coarseLocationPermissionGranted =
                ContextCompat.CheckSelfPermission(thisManifest.Permission.AccessCoarseLocation);
 
            // check if the app has permission to access fine location
            var fineLocationPermissionGranted =
                ContextCompat.CheckSelfPermission(thisManifest.Permission.AccessFineLocation);
 
            // if either is denied permission, request permission from the user
            if (coarseLocationPermissionGranted == Permission.Denied ||
                fineLocationPermissionGranted == Permission.Denied)
            {
                ActivityCompat.RequestPermissions(this, locationPermissions, locationPermissionsRequestCode);
            }
 
            // Register for broadcasts when a device is discovered
            _receiver = new BluetoothDeviceReceiver();
 
            RegisterReceiver(_receiver, new IntentFilter(BluetoothDevice.ActionFound));
 
            BluetoothDeviceReceiver.Adapter.StartDiscovery();
        }
    }
}

Now the application will call the BluetoothDeviceReceiver class’s OnReceive method when it detects Bluetooth hardware.

Wrapping up

Hopefully this is useful to anyone writing a Xamarin.Android application that interacts with Bluetooth devices – I struggled with this for a while and wasn’t able to find an article which detailed all the pieces of the puzzle:

  • Update the manifest with the 4 required application permissions
  • Create a class that extends BroadcastReceiver,
  • Check at runtime that the location permissions have been granted and prompt the user if they haven’t, and
  • Register the receiver class and start discovery.

About me: I regularly post about Microsoft technologies and .NET – if you’re interested, please follow me on Twitter, or have a look at my previous posts here. Thanks!

.net, C# tip, Clean Code, Visual Studio

Creating a RESTful Web API template in .NET Core 1.1 – Part #1: Returning HTTP Codes

I’ve created RESTful APIs with the .NET framework and WebAPI before, but nothing commercial with .NET Core yet. .NET Core has been out for a little while now – version 1.1 was released at Connect(); //2016 – I’ve heard that some customers now are willing to experiment with this to achieve some of the potential performance and stability gains.

To prepare for new customer requests, I’ve been experimenting with creating a simple RESTful API with .NET Core to see how different it is to the alternative version with the regular .NET Framework…and I’ve found that it’s really pretty different.

I’ve already written about some of the challenges in upgrading from .NET Core 1.0 to 1.1 when creating a new project – this post is about how to start with the default template for Web API projects, and transform it into something that is more like a useful project to host RESTful microservices.

This first post in the series is about turning the default project into a good HTTP citizen and return HTTP status codes.

When I create a new WebAPI project using .NET Core 1.1 from the default Visual Studio template, a number of files are created in the project. The more interesting one is the “ValuesController” – this holds the standard verbs associated with RESTful services, GET, POST, PUT and DELETE. I’ve pasted the default code created below:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
 
namespace MyWebAPI.Controllers
{
    [Route("api/[controller]")]
    public class ValuesController : Controller
    {
        // GET api/values
        [HttpGet]
        public IEnumerable<string> Get()
        {
            return new string[] { "value1""value2" };
        }
 
        // GET api/values/5
        [HttpGet("{id}")]
        public string Get(int id)
        {
            return "value";
        }
 
        // POST api/values
        [HttpPost]
        public void Post([FromBody]string value)
        {
        }
 
        // PUT api/values/5
        [HttpPut("{id}")]
        public void Put(int id, [FromBody]string value)
        {
        }
 
        // DELETE api/values/5
        [HttpDelete("{id}")]
        public void Delete(int id)
        {
        }
    }
}

However, one of the things I don’t like about this which would be very easy to change is the return type of each verb. A good RESTful service should return HTTP status codes describing the result of the action – typically 200 codes for success:

  • 200 – Request is Ok;
  • 201 – Resource created successfully;
  • 202 – Update accepted and will be processed (although may be rejected);
  • 204 – Request processed and there is no content to return.

Additionally, responses to RESTful actions will sometimes contain information:

  • 200 – OK – if the action is GET, the response will contain an object (or list of objects) which were requested.
  • 201 – Created – the response will contain the object which was created, and also the unique URI required to get that object.
  • 202 – Accepted – the response will contain the object for which an update was requested.
  • 204 – No content to return – this could be returned as a result of a delete request, where it would make no sense to return an object (as it theoretically no longer exists).

    As a brief aside, some writers disagree that the Delete request should return no content – for a HATEOAS application, I can see why returning an empty response is not helpful.

I think the default ValuesController would be more useful if it implemented a pattern of returning responses with correctly configured HTTP status codes, and I think the first step towards this would be to use the default code below for the ValueController (which – as a default template – obviously does nothing useful yet).

using Microsoft.AspNetCore.Mvc;
 
namespace MyWebAPI.Controllers
{
    [Route("api/[controller]")]
    public class ValuesController : Controller
    {
        // GET api/values
        [HttpGet]
        public IActionResult Get()
        {
            return Ok(new string[] { "value1""value2" });
        }
 
        // GET api/values/5
        [HttpGet("{id}")]
        public IActionResult Get(int id)
        {
            return Ok("value");
        }
 
        // POST api/values
        [HttpPost]
        public IActionResult Post([FromBody]string value)
        {
            return Created($"api/Values/{value}", value);
        }
 
        // PUT api/values/5
        [HttpPut("{id}")]
        public IActionResult Put(int id, [FromBody]string value)
        {
            return Accepted(value);
        }
 
        // DELETE api/values/5
        [HttpDelete("{id}")]
        public IActionResult Delete(int id)
        {
            return NoContent();
        }
    }
}

The main changes I’ve made so far are:

  • The return type of each action is now IActionResult, which allows for Http status codes to be returned.
  • For the GET actions, I’ve just wrapped the objects returned (which are simple strings) with the Ok result.
  • For the POST action, I’ve used the Created result object. This is different to OK because in addition to including an object, it also includes a URI pointing to the location of the object.
  • For the PUT action, I just wrapped the object returned with the Accepted result. The return type of Accepted is new in .NET Core v1.1 – this won’t compile if you’re targeting previous versions.
  • Finally, for the DELETE action, rather than returning void I’ve returned a NoContent result type.

I really like how .NET Core v1.1 bakes in creating great RESTful services in a clean and simple way and prefer it to the way previously used in .NET. I’m planning a number of other posts which will focus on some functional and non-functional aspects of creating a clean RESTful service:


About me: I regularly post about .NET – if you’re interested, please follow me on Twitter, or have a look at my previous posts here. Thanks!

.net, C# tip, UWP, Visual Studio

Testing your Windows App with Appium in Windows 10 and Visual Studio 2015

At Connect(); // 2016, Scott Hanselman’s keynote include a short description of a tool called Appium (presented by Stacey Doerr). This tool allows you to create and automate UI tests for Windows Apps – not just UWP apps, but basically any app which runs on your Windows machine. Automated UI testing is definitely something that I’ve missed when moving from web development to UWP development, so I was quite excited to find out there’s a project would help fill this gap.

As is often the case, getting started with new things is tricky –  when I follow present instructions from Microsoft, I found some errors occurred. That’s likely to be caused by my development machine set up – but you might hit the same issue. In this post, I’ll describe the process I followed to get Appium working, and I’ll also document the error messages I found on the way.

I hope that this blog post becomes irrelevant soon and that this isn’t an issue affecting a lot of people.

Installing and Troubleshooting Appium

Step 1 – Install Node.js

Install Node.js from here.

Step 2 – Open a PowerShell prompt as Administrator, and install Appium

From an elevated PowerShell prompt, run the command:

npm install –g appium

When I ran this command, the following warnings were printed to the screen – however I don’t think they’re anything to worry about:

npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^1.0.12(node_modules\appium\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.0.15: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})

 Step 3 – From an elevated PowerShell prompt, run Appium

From an elevated PowerShell prompt, run the command:

appium

After a few seconds, the following text is printed to the screen.

Welcome to Appium v1.6.0
Appium REST http interface listener started on 0.0.0.0:4723

At this point I tried to run the tests in the Sample Calculator App provided by Appium on GitHub – found here. I used Visual Studio to run these tests, but found all 5 tests failed, and the following error was printed to the PowerShell prompt.

[Appium] Creating new WindowsDriver session
[Appium] Capabilities:
[Appium]   app: 'Microsoft.WindowsCalculator_8wekyb3d8bbwe!App'
[Appium]   platformName: 'Windows'
[Appium]   deviceName: 'WindowsPC'
[BaseDriver] The following capabilities were provided, but are not recognized by appium: app.
[BaseDriver] Session created with session id: dcfce8e7-9615-4da1-afc5-9fa2097673ed
[WinAppDriver] Verifying WinAppDriver is installed with correct checksum
[debug] [WinAppDriver] Deleting WinAppDriver session
[MJSONWP] Encountered internal error running command: 
	Error: Could not verify WinAppDriver install; re-run install
    at WinAppDriver.start$ (lib/winappdriver.js:35:13)
    at tryCatch (C:\Users\Jeremy\AppData\Roaming\npm\node_modules\appium\node_modules\babel-runtime\regenerator\runtime.js:67:40)
    at GeneratorFunctionPrototype.invoke [as _invoke] (C:\Users\Jeremy\AppData\Roaming\npm\node_modules\appium\node_modules\babel-runtime\regenerator\runtime.js:315:22)
    at GeneratorFunctionPrototype.prototype.(anonymous function) [as next] (C:\Users\Jeremy\AppData\Roaming\npm\node_modules\appium\node_modules\babel-runtime\regenerator\runtime.js:100:21)
    at GeneratorFunctionPrototype.invoke (C:\Users\Jeremy\AppData\Roaming\npm\node_modules\appium\node_modules\babel-runtime\regenerator\runtime.js:136:37)

For some reason on my machine, the WinAppDriver has not been installed correctly during the installation of Appium.

Step 4 – Manually install v0.5-beta of the WinAppDriver

This is pretty easy to fix – we can just grab the WinAppDriver installer from its GitHub site. But for version 1.6.0 of Appium, I found that it was important to select the correct version of WinAppDriver – specifically v0.5-beta, released on September 16 2016. Higher versions did not work for me with Appium v1.6.0.

Step 5 – Restart Appium from an elevated PowerShell prompt

Installed WinAppDriver v0.5-beta was a pretty simple process, I just double clicked on the file and selected all the default options. Then I repeated Step 3 and restarted Appium from the elevated PowerShell prompt. Again, after a few seconds, the same message appeared.

Welcome to Appium v1.6.0
Appium REST http interface listener started on 0.0.0.0:4723

This time, when I ran the tests for the Sample Calculator App from GitHub they all passed. Also, the PowerShell prompt showed no errors – instead of saying that it couldn’t verify the WinAppDriver install, I got the message below:

[WinAppDriver] Verifying WinAppDriver is installed with correct checksum
[debug] [WinAppDriver] WinAppDriver changed state to 'starting'
[WinAppDriver] Killing any old WinAppDrivers, running: FOR /F "usebackq tokens=5" %a in (`netstat -nao ^| findstr /R /C:"4823 "`) do (FOR /F "usebackq" %b in (`TASKLIST /FI "PID eq %a" ^| findstr /I winappdriver.exe`) do (IF NOT %b=="" TASKKILL /F /PID %a))
[WinAppDriver] No old WinAppDrivers seemed to exist
[WinAppDriver] Spawning winappdriver with: undefined 4823/wd/hub
[WinAppDriver] [STDOUT] Windows Application Driver Beta listening for requests at: http://127.0.0.1:4823/wd/hub
[debug] [WinAppDriver] WinAppDriver changed state to 'online'

I was able to see the standard Windows Calculator appear, and a series of automated UI tests were carried out on the app.

How do I get automation information for these apps?

When you look at the Sample Calculator App and the basic scenarios for testing, you’ll see some code with some strange constant values – such as the in the snippet below.

DesiredCapabilities appCapabilities = new DesiredCapabilities();
appCapabilities.SetCapability("app""Microsoft.WindowsCalculator_8wekyb3d8bbwe!App");
appCapabilities.SetCapability("platformName""Windows");
appCapabilities.SetCapability("deviceName""WindowsPC");
CalculatorSession = new RemoteWebDriver(new Uri(WindowsApplicationDriverUrl), appCapabilities);
Assert.IsNotNull(CalculatorSession);
CalculatorSession.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(2));
 
// Make sure we're in standard mode
CalculatorSession.FindElementByXPath("//Button[starts-with(@Name, \"Menu\")]").Click();
OriginalCalculatorMode = CalculatorSession.FindElementByXPath("//List[@AutomationId=\"FlyoutNav\"]//ListItem[@IsSelected=\"True\"]").Text;
CalculatorSession.FindElementByXPath("//ListItem[@Name=\"Standard Calculator\"]").Click();

The code above shows that the test looks for an app with identifier:

“Microsoft.WindowsCalculator_8wekyb3d8bbwe!App”

It’s obvious this is for the Microsoft Windows Calculator app – but most of us won’t recognise the strange looking code appended at the end of this string. This is the application’s automation identifier.

In order to locate this identifier, start the standard Calculator application from within Windows (open a Run prompt and enter “Calc”).

There’s a tool shipped with the Visual Studio 2015 called “Inspect” – it should normally be available at the location:

C:\Program Files (x86)\Windows Kits\10\bin\x86

Start Inspect.exe from the directory specified above. When you run the Inspect application, you’ll get a huge amount of information about the objects currently being managed by Windows 10 – when you drill into the tree view on the left side of the screen to see running applications, you can select “Calculator”, and on the right hand side a value for “AutomationId” will be shown – I’ve highlighted it in red below.

inspect

The other items – menus, buttons, and display elements – can also be obtained from this view when you select the corresponding menu, button or display elements – a particularly useful property is “Legacy|Accessible:Name” when identifying elements using the FindElementByXPath method.

Conclusion

I hope this post is useful for anyone interested in automating UI tests for Windows App, and particularly if you’re having problems getting Appium to work. There’s some really useful sample apps on GitHub from Appium – I found coding for Windows Apps to be a bit confusing to start off with, but with a few key bits of information – like using the Inspect tool  – you can start to tie together how the sample apps were written and how they work. This should get you up and running with your own automated UI test code. I’m excited about the opportunities this tool gives me to improve the quality of my applications – I hope this post helps you get started too.

.net, HoloLens, Unity, UWP, Visual Studio

Coding for the HoloLens with Unity 5 – Part #1: Setting up your environment

I’m starting a new series of posts on coding for the HoloLens with Unity. There’s relatively few posts on how to code for this device, and the ones that I’ve found so far haven’t been as complete as I’d like them to be, and this series will be part tutorial and part lab-notes for myself.

So far, I’ve planned for the first 3 posts in the series.

  • Part 1 – Getting started – downloading and installing the software;
  • Part 2 – Creating a project in Unity 5, and adding a simple object to a virtual world;
  • Part 3 – Deploying this project to the HoloLens emulator.

I’ll follow these introductory posts with some more complex and interesting projects.

Getting started – downloading and installing the software

You don’t need a physical HoloLens to develop software for the HoloLens (although it would help). You can develop your app using available tools, and test it on an emulator – as long as you have Windows 10 Professional. The reason for this is that the emulator uses Hyper-V, which is available on Window 10 Pro – it’s not available on the home edition.

Hardware requirements

There are detailed hardware requirements at this link – key requirements are a 64-bit CPU with 4 cores, 8GB of RAM, and hardware assisted virtualisation enabled in the BIOS settings – Microsoft provides a guide on how to do this here.

Software downloads

You’ll need to install 4 software components – VS2015.3, the HoloLens emulator, Unity 5, and the UWP runtime for Unity.

The first development tool you’ll need is the IDE – Visual Studio 2015, Update 3. This is freely available as the Community Edition. You can get this here.

Next, you’ll need the HoloLens emulator to test your apps – you can get the emulator here (v10.0.14342.1018). This is a simple executable, which will check to see if your computer is suitable for HoloLens development while it’s installing.

You’ll need two pieces of Unity software to develop and deploy using Unity 5. These are both available from the Unity site at this link.

  • The first item to download and install will be the Unity Editor for the HoloLens Technical Preview. There’s a special edition for the HoloLens, and you can choose to go with either a 32-bit version or a 64-bit version.
  • The second item is the UWP Runtime for Unity – this allows you to build your applications as a Universal Windows Platform application, which is necessary to deploy and run on a HoloLens.

You’ll need to register as a Unity developer, but there’s no charge for this if you’re using the personal edition option.

Next time I’m going to look at writing my first Unity 3d application, where I’ll create a simple object in a virtual world.

.net, Making, Raspberry Pi 3, Visual Studio

A servo library in C# for Raspberry Pi 3 – Part #1, implementing PWM

Windows IoT Core is a young project – and whereas there are already a lot of good tutorials and examples on the internet, and there’s a lot more work to be done before the libraries available can compare with the work done by the Arduino community.

I’ve managed to make servo motors work in the past with Arduino – there’s already a servo project packaged with the Arduino development environment, and that just works out of the box. I was interested to see if I could do this in C# with the Raspberry Pi 3, and I couldn’t find any simple pre-existing code for this. Since I like an interesting technical challenge, I thought this would be a good problem to solve.

First – how do servos work?

A servo is more than just a simple motor which accepts a power supply and spins round – it’s possible to precisely control how much a servo turns. It’s able to do this because the servo is basically made up of a motor, a potentiometer, and a controller. A very simple explanation of how it works is:

  • The controller chip is given a signal – for example, turn the motor to the 90 degree position;
  • The motor’s output spindle is connected to a potentiometer – since the controller chip is able to measure the resitance between terminals of the potentiometer, therefore it’s able to infer the current position of the motor;
  • The controller only powers the motor until the resistance of the potentiometer matches the value it expects when the spindle is at the 90 degree position.

So this explains the mechanical operation of a servo – but what about the signal which is sent to the controller chip? How do we tell it to move to 0 degrees, 90 degrees, or 180 degrees?

It turns out there’s quite a simple answer to this – we send a series of pulses to the controller, which have different widths for different motor positions – this works like this:

  • The controller chip expects a series of digital pulses at a particular frequency;
  • The frequency describes how many pulses are sent per second – so for example, if the time between pulses starting needs to be 20ms, then we’d need to send 50 per second (50 cycles x 20ms = 1000ms).
    • There for the frequency is 50 pulses per second – also called 50Hz.
  • Each signal is made up of two logic states – logic 1 (5 volts) and logic 0 (0 volts);
    • The ratio of time in each cycle spent at logic 1 to the total length of the cycle is called the duty cycle.
    • For example, if the time between pulses starting is 20ms, and the pulse is 2ms at logic 1, then the duty cycle is 10% (2ms/20ms x 100%);

My research suggested that most servos expect pulses at a frequency of 50Hz. They will move to:

  • 0 degree position with a duty cycle of 5% (1ms of logic 1 in a 20ms pulse);
  • 180 degree position with a duty cycle of 10% (2ms of logic 1 in a 20ms pulse);

So my challenge was to find a way for the Raspberry Pi to generate a series of variable width pulses.

This technique of changing the width of pulses is is known as pulse width modulation (PWM).

This is easier said than done with the Raspberry Pi. Whereas the Arduino has several pins that output PWM signals, there are no pins in the Raspberry Pi that obviously output PWM.

Next – can I simulate PWM using C# code?

Well…I gave it a go. My theory was that I could set a pin to logic 1, and then wait for a certain number of milliseconds to pass before setting the pin back to logic zero.

I connected the three wires of the servo to my Raspberry Pi – the 5v wire to Pin 2, the ground wire to Pin 39, and the control wire went to Pin 29 (which was GPIO 5).

rp2_pinout

In order to develop a Windows app for the Raspberry Pi, I created a blank Windows UWP app, and added a reference to the Windows IoT Extensions.

screenshot.1462650773

I then added the code below to the MainPage.xaml.cs file.

This code didn’t work – I’m just including this as part of the path that I followed.

var gpioController = GpioController.GetDefault();
var gpioPin = gpioController.OpenPin(5);
gpioPin.SetDriveMode(GpioPinDriveMode.Output);
    
var _stopwatch = new Stopwatch();
_stopwatch.Start();
    
// number of system ticks in a single millisecond
var ticksPerMs = (ulong)(Stopwatch.Frequency) / 1000;
 
// length of pulse is 20ms (which equates to a frequency of 50Hz)
var pulseDuration = 20;
 
// let the pin sit at logic 1 until 2ms have passed
var logicOneDuration = 2;
 
while (true)
{
    var ticks = _stopwatch.ElapsedTicks;
 
    gpioPin.Write(GpioPinValue.High);
    
    while (true)
    {
        var timePassed = _stopwatch.ElapsedTicks - ticks;
 
        if ((ulong)(timePassed) >= logicOneDuration * ticksPerMs)
        {
            break;
        }
    }
    
    gpioPin.Write(GpioPinValue.Low);
    
    while (true)
    {
        var timePassed = _stopwatch.ElapsedTicks - ticks;
 
        if ((ulong)(timePassed) >= pulseDuration* ticksPerMs)
        {
            break;
        }
    }
}

This experiment wasn’t really successful – theoretically it was sound, but practically I don’t think this method of “bitbanging” is really good enough to give the accuracy necessary for a servo controller. I found this made the servo twitch, but not much else.

I tried a different way – rather than looping until a certain time passed, I thought I’d try blocking the thread for the a number of milliseconds after setting the GPIO pin to high or low…this didn’t really work either, giving more-or-less the same results as the original code (i.e. the servo twitched, but didn’t consistently move in the way I expected it to).

public MainPage()
{
    this.InitializeComponent();
 
    var gpioController = GpioController.GetDefault();
    var gpioPin = gpioController.OpenPin(5);
    gpioPin.SetDriveMode(GpioPinDriveMode.Output);
            
    while (true)
    {
        gpioPin.Write(GpioPinValue.High);
        Task.Delay(2).Wait();
        gpioPin.Write(GpioPinValue.Low);
        Task.Delay(18).Wait();
    }
}

I needed to find another way to generate PWM from a Raspberry Pi 3. Fortunately, Microsoft have provided a technology which solves this problem.

Using Microsoft Lightning Providers to generate PWM

Lightning is new software from Microsoft that implement some new functions, including SPI and PWM support. It’s pretty easy to enable this software – there’s few simple steps.

This learning process was helped by the set-up guide from Microsoft and from the blog post from Lee P. Richardson here.

Change the default controller driver

I opened the online administrative interface for the Pi at http://minwinpc:8080, and navigated to the Devices tab of this interface. This has a dropdown at the top of the page showing the “Default Controller Driver”, which was set to “Inbox Driver”. I opened this dropdown, and selected the second value which is “Direct Memory Mapped Driver”. Once I selected this, I clicked on the button titled “Update Driver”, and was prompted to reboot my Pi.

screenshot.1462663123

When I rebooted the Pi, I looked at the Devices tab of the interface again, and saw that my option was selected.

Download the lightning providers from Nuget

I right clicked on the Windows app project in VS2015, and selected “Manage Nuget Packages…”. This opened the Nuget package manager, and I searched for “Microsoft.IoT.Lightning”. This returned two packages:

  • Microsoft.IoT.Lightning (presently v1.0.4), and
  • Microsoft.IoT.Lightning.Providers (presently v1.0.0);

screenshot.1462663411

Change the package.appxmanifest file to add the new capabilities

I had to make a couple more changes to enable device capabilities. There were changes to the package.appxmanifest file. I needed to make these changes directly to the XML, so I right clicked on the file in VS2015, and selected “View Code”.

First, add the IOT property to the Package node, and add “iot” to the ignoreable namespaces.

<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" 
         xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" 
         xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" 
         xmlns:iot="http://schemas.microsoft.com/appx/manifest/iot/windows10" 
         IgnorableNamespaces="uap mp iot">

Next, add the new iot and DeviceCapabilities.

  <Capabilities>
    <Capability Name="internetClient" />
    <iot:Capability Name="lowLevelDevices" />
    <DeviceCapability Name="109b86ad-f53d-4b76-aa5f-821e2ddf2141" />
  </Capabilities>

Add the PWM code for a servo

I found the code worked well – obviously this is proof of concept code, but I found it moved the servo from 0 degrees, to 90 degrees, and then to 180 degrees.

public MainPage()
{
    this.InitializeComponent();
 
    Servo();
}
        
private async void Servo()
{
    if (LightningProvider.IsLightningEnabled)
    {
        LowLevelDevicesController.DefaultProvider = LightningProvider.GetAggregateProvider();
    }
 
    var pwmControllers = await PwmController.GetControllersAsync(LightningPwmProvider.GetPwmProvider());
    if (pwmControllers != null)
    {
        // use the on-device controller
        var pwmController = pwmControllers[1];
 
        // Set the frequency, defaulted to 50Hz
        pwmController.SetDesiredFrequency(50);
 
        // Open pin 5 for pulse width modulation
        var servoGpioPin = pwmController.OpenPin(5);
 
        // Set the Duty Cycle - 0.05 will set the servo to its 0 degree position
        servoGpioPin.SetActiveDutyCyclePercentage(0.05);
 
        // Start PWN from pin 5, and give the servo a second to move to position
        servoGpioPin.Start();
        Task.Delay(1000).Wait();
        servoGpioPin.Stop();
 
        // Set the Duty Cycle - 0.1 will set the servo to its 180 degree position
        servoGpioPin.SetActiveDutyCyclePercentage(0.1);
 
        // Start PWN from pin 5, and give the servo a second to move to position
        servoGpioPin.Start();
        Task.Delay(1000).Wait();
        servoGpioPin.Stop();
    }
}

In the Part 2, I’ll design an interface for the servo library and refine the implementation code.

.net, Raspberry Pi 3, Visual Studio

How to workaround “DEP0001 : Unexpected Error: -2145615869” with Raspberry Pi and VS2015

I’ve started to do some Windows App development for the Raspberry Pi 3 with IoT Core (v14322), and quickly came across an issue which temporarily stopped me deploying from the Raspberry Pi to Visual Studio.

The issue manifests as an error with code DEP0001 after trying to deploy a Windows 10 App to the “Remote Machine” (i.e. the Raspberry Pi).

screenshot.1462628381

Apparently this is caused when the destination Raspberry Pi becomes disconnected from the network after Visual Studio 2015 has been started. Even when it’s reconnected, VS2015 doesn’t re-acquire the connection to the Pi.

Simple fix? Restart Visual Studio 2015 and try deploying again. I know, I know – I hate it too – but it works. This issue has been discussed on Microsoft’s Windows IoT forums here, so I’d expect to see a fix for this in later versions of the framework.

 

.net, Computer Vision, UWP, Visual Studio, Windows Store Apps

How to use the camera on your device with C# in a UWP application: Part #3, saving a picture

Previously in this series, we looked at how to preview your device’s camera output, and how to use a physical button to focus the camera.

This time I’d like to look at how to capture an image, and store it in a local device folder.

Adding the capability to save to the pictures folder

If you want to save pictures to one of the many standard Windows folders, you need to add this capability to the package manifest. In the VS2015 project which we’ve been building over the last two parts of this series, double click on the Package.appxmanifest file. In the list of capabilities, tick the box with the text “Pictures Library”.

screenshot.1461274147

Our application is now allowed to save to the Pictures library on our device.

Capture an image using the device button

In part 2, we set up our app to make the camera focus when the button is half pressed – after it has focussed, we’d like to fully press the button to capture the image presently being previewed. To do this, we need to handle the CameraPressed event in our code.

if (ApiInformation.IsTypePresent("Windows.Phone.UI.Input.HardwareButtons"))
{
    HardwareButtons.CameraHalfPressed += HardwareButtons_CameraHalfPressed;
    HardwareButtons.CameraPressed += HardwareButtons_CameraPressed;
}

The next step is to write the event handler.

Writing to “Known Folders”

The Windows UWP API has some functions already baked in that allow us to identify special folders in Windows, and save files to these folders.

To get these special folders, we use the static class “KnownFolders”. For each of these known folders, there are methods available to create files. These created files implement the IStorageFile interface – and fortunately, the _mediaCapture has a method called CapturePhotoToStorageFileAsync, which allows us to save an image to a file which implements this interface. The code below for the event handler shows how it’s done.

private async void HardwareButtons_CameraPressed(object sender, CameraEventArgs e)
{
    // This is where we want to save to.
    var storageFolder = KnownFolders.SavedPictures;
 
    // Create the file that we're going to save the photo to.
    var file = await storageFolder.CreateFileAsync("sample.jpg", CreationCollisionOption.ReplaceExisting);
 
    // Update the file with the contents of the photograph.
    await _mediaCapture.CapturePhotoToStorageFileAsync(ImageEncodingProperties.CreateJpeg(), file);
}

So now we have a basic Windows application, which acts as a viewfinder, allows us to focus if the device is capable, and then allows us to save the presently displayed image to the special Windows SavedPictures folder. This is a pretty good app – and we’ve done it in about 100 lines of code (shown below). Not bad!

using System;
using System.Linq;
using System.Threading.Tasks;
using Windows.Devices.Enumeration;
using Windows.Foundation.Metadata;
using Windows.Media.Capture;
using Windows.Media.Devices;
using Windows.Media.MediaProperties;
using Windows.Phone.UI.Input;
using Windows.Storage;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
 
namespace BasicCamera
{
    public sealed partial class MainPage : Page
    {
        // Provides functionality to capture the output from the camera
        private MediaCapture _mediaCapture;
 
        public MainPage()
        {
            InitializeComponent();
 
            Application.Current.Resuming += Application_Resuming;
 
            if (ApiInformation.IsTypePresent("Windows.Phone.UI.Input.HardwareButtons"))
            {
                HardwareButtons.CameraHalfPressed += HardwareButtons_CameraHalfPressed;
                HardwareButtons.CameraPressed += HardwareButtons_CameraPressed;
            }
        }
 
        private async void Application_Resuming(object sender, object o)
        {
            await InitializeCameraAsync();
        }
 
        protected override async void OnNavigatedTo(NavigationEventArgs e)
        {
            await InitializeCameraAsync();
        }
 
        private async Task InitializeCameraAsync()
        {
            if (_mediaCapture == null)
            {
                // Get the camera devices
                var cameraDevices = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture);
 
                // try to get the back facing device for a phone
                var backFacingDevice = cameraDevices
                    .FirstOrDefault(c => c.EnclosureLocation?.Panel == Windows.Devices.Enumeration.Panel.Back);
 
                // but if that doesn't exist, take the first camera device available
                var preferredDevice = backFacingDevice ?? cameraDevices.FirstOrDefault();
 
                // Create MediaCapture
                _mediaCapture = new MediaCapture();
 
                // Initialize MediaCapture and settings
                await _mediaCapture.InitializeAsync(
                    new MediaCaptureInitializationSettings
                    {
                        VideoDeviceId = preferredDevice.Id
                    });
 
                // Set the preview source for the CaptureElement
                PreviewControl.Source = _mediaCapture;
 
                // Start viewing through the CaptureElement 
                await _mediaCapture.StartPreviewAsync();
            }
        }
 
        private async void HardwareButtons_CameraHalfPressed(object sender, CameraEventArgs e)
        {
            // test if focus is supported
            if (_mediaCapture.VideoDeviceController.FocusControl.Supported)
            {
                // get the focus control from the _mediaCapture object
                var focusControl = _mediaCapture.VideoDeviceController.FocusControl;
 
                // try to get full range, but settle for the first supported one.
                var focusRange = focusControl.SupportedFocusRanges.Contains(AutoFocusRange.FullRange) ? AutoFocusRange.FullRange : focusControl.SupportedFocusRanges.FirstOrDefault();
 
                // try to get the focus mode for focussing just once, but settle for the first supported one.
                var focusMode = focusControl.SupportedFocusModes.Contains(FocusMode.Single) ? FocusMode.Single : focusControl.SupportedFocusModes.FirstOrDefault();
 
                // now configure the focus control with the range and mode as settings
                focusControl.Configure(
                    new FocusSettings
                    {
                        Mode = focusMode,
                        AutoFocusRange = focusRange
                    });
 
                // finally wait for the camera to focus
                await focusControl.FocusAsync();
            }
        }
 
        private async void HardwareButtons_CameraPressed(object sender, CameraEventArgs e)
        {
            // This is where we want to save to.
            var storageFolder = KnownFolders.SavedPictures;
 
            // Create the file that we're going to save the photo to.
            var file = await storageFolder.CreateFileAsync("sample.jpg", CreationCollisionOption.ReplaceExisting);
 
            // Update the file with the contents of the photograph.
            await _mediaCapture.CapturePhotoToStorageFileAsync(ImageEncodingProperties.CreateJpeg(), file);
        }
    }
}

Of course, there’s still a bit more to be done – this code doesn’t handle resource clean-up, or deal with what happens when the application is suspended or loses focus. We’ll look at that next time.