A Windows 10 UWP app can be built upon the Remote-Wiring library such that the app can interact with an Arduino device running Firmata. An app, similar to the Windows Remote Arduino “Blinky” example, but with feature additions, is developed. It performs GPIO (output AND input) as well as some analog IO. This app is functionally the same as Windows 8.1 version in the previous blog in this series. This blog works through the same material (ie repeats much of it) as the previous blog but from the Universal Windows Platform (UWP) context rather Windows 8.1 Universal App context. The target for the app is Win 10 desktop, Win 10 phone and Raspberry PI2 (running Win 10 IoT). The latter target is a "work-in-progress though".This blog can be read without reference to the previous blog.
The Windows Remote Arduino “Blinky” example is at ms-iot.github.io.
Link to the previous blog: Windows 8.1 Windows Remote Arduino and Universal apps
Now available:. Full solution for this tutorial is on Codeplex at :https://iotsampler.codeplex.com/releases/view/615805
Universal apps (UA) reached their zenith in Windows 8.1 You could implement apps targeted at Windows Intel desktop, the ARM RT Surface and the Windows Phone (ARM), all in the same solution. They could share common code such as event handlers, general computation and data. XAML code had to be specific to the target. You just compiled the separate subprojects for each target. During the compilations, the common code was included.
With the “One Windows” paradigm shift in Windows 10 the same code for all targets, including the XAML code can be used for all targets. The same project just needs to be recompiled for different targets. With the UA name applied to Windows 8 apps, a new name was needed for the truly universal apps. Hence the name Universal Windows Platform apps was coined for Windows 10.
All Windows 10 platforms support UWP apps. But there are extensions specific to the each platform. For example Windows 10 IoT extensions support GPIO, I2C, SPIO etc. Mobile extensions support phone functions. Etc. UWP provides a guaranteed core API layer across all devices.
The Windows 10 Extension SDKs. The Desktop, Mobile and IoT extensions are checked.
For tis blog we use the UWP template rather than the UA as in the previous blog. We don't need any of the extension SDKs.
You can skip this section if you have already done the Win 8.1 activity.
USB or Bluetooth can be used for the Firmata communications between the Arduino device and the Windows device. For Windows 10 both can be used, whereas for Windows 8.1 only Bluetooth can be used. For this version of the app, Bluetooth will be used. I used a Sparkfun Bluetooth Mate Gold[1] whereas the Sparkfun Bluetooth Mate Silver was used with the “Blinky” example referenced above. The main difference is the range of the Gold is up to 100m whereas that of the Silver is 10m. The default handshaking settings are also different. These both have a TTL level UART interface that can be used both for configuring the operating mode of the Bluetooth device and for interacting with the Arduino serial port.
Figure 1 Sparkfun Bluetooth Mate Gold
Figure 2 Bluetooth Mate Gold Pins, including factory reset
If you need to configure the Bluetooth device, a Sparkfun or Freetronics USB-Serial or Free device can be used to configure the device via a desktop serial terminal. You can also factory reset the device to default settings by connecting the PIO6 (its actually PIO4) pin to high, and toggle three times.
Bluetooth Mate has the same pin out as the Sparkfun FTDI Basic, and so they can be used interchangeably. you cannot directly plug the Bluetooth Mate to an FTDI Basic board (you’ll have to swap TX and RX). That configuration can be used with a desktop serial terminal, with the FTDI device USB connected to the desktop, to configure the Bluetooth device (or to use Bluetooth device for serial communications from the desktop.
The default TTL UART serial settings are:
Note that the device can store up to 8 device parings.
The documentation for the Bluetooth device is at: http://www.sparkfun.com/datasheets/Wireless/Bluetooth/rn-bluetooth-um.pdf
The Firmata configuration is for a Baud rate of 57600 which needs to be changed or the Bluetooth device configured for that. For this exercise, we will modify the Firmata configuration, which is the easier approach. The Hardware flow of control also can be handled by configuring the Bluetooth device, but for this exercise is handled by connecting RTS to CTS.
Whist the Bluetooth device can be mounted on a Breadboard and connected to the Arduino device from there, I elected to mount a socket for it on a Prototyping Shield.
A 6 pin Arduino Shield Header was soldered onto the Bluetooth device at the TTL UART pins with the socket facing outwards. The pins were bent 900 downwards so that the device can be plugged vertically into another shield header. The BT socket then can be used to directly connect it to similarly mounted FTDI Basic module if configuration is required. A wire was later soldered to PIO6 (PIO4) on the Bluetooth module, for factory resetting.
Figure 3 Bluetooth Module with shield header at UART pins, and shield headers
An 8 shield header was mounted in the middle of the prototype shield at the bottom. Also add headers at the outside of the shield so that it can plug directly into the Uno.
Figure 4 Arduino Prototype Shield for mounting the Bluetooth module
The Bluetooth module is then inserted facing the GPIO pins, towards the pins 0 and 1 (Rx/Tx)., leaving the yellow location clear. One of those can be used a temporary location for the factory reset wire.
Figure 6 Mounted Bluetooth module on Arduino device
Note: The Arduino Uno’s UART Pins 0 and 1 are unavailable when it is being programmed via USB from the Arduino IDE. These same pins are what are connected to the Bluetooth module’s TTL UART interface when it is interfaced for Firmata communications. Therefore, when the Arduino device is to be programmed in this section, the Bluetooth device should not be connected.
2.1 Assuming that you have previously developed for an Arduino (Uno) device, create a new Standard Firmata shield:
2.2 There is one change to be made, the Baud rate. In the IDE, do a search for 57600. Replace it 115200. Save the Sketch, I called it Firmata_115200. Program the Uno and this part is done.
This section only slightly different that already done the Win 8.1 activity.
The software stack consists of three layers:
The Remote-Wiring API implements properties (configuration), methods and event at a conceptually high level for Arduino hardware interaction. For example, GPIO (eg Get and Set Pin, On Pin changed etc). It communicates with the Firmata layer using the Firmata protocol. Firmata communicates down the stack via the serial protocol that is implemented as Bluetooth and USB-Serial transport layers in the Serial layer. The USB option isn’t available for Windows 8.1.
This software stack called is available for two sources:
Both contain Windows 8.1 and Windows 10 versions. Whilst both versions’ Windows 10 versions will build, I have found that the second one’s Windows 8.1 won’t build. I used the Visual Studio 2015 RC version:
3.1 Download the first version. To do so properly, you need to clone the repository (don’t download the zip):
git clone --recursive https://github.com/ms-iot/windows-remote-arduino-samples.git
The directory structure of what you get is:
windows-remote-arduino-samples
o
remote-wiring
Microsoft.Maker.win8_1
Microsoft.Maker.win10
source
win8_1
o win10
win10
The latter two folders (win8_1 and win10) are just example apps (including the “blinky” example) which we will ignore for now. Both Maker versions make use of the same sources folder so for Windows 10 we need just:
to a suitable folder. I suggest one at the root of the drive, say, c:\wras10 as I have found that you can get some errors with an ARM build to do with path names being too long. You might want to also copy the .md files for reference. These can be opened in VS.
3.2 Open the solution file in Microsoft.Maker.win10
3.3 Set the target to Win32 build the solution.
Three builds are done. One for each of the three layers in the software stack..
3.4 Do same for the ARM configuration. If you have an x64 machine, then you might like to try that build as well.
There is a "short-circuit" in this section for those who have done the previous Win 8.1 activity.
For this initial version of the app/s, a software button will turn a hardware LED on and another will turn it off. The LED will be connected to GPIO pin 5.
The “Blinky” documentation says that there are a number of ways to get and use these libraries. Ultimately Nuget will be the way but that is not yet available. You can reference these built versions in a general manner on your development system, The easiest way is to just add the required Universal app to the solution and reference them. We will use that method.
4.1 Add a new C# Windows Blank Universal app to the solution. (Note not Windows 8.1 this time):
Give it a suitable name. I called mine wrauwp: Windows Remote Arduino Universal app UWP. Note that this time there is only ONE project created (UWP).. The XAML and CSharp code is the same for the desktop and mobile versions of the app. The difference is in how it is compiled.
The Serial and Bluetooth capabilities are needed in the pacakage manifest:
4.2 Open the package.appmanifest in the text editor (not its GUI) by View Code. The Internet Client capability is included at the bottom. Modify this section to:
and save it. We only have one project to do this to this time.. Note that its is slightly different to the Win 8.,1 version.
Also, if we were using USB-Serial rather than Bluetooth-Serial on the desktop, we would add a capability for that.
A reference to each of the relevant software layers is required:
4.3 Add references Firmata, RemoteWiring and Serial for the desktop UA (again only need do this for one project):
HINT: For those who have already done the previous Windows 8.1 you can now short-circuit what follows:
For those continuing here …
4.4 Modify both UA’s Grid XAML to:
Comment We only have one MainPage.cs this time, as there is only one app project…One Windows. Previously there was one for the desktop and one for the phone, which we made common by placing one version in the share subproject.
All cs code will refer to MainPage.cs
4.7 In the MainPage class add the following declarations at the top of the class:
4.8 in the MainPage constructor, after InitializeComponent() add:
Replace FireFly-748B with your SPP.
4.9 Implement OnConnectionEstablished by add the following mthod to the class:
4.10 And finally add the event handlers for the buttons to the class:
4.11 Test build the UWP app in x86, x64 and ARM configurations
In this section we will wire up the hardware LED to the Arduino device and run the app on the desktop, and a Windows 10 Phone* * I don't have a Windows 10 Phone at the moment. Can't risk updating it. So let me know how you go if you can test it, thanks.
Test on your desktop
5.1 Set the Desktop app as the Startup Project
5.2 Set the target to x86 and Local Machine. Rebuild the desktop UWP app
5.3 Connect the Arduino Pin 5 to a hardware LED. Provide GND, VCC and a suitable resistor in series.
5.4 Power up the Arduino device and pair up the Bluetooth module with your desktop (Passkey=1234). .. I’ll assume you know how to do this.
5.5. Run the app.
5.6 It will probably ask you whether it’s OK for the app to connect to the Bluetooth device .. OK
5.7 Test the functionality of the app. Set a breakpoint in the button handler/s and check that you can debug.
5.8 Repeat 4.1 to 4.6 for x64 if you have a 64 bit desktop.
5.9 Turn off Bluetooth on your desktop
Now to test your Windows 10 Phone, assuming the phone is configured for development.
5.10 Turn on your phone, go to Settings/Bluetooth and turn it on. Pair with the Bluetooth module (Passkey = 1234).
5.11 Continuing with the Windows Universal app as the startup project ..
5.12 Set the Target to ARM,, Device and rebuild
5.11 Connect up the phone via USB Serial to the desktop and deploy the app.
5.12 Test run the app and check the functionality. You are now “wireless” .. Cool Set a breakpoint in the button handler/s and check that you can debug.
Now to test the Raspberry PI 2
THIS IS A WORK IN PROGRESS. SEE NOTE AT END OF THIS SECTION
5.13 The Remote debugger is already installed and active on the RPI2 configured for Win 10 IoT.
Although installation sets up suitable Firewall rules, I normally turn off the Firewall for development, on the target. 5.14 Determine the IP address of the RPI2, eg with the Windows IoT Core Watcher
5.15 In Project Properties-Debug set the target to Remote Machine, No authentication and enter the IP address
5.16 Rebuild the UWP app
5.17 Deploy and test the app on the RPI2.
I haven't got the RPI2 version to connect over Bluetooth yet:
The Bluetooth dongle is loaded on the RPI2
The following will pretty up the UI and add Bluetooth Connect and Disconnect buttons.
6.1 Modify the UI GRID XAML code to (PS: Note change to previous buttons grid rows):
The UI has larger buttons and is more colorful providing better usability. I arrived at this after user testing it with my 4 year old granddaughter!.
The ProgressRing is visible and circulates whilst the app is connecting.
6.2 Insert at the bottom of OnConnectionEstablished() :
6.3 Add the following handlers for the Connect and DisConnect buttons:
6.4 Comment out or remove the following line from MainPageConstructor as its now in the Connect button handler:
bluetooth.begin(115200, SerialConfig.SERIAL_8N1);
6.5 Add the following state management to the OnButton handler
6.6 And the following to the OffButton handler:
6.7 Deploy and test the app on all three (4) targets as in section 5
In this extension to the Windows 8.1 Universal apps, a pushbutton GPIO input, at Arduino Pin 5, is facilitated and its state is displayed in the UI. The input will initially be sensed by periodically reading the value. The functionality will then be improved by implementing a handler for the DigitalPinChanged event
7.1 Modify the Grid control in the UI XAML code for both UA as follows:
7.2 In the MainPage class specify the the input pin:
- In declarations at the top of the class add the input pin:
- In the OnConnectionEstablished handler set it to input::
7.3, Add a timer to poll the input as follows:
- In declarations at the top of the class:
- In the constructor set the timer:
- Add its timer tick event handler
- Implement PushButton_Pressed():
7.4 We need a pushbutton switch. Thankfully my development board provides these so I just use that. If you don’t have such a beast, then implement the circuit opposite.
With the Win 10 IoT Raspberry PI 2 (RPI2), it has been reported that there are some bugs with how often the digital inputs are registered, which will be fixed in the RTM for Win 10 IoT.
Debouncing can be improved for this situation in hardware by:
- Put a small capacitor across the switch to add some hardware debouncing as an RC delay.
- Also add a Schmidt trigger to this circuit.
With the RPI2 there is an option to add debouncing through software configuration.
7.5 Build, deploy and test the app on the targets as previous
Let’s add a software simulated LED to the UI to display the state of the switch.
7.6 Add the following to the UI in the grid XAMLcode in both Universal apps:
- Add another Row Definition (at bottom )::
- Add the following ellipse control to that row:
7.7 Add two color brush definitions to the MainPage class declarations at the top:
7.8 Implement the LED’s manipulation with these colors as follows:
- In the class constructor set its initial color:
- In PushButtonPressed() set its color depending upon the button’s state:
7.9 Build, deploy and test the apps on the targets ..Wala!
Now to improve this code using the digital event.
7.10 Comment out all code to do with the timer, but leave the PushButtonPressed() function; hence the reason for separate to the timer tick event handler.
7.11 Add the event delegate specification to the OnConnectionEstablished() event handler within the action
We could try to implement the event handler as follows:
But this fail as the event runs in a thread separate to the main UI thread. This is the same issue as in .NET Windows Forms if (InvokeRequired) scenario.
7.12 Implement the event handler as follows
7.13 Build, deploy and test the apps on the targets. Wala
This extension to the app functionality adds a progress bar to the UA UI to display the level of a potentiometer in the hardware. The analog input is via A0, pin 14.
Again my development board provides a potentiometer for this purpose but if you don’t have such you need to implement this circuit:
The analog input pins are pins 14 (A0) to pin 19 (A5).
You set a pin in analog mode in OnConnectionEstablished() as per: // Note: Need actual pin number, not analog index: arduino.pinMode(ANALOG_PIN, PinMode.ANALOG);
The comment above is quite pertinent. The event handler signature provides the analog pin index (0 to 5) not the pin number.
You read the pin value as per: //Note: Analog Read Pin number IS the analog index int PinValue = arduino.analogRead(ANALOG_PIN-14);
Analog values range from 0 to 1024. (10 bit)
The event handler delegate is wired up in OnConnectionEstablished() as per: arduino.DigitalPinUpdatedEvent += Arduino_DigitalPinUpdated;
8.0 Re-enable the Poll timer and disable the Pushbutton event in the MainPage class
8.1 In the grid control in the UI XAML code add another row to the grid as previous and add a ProgressBar:
8.2 Add the Analog pin code as follows.
- Declare the pin at the top of MainPage class:
- Set its mode to analog in OnConnectionEstablished() as above
- Add the following to the timer tick event:
8.3 Build, deploy and test the app on the targets. Vary the potentiometer position and observe the ProgressBar changes.
Now for the event driven version
8.4 Again comment out the Poll Timer code.
8.5 Add the analog event handler delegate specification to OnConnectionEstablished():
8.6 Add the Arduino_DigitalPinUpdated event handler method:
Note that the UI update has again to be done asynchronously.
8.7 Build, deploy and test the app on the targets.
It is left to reader to implement analog output as PWM, to drive a LED (dimmed via a slider).
I might provide a solution to this at a later stage.
[1] I actually used a retired earlier version of the Bluetooth module, but functionality seems to be the same.
Hello! I have the same problem (vs2017) when i try to read a analog PIN. Im trying to read a temp sensor (LM35). "cannot convert from int to string" Did you solved the problem? Could you tell me how to solve it? My project: Raspberry pi 3 + Arduino UNO + VS2017 + C# UWP Thank you very much!
hel lo, i have a problem in the point 7.11 it gives me error 1061 here: arduino.AnalogPinUpdatedEvent += Arduino_AnalogPinUpdated; vs 2017 says: 'RemoteDevice' non contiene una definizione di 'AnalogPinUpdatedEvent' e non è stato trovato alcun metodo di estensione 'AnalogPinUpdatedEvent' che accetta un primo argomento di tipo 'RemoteDevice'. 8.1 and an error 1503 can't convert from int to string: int PinValue = arduino.analogRead(ANALOG_PIN-14);
LED Dimmer as PWM is now in the project code.