This blog is a Tutorial on how to implement Win 10 IoT Universal Apps that make use of Raspberry PI 2 (RPI2) General Purpose Input Output (GPIO) pins. This covers:
The interrupt (event driven) version addresses the InvokeRequired pattern in the XAML context. (Controls can't be updated directly from another thread).
In this tutorial you will create 5 versions of a Universal App that interacts with the RPI2 GPIO pins. The projects should also be able to run on the Minnow board but might need to make some changes to the GPIO Pins used. The RPI2 apps use GPIO5 and GPIO6.
You will create a Blank UA project. Note that the template is the same Blank template used for the desktop. It's a Universal app so its supposed to run "universally".
Its not the Windows IoT Core – Background Application (IoT). That is another beast!
Being UA the app can be recompiled for various targets, the desktop, a Windows Phone or an IoT device. Note that RT is not an option as the Surface 1 and 2 won't get a Win 10 version.The target is x86/x64 for the desktop (or Minnow) or ARM for the RPI2. You change that when on the Toolbar at the top:
Also you select the device from that Toolbar:
For the RPI2 you choose Remote Machine and insert the IPAddress and set no authentication:
The IPAddress is displayed on the RPI2 screen,, once booted or can be determined over a PowerShell connection,
To simplify matters, the XAML code is supplied so it can be pasted directly into the MainPage.xaml in the source View.
It is suggested that you configure the XANL editor to show the designer in full window (no split view) default to Sourece View and turn off "Run project code in XAML Designer. Interaction with XAML pages is easier that way; no more waiting for the Designer to load when you open an XAML page:
The XAML supplied is for the screen size 13.3" Desktop (1280 x 720) 100% scale. That is selectable at top left in Designer Window
The app takes user input as a clicked or pressed event via an XAML button control, an active circular graphic and finally as a hardware push button. When pressed, the RPI2 image visibility toggles and the DateTime gets updated (What is the significance of 29 July 2015 ??).
There is a complication with the fifth app,which if you have done much hardware oriented UI development in .NET (particularly the Compact Framework) you will be aware that the only thread that can update a UI control is the main UI thread. Other threads have to signal it to do their updates.. Read up on InvokeRequired. This issue is resolved using Async code with the fifth app.
You can short circuit the development of one or more of the projects by downloading the complete solution in source from Codeplex:
"Windows 10 IoT Samples": https://IoTSampler.Codeplex.com
You will need a RPI2, a breadboard, a led and a pushbutton. You will also need a Windows 10 development system with Visual Studio 2015 and the IoT extensions installed.. The RPI2 will need to have the Win10 IoT installed. Look at getting started at: http://ms-iot.github.io/content/en-US/GetStarted.htm
I use a "Basic Stamp Professional Development Board" for my IO:
This version of the app flashes an external LED in sync with the GUI ellipse. For that you will need a suitable LED circuit.
With the development board I am using for my IO, there is an an array of 16 LEDS that each take single bit input and turn on with a logic high. .. Simple.
if you don't have something similar you will need to set up a suitable LED in series with a current limiting resistor. An example in the "Getting Started" documentation is at http://ms-iot.github.io/content/en-US/win10/samples/Blinky.htm
This though uses the GPIO 5 pin as a current sink and so a logic low turns the LED on. If you use that circuit then you will need to reverse the polarity *=(change pin highs to low and pin lows to high) in the code in this section.
The default maximum sink current is 8mA although it can be configured to be up to 16 mA. Output source current limitation are similar.
Sink or source current? If you sink then the Vcc for the LED does not need to come from the microprocessor and can even be higher than the 3.3V limit of the RPI2, provided the current limiation is correct.
A warning though,, RPI2 pins should not experience a voltage greater than 3.3V, although there is a 5V supply pin available.
FYI, this link discusses the RPI2 GPIO pin electrical characteristics:
"GPIO Electrical Specifications, Raspberry Pi input and output pin voltage and current capability"
We now need to add the IoT Extensions. This give us access to the GPIO features:
In this version of the app, an external push button is polled. When button press is detected the click event is called.
For this you will need a push button circuit that is normally low, but goes high when the push button is pressed This is input to GPIO 6.
Note that the input voltage must be limited to 3.3V not 5V. My IO development board is 5V based so I can either put a suitable resistor in series (say 10K) or use a level shifter such as the Freetronics Logic Level Coverter Moduler.
if you are creating your own circuit on breadboard you might implement it with the following circuit:
The Push Button Circuit,
A suitable resistor would be, say 10K. Although the switch debounce is set in software a small capacitor across the switch can help.
The app is improved in this version of the app by generating an interrupt on GPIO 5 when the button is pressed.
This is captured in the C# code by the pin ValueChanged event handler.
In version 4 of the app, the poll timer tick event handler could directly update the UI controls as it runs in the same thread as the UI.
The interrupt occurs as a separate thread and so the app will fail if the PB ValueChanged event handler calls button_click directly. Try it.
This is the exactly the same problem that will occur in .NET CF with hardware buttons where you had to use the
if (control.InvokeRequired) pattern.
The async code above is the equivalent in this context.
OK Beppe, Thanks for the feedback.
Great job David !! If you agree, I'll use as exercise in next courses :-) Beppe