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 and Universal Windows Platform Apps

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.

clip_image001

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.

image
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.

[1] Set up the Bluetooth communication with the Arduino device.

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.

 

 

clip_image002_thumb

Figure 1 Sparkfun Bluetooth Mate Gold

clip_image004_thumb1

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:

  • · Baud rate 115,200
  • · 8 bits
  • · No Parity
  • · 1 stop bit
  • · Hardware flow control enabled (on Mate Silver this is None)
  • · Serial Port Profile (SPP): FireFly-WXYZ
    where WXYZ is the last 4 digits of the device's BT MAC Address.
  • · Passkey 1234

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.

clip_image006_thumb

clip_image008_thumb

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.

clip_image010_thumb2

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.

clip_image012_thumb1

Figure 6 Mounted Bluetooth module on Arduino device


[2] Set up Firmata

You can skip this section if you have already done the Win 8.1 activity.

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:

clip_image014_thumb1

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.


[3] Set up the Universal App Firmata software stack

This section only slightly different that already done the Win 8.1 activity.

The software stack consists of three layers:

clip_image016_thumb1

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:

  1. https://github.com/ms-iot/windows-remote-arduino-samples
  2. https://github.com/ms-iot/remote-wiring/

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:

  • Microsoft Visual Studio Community 2015 RC
  • Version 14.0.22823.1 D14REL
  • Microsoft .NET Framework
  • Version 4.6.00076

3.1 Download the first version. To do so properly, you need to clone the repository (don’t download the zip):

  • Install git or GitHub
  • In the git shell or GitHub Desktop Shell (it’s Powershell), enter the following from a suitable directory:

    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
      
    o win8_1
      
    o 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:

  • windows-remote-arduino-samples
      
    o remote-wiring
          
      Microsoft.Maker.win10
            
    source

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.


[4] Create the HW LED UWP app

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):

image

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:

In packkage.appmanifest
  1.   <Capabilities>
  2.     <Capability Name="internetClient" />
  3.     <DeviceCapability Name="bluetooth.rfcomm">
  4.       <Device Id="any">
  5.         <Function Type="name:serialPort"/>
  6.       </Device>
  7.     </DeviceCapability>
  8.   </Capabilities>
  9. </Package>

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):
image

 


HINT: For those who have already done the previous Windows 8.1 you can now short-circuit what follows:

  • Copy the grid xml code from that project to MainPage.xaml in this new project.
  • Copy everything in MainPage,cs to MainPage.cs in thisproject (overwrite it).
    You will need to set the namespace back to the name of your new app.
  • You can now skip to testing the app on the target/s

Open-mouthed smile

For those continuing here …

4.4 Modify both UA’s Grid XAML to:

MainPage.xaml: UI
  1. <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
  2.     <Grid.RowDefinitions>
  3.         <RowDefinition Height="Auto"/>
  4.         <RowDefinition Height="Auto"/>
  5.     </Grid.RowDefinitions>
  6.     <Button Name="OffButton" Click="OffButton_Click" Grid.Row="0" IsEnabled="False" HorizontalAlignment="Stretch" Foreground="White" Background="Green" FontSize="32">Off!</Button>
  7.     <Button Name="OnButton" Click="OnButton_Click" Grid.Row="1" IsEnabled="False" HorizontalAlignment="Stretch" Foreground="White" Background="Red" FontSize="32">On!</Button>
  8. </Grid>

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:

MainPage.cs Declarations
  1. //Usb is not supported on Win8.1. To see the USB connection steps, refer to the win10 solution instead.
  2. BluetoothSerial bluetooth;
  3. RemoteDevice arduino;
  4.  
  5. // The pins used. Note: Actual pinn numbers.
  6. private const int LED_PIN = 5;

4.8 in the MainPage constructor, after InitializeComponent() add:

In MainPage() the constructor
  1. bluetooth = new BluetoothSerial("FireFly-748B");
  2. arduino = new RemoteDevice(bluetooth);
  3. bluetooth.ConnectionEstablished += OnConnectionEstablished;

Replace FireFly-748B with your SPP.

4.9 Implement OnConnectionEstablished by add the following mthod to the class:

Add OnConnectionEstablished()
  1. private void OnConnectionEstablished()
  2. {
  3.     //enable the buttons on the UI thread!
  4.     var action = Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, new Windows.UI.Core.DispatchedHandler(() => {
  5.         this.OnButton.IsEnabled = true;
  6.         this. OffButton.IsEnabled = true;
  7.  
  8.         arduino.pinMode(LED_PIN, PinMode.OUTPUT);
  9.     }));
  10. }

4.10 And finally add the event handlers for the buttons to the class:

Add Button Event Handlers
  1. private void OnButton_Click(object sender, RoutedEventArgs e)
  2. {
  3.     //turn the LED connected to pin 5 ON
  4.     arduino.digitalWrite(5, PinState.HIGH);
  5. }
  6.  
  7. private void OffButton_Click(object sender, RoutedEventArgs e)
  8. {
  9.     //turn the LED connected to pin 5 OFF
  10.     arduino.digitalWrite(5, PinState.LOW);
  11. }

4.11 Test build the UWP app in x86, x64 and ARM configurations


[5] Deploying and testing the Universal apps.

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

clip_image0243
5.3 Connect the Arduino Pin 5 to a hardware LED. Provide GND, VCC and a suitable resistor in series.

As mentioned in a previous blog with respect to Windows 10 IoT Raspberry PI 2 GPIO I use a development board for implementing my testing IO such as LEDs, switches etc. If you do not have a similar board you might like to use the “Blinky” hardware configuration but you will need to reverse the polarity of pin setting in button handlers.

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 Open-mouthed smile
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

image

5.15 In Project Properties-Debug set the target to Remote Machine, No authentication and enter the IP address

image

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:

  • Bluetooth in the main isn't yet supported
  • I was able to add a CSR Bluetooth dongle and see it in the devices via the web app. See below.
    Possibly need to pair the BT device on the Arduino Uno in the RPI2 context.
  • The app downloaded and ran on the device, it just didn't connect. Sad smile
  • Please leave any comments if you have any ideas or success with this.
  • I'll update here when I make progress

image
The Bluetooth dongle is loaded on the RPI2


[6] “Pretty up” the UI

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):

Add two Buttons &amp;amp;amp;
  1. <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
  2.     <Grid.RowDefinitions>
  3.         <RowDefinition Height="Auto"/>
  4.         <RowDefinition Height="Auto"/>
  5.         <RowDefinition Height="Auto"/>
  6.         <RowDefinition Height="Auto"/>
  7.         <RowDefinition Height="32"/>
  8.         <RowDefinition Height="Auto"/>
  9.     </Grid.RowDefinitions>
  10.     <Button Name="ConnectButton" Click="ConnectButton_Click" Grid.Row="0" IsEnabled="True" HorizontalAlignment="Stretch" BorderBrush="Lime" Foreground="Lime" FontSize="32">Connect</Button>
  11.     <Button Name="OffButton" Click="OffButton_Click" Grid.Row="1" IsEnabled="False" HorizontalAlignment="Stretch" Foreground="White" Background="Green" FontSize="32">Off!</Button>
  12.     <Button Name="OnButton" Click="OnButton_Click" Grid.Row="2" IsEnabled="False" HorizontalAlignment="Stretch" Foreground="White" Background="Red" FontSize="32">On!</Button>
  13.     <Button Name="DisconnectButton" Click="DisconnectButton_Click" Grid.Row="3" IsEnabled="False" HorizontalAlignment="Stretch" Foreground="Red" BorderBrush="Red" FontSize="32">Disconnect</Button>
  14.     <ProgressRing x:Name="progress1" Grid.Row="5" Height="50" Visibility="Visible"/>
  15. </Grid>

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() :

In OnConnectionEstablished()
  1. //BT is connected so turn off progress ring
  2. this.progress1.IsActive = false;
  3. this.progress1.Visibility = Visibility.Collapsed;

6.3 Add the following handlers for the Connect and DisConnect buttons:

Add new button's eventhandlers
  1. private void ConnectButton_Click(object sender, RoutedEventArgs e)
  2. {
  3.     //these parameters don't matter for bluetooth- Arduino Firmata, except  SerialConfig.SERIAL_8N1
  4.     bluetooth.begin(115200, SerialConfig.SERIAL_8N1);
  5.     this.ConnectButton.IsEnabled = false;
  6.  
  7.     //Connecting BT so show progress ring
  8.     this.progress1.IsActive = true;
  9.     this.progress1.Visibility = Visibility.Visible;
  10. }
  11.  
  12. private void DisconnectButton_Click(object sender, RoutedEventArgs e)
  13. {
  14.     bluetooth.end();
  15.     this.OnButton.IsEnabled = false;
  16.     this.OffButton.IsEnabled = false;
  17.     this.ConnectButton.IsEnabled = true;
  18.     this.DisconnectButton.IsEnabled = false;
  19. }

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

In OnButton_Cllick()
  1. this.OffButton.IsEnabled = true;
  2. this.OnButton.IsEnabled = false;

6.6 And the following to the OffButton handler:

In OffButton_Click
  1. this.OffButton.IsEnabled = false;
  2. this.OnButton.IsEnabled = true;

6.7 Deploy and test the app on all three (4) targets as in section 5


[7] Add a Pushbutton input

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:

Add a textbox to UI
  1. <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
  2.     <Grid.RowDefinitions>
  3.         <RowDefinition Height="Auto"/>
  4.         <RowDefinition Height="Auto"/>
  5.         <RowDefinition Height="Auto"/>
  6.         <RowDefinition Height="Auto"/>
  7.         <RowDefinition Height="32"/>
  8.         <RowDefinition Height="Auto"/>
  9.         <RowDefinition Height="Auto"/>
  10.     </Grid.RowDefinitions>
  11.     <Button Name="ConnectButton" Click="ConnectButton_Click" Grid.Row="0" IsEnabled="True" HorizontalAlignment="Stretch" BorderBrush="Lime" Foreground="Lime" FontSize="32">Connect</Button>
  12.     <Button Name="OffButton" Click="OffButton_Click" Grid.Row="1" IsEnabled="False" HorizontalAlignment="Stretch" Foreground="White" Background="Green" FontSize="32">Off!</Button>
  13.     <Button Name="OnButton" Click="OnButton_Click" Grid.Row="2" IsEnabled="False" HorizontalAlignment="Stretch" Foreground="White" Background="Red" FontSize="32">On!</Button>
  14.     <Button Name="DisconnectButton" Click="DisconnectButton_Click" Grid.Row="3" IsEnabled="False" HorizontalAlignment="Stretch" Foreground="Red" BorderBrush="Red" FontSize="32">Disconnect</Button>
  15.     <ProgressRing x:Name="progress1" Grid.Row="5" Height="50" Visibility="Visible"/>
  16.     <TextBox Name="TxtPin6" Visibility="Visible" Grid.Row="6" Text="Pushbutton: HIGH"></TextBox>
  17. </Grid>

7.2 In the MainPage class specify the the input pin:

- In declarations at the top of the class add the input pin:

In MainPage Declarations
  1. private const int PB_PIN = 6;

- In the OnConnectionEstablished handler set it to input::

In OnConnectionEstablished
  1. arduino.pinMode(PB_PIN, PinMode.INPUT);

7.3, Add a timer to poll the input as follows:

- In declarations at the top of the class:

In MainPage Declarations
  1. // In Poll mode timer ticks sample the inputs
  2. private DispatcherTimer pbPolltimer;

- In the constructor set the timer:

In MainPage()
  1. this.pbPolltimer = new DispatcherTimer();
  2. this.pbPolltimer.Interval = TimeSpan.FromMilliseconds(250);
  3. this.pbPolltimer.Tick += PBTimer_Tick;
  4. this.pbPolltimer.Stop();

- Add its timer tick event handler

Add Poll Timer Tick handler
  1. PinState pbPinValue = PinState.LOW;
  2.  
  3. private void PBTimer_Tick(object sender, object e)
  4. {
  5.     PinState pbPinValueTemp = arduino.digitalRead(6);
  6.     Pushbutton_Pressed(pbPinValueTemp);
  7. }

- Implement PushButton_Pressed():

Add PushButton_Pressed()
  1. private void Pushbutton_Pressed(PinState pbPinValueTemp)
  2. {
  3.     if (pbPinValue != pbPinValueTemp)
  4.     {
  5.         //Write value if changed
  6.         TxtPin6.Text = "Pushbutton: " + pbPinValueTemp.ToString();
  7.         pbPinValue = pbPinValueTemp;
  8.     }
  9. }

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.

clip_image0293

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 )::            

  1. <RowDefinition Height="Auto"/>

- Add the following ellipse control to that row:

Add an ellipse to the UI
  1. <Ellipse x:Name="PBStatusLED" Fill="#FF96969B" Grid.Row="7" Stroke="Black" Width="64" IsRightTapEnabled="False" IsTapEnabled="True" IsDoubleTapEnabled="False" Height="64" VerticalAlignment="Top" HorizontalAlignment="Center" />

7.7 Add two color brush definitions to the MainPage class declarations at the top:

Add colors in the Declarations
  1. // Colors for ellipse when hardware pushbutton is pressed/not pressed
  2. private SolidColorBrush redBrush = new SolidColorBrush(Windows.UI.Colors.Red);
  3. private SolidColorBrush grayBrush = new SolidColorBrush(Windows.UI.Colors.LightGray);

7.8 Implement the LED’s manipulation with these colors as follows:

- In the class constructor set its initial color:

In the constructor
  1. //Start with off color for ellipse
  2. this.PBStatusLED.Fill = grayBrush;

- In PushButtonPressed() set its color depending upon the button’s state:

Add to Pushbutton_Pressed()
  1. switch (pbPinValue)
  2. {
  3.     case PinState.HIGH:
  4.         this.PBStatusLED.Fill = redBrush;
  5.         break;
  6.     case PinState.LOW:
  7.         this.PBStatusLED.Fill = grayBrush;
  8.         break;
  9. }

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

Add to OnConnectionEstablished
  1. arduino.AnalogPinUpdatedEvent += Arduino_AnalogPinUpdated;

We could try to implement the event handler as follows:

Invalid DigitalPinUpdated
  1. private async void Arduino_DigitalPinUpdated(byte pin, PinState pinValue)
  2. {
  3.     if (pin == PB_PIN)
  4.     {
  5.         Pushbutton_Pressed(pinValue);
  6.     }
  7. }

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

Add DigitalPinUpdated
  1. private async void Arduino_DigitalPinUpdated(byte pin, PinState pinValue)
  2. {
  3.  
  4.     await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
  5.     {
  6.         if (pin == PB_PIN)
  7.         {
  8.             Pushbutton_Pressed(pinValue);
  9.         }
  10.  
  11.     });
  12. }

7.13 Build, deploy and test the apps on the targets. Wala Open-mouthed smile


[8] Add an Analog Input

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:

clip_image030_thumb1

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:

Add a ProgressBar to the UI
  1. <ProgressBar x:Name="analogBar" Value="0" Margin="10" Maximum="255" Height="32" IsIndeterminate="False" Grid.Row="8" Foreground="Green"/>

8.2 Add the Analog pin code as follows.

- Declare the pin at the top of MainPage class:

Add the Analog Pin
  1. private const int ANALOG_PIN = 14;

- Set its mode to analog in OnConnectionEstablished() as above

- Add the following to the timer tick event:

Add to Timer Tick Handler
  1. //Note: Analog Read Pin number is the analog index
  2. int PinValue = arduino.analogRead(ANALOG_PIN-14);
  3. this.analogBar.Value = PinValue;

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():

Set Analog Pin Mode
  1. // Note: Need actual pin number, not analog ibndex:
  2. arduino.pinMode(ANALOG_PIN, PinMode.ANALOG);

8.6 Add the Arduino_DigitalPinUpdated event handler method:

Add AnalogPinUpdated
  1. private async void Arduino_AnalogPinUpdated(byte pin, ushort PinValue)
  2. {
  3.     //Note: Pin number is the analog index
  4.     if (pin == ANALOG_PIN -14)
  5.     {
  6.         await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
  7.         {
  8.             this.analogBar.Value = PinValue;
  9.         });
  10.     }
  11. }

Note that the UI update has again to be done asynchronously.

8.7  Build, deploy and test the app on the targets. Open-mouthed smile Red heart


[9] Add a PWM output

It is left to reader to implement analog output as PWM, to drive a LED (dimmed via a slider).

  • PWM pins:
    3, 5, 6, 9, 10, and 11
  • To set a pin as PWM:
    arduino.pinMode(PWM_PIN,PinMode.PWM)
  • To set a PWM level
    arduino.analogWrite(byte, ushort)
  • analogWrite values are from 0 to 255 (the ushort parameter)

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.