Intégration IoT : Contrôle Arduino à distance via applications Windows 10 UWP
Composants et fournitures
| Arduino UNO | ×1 |
| Module Bluetooth SparkFun BlueSMiRF Silver (version Gold utilisée) | ×1 |
À propos du projet
Note : Voir les mises à jour dans les commentaires en bas.
Une application Windows 10 UWP peut être construite sur la bibliothèque Remote-Wiring pour interagir avec un appareil Arduino exécutant Firmata. Une application, similaire à l'exemple « Blinky » de Windows Remote Arduino mais avec des fonctionnalités supplémentaires, est développée. Elle effectue des GPIO (sortie ET entrée) ainsi que des E/S analogiques. Cette application est fonctionnellement identique à la version Windows 8.1 du blog précédent de cette série. Ce blog reprend le même matériel (le répète largement) que le précédent mais dans le contexte Universal Windows Platform (UWP) plutôt que Windows 8.1 Universal App. Les cibles sont : bureau Win 10, téléphone Win 10 et Raspberry PI2 (sous Win 10 IoT) — cette dernière cible est un « travail en cours ». Ce blog peut être lu sans référence au précédent.
Ce projet est détaillé sur mon blog : https://embedded101.com/...
L'exemple Windows Remote Arduino « Blinky » se trouve sur ms-iot.github.io.
Applications Universelles et Applications Universal Windows Platform
Les applications universelles (UA) ont atteint leur apogée avec Windows 8.1. On pouvait implémenter des applications ciblant Windows bureau Intel, Surface ARM RT et Windows Phone (ARM), toutes dans la même solution. Elles partageaient du code commun (gestionnaires d'événements, calculs généraux, données). Le code XAML devait être spécifique à la cible. On compilait simplement les sous-projets séparés pour chaque cible.
Avec le changement de paradigme « One Windows » dans Windows 10, le même code pour toutes les cibles, y compris le XAML, peut être utilisé. Le même projet a juste besoin d'être recompilé pour différentes cibles. Comme le nom UA s'appliquait aux apps Windows 8, un nouveau nom était nécessaire pour les apps vraiment universelles. D'où « Universal Windows Platform apps » pour Windows 10.
Toutes les plateformes Windows 10 supportent les apps UWP. Mais il y a des extensions spécifiques à chaque plateforme. Par exemple, les extensions Windows 10 IoT supportent GPIO, I2C, SPI, etc. Les extensions Mobile supportent les fonctions téléphoniques. UWP fournit une couche API de base garantie sur tous les appareils.
Les SDK d'extension Windows 10. Les extensions Bureau, Mobile et IoT sont cochées.
Pour ce blog, nous utilisons le template UWP plutôt que UA comme dans le blog précédent. Nous n'avons besoin d'aucun SDK d'extension.
[1] Configurer la communication Bluetooth avec l'appareil Arduino
Vous pouvez sauter cette section si vous avez déjà fait l'activité Win 8.1.
USB ou Bluetooth peuvent être utilisés pour les communications Firmata entre l'appareil Arduino et l'appareil Windows. Pour Windows 10, les deux sont possibles, alors que pour Windows 8.1 seul Bluetooth l'est. Pour cette version de l'app, Bluetooth sera utilisé. J'ai utilisé un Sparkfun Bluetooth Mate Gold alors que l'exemple « Blinky » utilise le Silver. La différence principale : portée jusqu'à 100m pour le Gold contre 10m pour le Silver. Les paramètres de handshaking par défaut sont aussi différents. Les deux ont une interface UART TTL utilisable pour configurer le mode de fonctionnement du module Bluetooth et pour interagir avec le port série de l'Arduino.






Si vous devez configurer le module Bluetooth, un adaptateur USB-Serial Sparkfun, Freetronics ou équivalent peut être utilisé avec un terminal série sur PC. Vous pouvez aussi réinitialiser le module aux paramètres d'usine en connectant la broche PIO6 (en fait PIO4) au niveau haut, et basculer trois fois.
Le Bluetooth Mate a le même brochage que le Sparkfun FTDI Basic, ils sont interchangeables. Vous ne pouvez pas brancher directement le Bluetooth Mate sur un FTDI Basic (il faut inverser TX et RX). Cette configuration peut être utilisée avec un terminal série sur PC, le FTDI en USB, pour configurer le module Bluetooth (ou l'utiliser pour communications série depuis le PC).
Paramètres série TTL UART par défaut :
- Baud rate 115 200
- 8 bits
- Pas de parité
- 1 bit de stop
- Contrôle de flux matériel activé (sur Mate Silver : Aucun)
- Profil Port Série (SPP) : FireFly-WXYZ où WXYZ = 4 derniers chiffres de l'adresse MAC BT
- Code d'accès 1234
Note : l'appareil peut stocker jusqu'à 8 appariements.
Documentation du module Bluetooth : https://www.sparkfun.com/...
La configuration Firmata utilise un baud rate de 57600 qu'il faut changer ou configurer le module Bluetooth pour cela. Pour cet exercice, nous modifierons la configuration Firmata (approche plus simple). Le contrôle de flux matériel peut être géré en configurant le module Bluetooth, mais ici il est géré en reliant RTS à CTS.
Bien que le module Bluetooth puisse être monté sur plaque d'essai et connecté à l'Arduino depuis là, j'ai choisi de monter une prise pour celui-ci sur un shield de prototypage.
Un connecteur shield Arduino 6 broches a été soudé sur le module Bluetooth aux broches UART TTL avec la prise vers l'extérieur. Les broches ont été pliées à 90° vers le bas pour que le module se branche verticalement dans un autre connecteur shield. La prise BT peut alors se connecter directement à un module FTDI Basic monté de même si configuration requise. Un fil a été soudé plus tard sur PIO6 (PIO4) pour la réinitialisation d'usine.
Un connecteur shield 8 broches a été monté au milieu du shield de prototypage en bas. Ajoutez aussi des connecteurs sur les bords extérieurs pour le brancher directement sur l'Uno.
Le module Bluetooth est ensuite inséré face aux broches GPIO, vers les broches 0 et 1 (Rx/Tx), laissant l'emplacement jaune libre. L'un d'eux peut servir d'emplacement temporaire pour le fil de réinitialisation d'usine.
[2] Configurer Firmata
Vous pouvez sauter cette section si vous avez déjà fait l'activité Win 8.1.
Note : Les broches UART 0 et 1 de l'Arduino Uno sont indisponibles lors de la programmation via USB depuis l'IDE Arduino. Ces mêmes broches sont connectées à l'interface UART TTL du module Bluetooth quand il est interfacé pour les communications Firmata. Par conséquent, quand l'Arduino doit être programmé dans cette section, le module Bluetooth ne doit PAS être connecté.
- En supposant que vous ayez déjà développé pour un Arduino (Uno), créez un nouveau shield Standard Firmata :
- Un changement : le Baud rate. Dans l'IDE, recherchez 57600. Remplacez par 115200. Sauvegardez le sketch, je l'ai appelé
Firmata_115200. Programmez l'Uno et c'est fait.
[3] Configurer la pile logicielle Firmata pour l'application universelle
Cette section est seulement légèrement différente si vous avez déjà fait l'activité Win 8.1.
La pile logicielle comprend trois couches :
- L'API Remote-Wiring implémente propriétés (configuration), méthodes et événements à un niveau conceptuel haut pour l'interaction matériel Arduino. Ex: GPIO (Get/Set Pin, On Pin Changed, etc.). Elle communique avec la couche Firmata via le protocole Firmata.
- Firmata communique vers le bas via le protocole série implémenté comme couches de transport Bluetooth et USB-Serial dans la couche Serial. L'option USB n'est pas disponible pour Windows 8.1.
Cette pile logicielle est disponible de deux sources :
Les deux contiennent versions Windows 8.1 et Windows 10. Bien que les deux versions Windows 10 compilent, j'ai trouvé que la seconde ne compile pas pour Windows 8.1. J'ai utilisé Visual Studio 2015 RC :
- Microsoft Visual Studio Community 2015 RC
- Version 14.0.22823.1 D14REL
- Microsoft .NET Framework Version 4.6.00076
- Téléchargez la première version. Pour ce faire correctement, clonez le dépôt (ne téléchargez pas le zip) :
git clone --recursive https://github.com/ms-iot/windows-remote-arduino-samples.git
La structure de répertoire obtenue :
windows-remote-arduino-samples
remote-wiring
Microsoft.Maker.win8_1
Microsoft.Maker.win10
source
win8_1
win10
Les deux derniers dossiers (win8_1 et win10) sont des exemples d'apps (dont « blinky ») qu'on ignorera pour l'instant. Les deux versions Maker utilisent le même dossier source, donc pour Windows 10 nous avons besoin de :
windows-remote-arduino-samples
remote-wiring
Microsoft.Maker.win10
source
Dans un dossier approprié, suggéré à la racine du disque (ex: c:\wras10) car j'ai eu des erreurs avec une compilation ARM dues à des noms de chemins trop longs. Vous pouvez aussi copier les fichiers .md pour référence, ouvrables dans VS.
- Ouvrez le fichier solution dans
Microsoft.Maker.win10 - Ciblez Win32 et compilez la solution. Trois compilations sont faites (une par couche de la pile).
- Faites de même pour la configuration ARM. Si vous avez une machine x64, essayez aussi cette compilation.
[4] Créer l'application UWP HW LED
Il y a un « raccourci » dans cette section pour ceux qui ont fait l'activité Win 8.1 précédente.
Pour cette version initiale, un bouton logiciel allume une LED matérielle et un autre l'éteint. La LED sera connectée à la broche GPIO 5.
La documentation « Blinky » dit qu'il y a plusieurs façons d'obtenir et d'utiliser ces bibliothèques. Finalement NuGet sera la voie mais ce n'est pas encore dispo. Vous pouvez référencer ces versions compilées de manière générale sur votre système de développement. La méthode la plus simple est d'ajouter l'application universelle requise à la solution et de les référencer. Nous utiliserons cette méthode.
- Ajoutez une nouvelle application universelle C# Windows Blank à la solution. (Note : pas Windows 8.1 cette fois) :

Donnez-lui un nom approprié. J'ai appelé la mienne wrauwp : Windows Remote Arduino Universal app UWP.
Notez qu'il n'y a qu'UN seul projet créé (UWP). Le XAML et le code C# sont identiques pour les versions bureau et mobile. La différence est dans la compilation.
Les capacités Serial et Bluetooth sont nécessaires dans le manifeste du package :
- Ouvrez
package.appmanifestdans l'éditeur de texte (pas son GUI) via « Voir le code ». La capacité Internet Client est incluse en bas. Modifiez cette section :
<Capabilities>
<Capability Name="internetClient" />
<DeviceCapability Name="bluetooth.rfcomm">
<Device Id="any">
<Function Type="name:serialPort"/>
</Device>
</DeviceCapability>
</Capabilities>
</Package>
Si nous utilisions USB-Serial au lieu de Bluetooth-Serial sur le bureau, nous ajouterions une capacité pour cela.
Une référence à chacune des couches logicielles est requise :
- Ajoutez les références Firmata, RemoteWiring et Serial pour l'application universelle bureau (une seule fois car un seul projet) :

ASTUCE : Pour ceux qui ont déjà fait le Windows 8.1 précédent, vous pouvez maintenant court-circuiter ce qui suit :
- Copiez le code XML du grid de ce projet vers
MainPage.xamldans ce nouveau projet. - Vous pouvez maintenant passer au test de l'app sur les cibles.
Pour ceux qui continuent ici …
- Modifiez le XAML Grid des deux UA pour :
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Button Name="OffButton" Click="OffButton_Click" Grid.Row="0" IsEnabled="False" HorizontalAlignment="Stretch" Foreground="White" Background="Green" FontSize="32">Off!</Button>
<Button Name="OnButton" Click="OnButton_Click" Grid.Row="1" IsEnabled="False" HorizontalAlignment="Stretch" Foreground="White" Background="Red" FontSize="32">On!</Button>
</Grid>
Commentaire Nous n'avons qu'un seul MainPage.cs cette fois, car un seul projet d'app… One Windows. Précédemment il y en avait un pour le bureau et un pour le téléphone, qu'on rendait commun en plaçant une version dans le sous-projet partagé.
Tout le code cs fera référence à MainPage.cs
- Dans la classe MainPage, ajoutez les déclarations suivantes au début :
// Usb non supporté sur Win8.1. Pour les étapes de connexion USB, référez-vous à la solution win10.
BluetoothSerial bluetooth;
RemoteDevice arduino;
// Broches utilisées. Note : numéros de broches réels.
private const int LED_PIN = 5;
- Dans le constructeur MainPage, après InitializeComponent() :
bluetooth = new BluetoothSerial("FireFly-748B");
arduino = new RemoteDevice(bluetooth);
bluetooth.ConnectionEstablished += OnConnectionEstablished;
Remplacez FireFly-748B par votre SPP.
- Implémentez OnConnectionEstablished en ajoutant la méthode suivante à la classe :
private void OnConnectionEstablished() {
// Activer les boutons sur le thread UI !
var action = Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, new Windows.UI.Core.DispatchedHandler(() => {
this.OnButton.IsEnabled = true;
this.OffButton.IsEnabled = true;
arduino.pinMode(LED_PIN, PinMode.OUTPUT);
}));
}
- Ajoutez enfin les gestionnaires d'événements pour les boutons :
private void OnButton_Click(object sender, RoutedEventArgs e) {
// Allumer la LED connectée à la broche 5
arduino.digitalWrite(5, PinState.HIGH);
}
private void OffButton_Click(object sender, RoutedEventArgs e) {
// Éteindre la LED connectée à la broche 5
arduino.digitalWrite(5, PinState.LOW);
}
- Testez la compilation de l'app UWP en configurations x86, x64 et ARM.
[5] Déploiement et test des applications universelles
Dans cette section, nous câblerons la LED matérielle sur l'Arduino et lancerons l'app sur le bureau et un téléphone Windows 10*.
Test sur votre bureau
- Définissez l'app Bureau comme projet de démarrage.
- Ciblez x86 et Local Machine. Recompilez l'app UWP bureau.

- Connectez la broche Arduino 5 à une LED matérielle. Fournissez GND, VCC et une résistance série adaptée.
Comme mentionné dans un blog précédent concernant le Windows 10 IoT Raspberry PI 2 GPIO, j'utilise une carte de développement pour mes tests d'E/S (LEDs, interrupteurs, etc.). Si vous n'en avez pas, vous pouvez utiliser la configuration matérielle « Blinky » mais vous devrez inverser la polarité du réglage de broche dans les gestionnaires de boutons.
- Alimentez l'Arduino et appuyez le module Bluetooth avec votre bureau (Code=1234). Je suppose que vous savez faire cela.
- Lancez l'app.
- Il demandera probablement si l'app peut se connecter au module Bluetooth… OK.
- Testez la fonctionnalité. Placez un point d'arrêt dans les gestionnaires de boutons et vérifiez que le débogage fonctionne.
- Répétez 4.1 à 4.6 pour x64 si vous avez un bureau 64 bits.
- Désactivez le Bluetooth sur votre bureau.
Maintenant testez votre téléphone Windows 10, en supposant qu'il est configuré pour le développement.
- Allumez le téléphone, allez dans Paramètres/Bluetooth et activez-le. Appairez avec le module Bluetooth (Code = 1234).
- Continuant avec l'app Windows Universal comme projet de démarrage…
- Ciblez ARM, Device et recompilez.
- Connectez le téléphone via USB Série au bureau et déployez l'app.
Maintenant testez le Raspberry PI 2
CECI EST UN TRAVAIL EN COURS. VOIR NOTE À LA FIN DE CETTE SECTION
- Le débogueur distant est déjà installé et actif sur le RPI2 configuré pour Win 10 IoT.
- Déterminez l'adresse IP du RPI2, ex: avec Windows IoT Core Watcher.

- Dans Propriétés du projet-Débogage, définissez la cible sur Machine distante, Aucune authentification, et entrez l'adresse IP.

- Recompilez l'app UWP.
- Déployez et testez l'app sur le RPI2.
Je n'ai pas encore réussi à connecter la version RPI2 via Bluetooth :
- Le Bluetooth n'est pas encore supporté dans l'ensemble
- Laissez des commentaires si vous avez des idées ou du succès avec cela.
- Je mettrai à jour quand je ferai des progrès.
Le dongle Bluetooth est chargé sur le RPI2 :

[6] « Embellir » l'interface utilisateur
Ce qui suit va améliorer l'UI et ajouter des boutons Connexion et Déconnexion Bluetooth.
- Modifiez le code XAML du Grid UI :
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="32"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Button Name="ConnectButton" Click="ConnectButton_Click" Grid.Row="0" IsEnabled="True" HorizontalAlignment="Stretch" BorderBrush="Lime" Foreground="Lime" FontSize="32">Connect</Button>
<Button Name="OffButton" Click="OffButton_Click" Grid.Row="1" IsEnabled="False" HorizontalAlignment="Stretch" Foreground="White" Background="Green" FontSize="32">Off!</Button>
<Button Name="OnButton" Click="OnButton_Click" Grid.Row="2" IsEnabled="False" HorizontalAlignment="Stretch" Foreground="White" Background="Red" FontSize="32">On!</Button>
<Button Name="DisconnectButton" Click="DisconnectButton_Click" Grid.Row="3" IsEnabled="False" HorizontalAlignment="Stretch" Foreground="Red" BorderBrush="Red" FontSize="32">Disconnect</Button>
<ProgressRing x:Name="progress1" Grid.Row="5" Height="50" Visibility="Visible"/>
</Grid>
L'UI a des boutons plus grands et plus colorés pour une meilleure utilisabilité. J'en suis arrivé là après l'avoir testée avec ma petite-fille de 4 ans !.
Le ProgressRing est visible et tourne pendant que l'app se connecte.
- Insérez à la fin de
OnConnectionEstablished():
// BT connecté donc éteindre le progress ring
this.progress1.IsActive = false;
this.progress1.Visibility = Visibility.Collapsed;
- Ajoutez les gestionnaires pour les boutons Connect et Disconnect :
private void ConnectButton_Click(object sender, RoutedEventArgs e) {
// Ces paramètres n'importent pas pour Bluetooth-Arduino Firmata, sauf SerialConfig.SERIAL_8N1
bluetooth.begin(115200, SerialConfig.SERIAL_8N1);
this.ConnectButton.IsEnabled = false;
// Connexion BT donc afficher progress ring
this.progress1.IsActive = true;
this.progress1.Visibility = Visibility.Visible;
}
private void DisconnectButton_Click(object sender, RoutedEventArgs e) {
bluetooth.end();
this.OnButton.IsEnabled = false;
this.OffButton.IsEnabled = false;
this.ConnectButton.IsEnabled = true;
this.DisconnectButton.IsEnabled = false;
}
- Mettez en commentaire ou supprimez la ligne suivante du constructeur MainPage car elle est maintenant dans le gestionnaire du bouton Connect :
bluetooth.begin(115200, SerialConfig.SERIAL_8N1);
- Ajoutez la gestion d'état suivante au gestionnaire OnButton :
this.OffButton.IsEnabled = true;
this.OnButton.IsEnabled = false;
- Et ceci au gestionnaire OffButton :
this.OffButton.IsEnabled = false;
this.OnButton.IsEnabled = true;
- Déployez et testez l'app sur les 3 (4) cibles comme dans la section 5.
[7] Ajouter une entrée poussoir
Dans cette extension aux apps universelles Windows 8.1, une entrée GPIO poussoir, sur la broche Arduino 5, est gérée et son état affiché dans l'UI. L'entrée sera initialement détectée en lisant périodiquement la valeur. La fonctionnalité sera ensuite améliorée en implémentant un gestionnaire pour l'événement DigitalPinChanged.
- Modifiez le contrôle Grid dans le code XAML UI :
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="32"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Button Name="ConnectButton" Click="ConnectButton_Click" Grid.Row="0" IsEnabled="True" HorizontalAlignment="Stretch" BorderBrush="Lime" Foreground="Lime" FontSize="32">Connect</Button>
<Button Name="OffButton" Click="OffButton_Click" Grid.Row="1" IsEnabled="False" HorizontalAlignment="Stretch" Foreground="White" Background="Green" FontSize="32">Off!</Button>
<Button Name="OnButton" Click="OnButton_Click" Grid.Row="2" IsEnabled="False" HorizontalAlignment="Stretch" Foreground="White" Background="Red" FontSize="32">On!</Button>
<Button Name="DisconnectButton" Click="DisconnectButton_Click" Grid.Row="3" IsEnabled="False" HorizontalAlignment="Stretch" Foreground="Red" BorderBrush="Red" FontSize="32">Disconnect</Button>
<ProgressRing x:Name="progress1" Grid.Row="5" Height="50" Visibility="Visible"/>
<TextBox Name="TxtPin6" Visibility="Visible" Grid.Row="6" Text="Pushbutton: HIGH"></TextBox>
</Grid>
- Dans la classe MainPage, spécifiez la broche d'entrée :
// Dans les déclarations en haut de la classe, ajoutez la broche d'entrée :
private const int PB_PIN = 6;
// Dans le gestionnaire OnConnectionEstablished, mettez-la en entrée :
arduino.pinMode(PB_PIN, PinMode.INPUT);
- Ajoutez un timer pour sonder l'entrée :
// Dans les déclarations en haut de la classe :
// En mode sondage, le timer échantillonne les entrées
private DispatcherTimer pbPolltimer;
// Dans le constructeur, configurez le timer :
this.pbPolltimer = new DispatcherTimer();
this.pbPolltimer.Interval = TimeSpan.FromMilliseconds(250);
this.pbPolltimer.Tick += PBTimer_Tick;
this.pbPolltimer.Stop();
// Ajoutez son gestionnaire d'événement tick :
PinState pbPinValue = PinState.LOW;
private void PBTimer_Tick(object sender, object e) {
PinState pbPinValueTemp = arduino.digitalRead(6);
Pushbutton_Pressed(pbPinValueTemp);
}
// Implémentez PushButton_Pressed() :
private void Pushbutton_Pressed(PinState pbPinValueTemp) {
if (pbPinValue != pbPinValueTemp) {
// Écrire la valeur si changée
TxtPin6.Text = "Pushbutton: " + pbPinValueTemp.ToString();
pbPinValue = pbPinValueTemp;
}
}
- Il nous faut un interrupteur poussoir. Heureusement ma carte de développement en fournit, j'utilise donc celle-ci. Sinon, implémentez le circuit opposé.
Avec le Win 10 IoT Raspberry PI 2 (RPI2), il a été signalé qu'il y a des bugs sur la fréquence d'enregistrement des entrées numériques, qui seront corrigés dans la RTM pour Win 10 IoT.
La fonctionnalité sera ensuite améliorée en implémentant un gestionnaire pour l'événement DigitalPinChanged.
L'antirebond peut être amélioré matériellement :
- Mettre un petit condensateur aux bornes de l'interrupteur pour ajouter un antirebond matériel comme délai RC.
- Ajouter un trigger de Schmitt à ce circuit.
Avec le RPI2, il y a une option pour ajouter l'antirebond par configuration logicielle.

- Compilez, déployez et testez l'app sur les cibles comme précédemment.
Ajoutons maintenant une LED simulée logiciellement dans l'UI pour afficher l'état de l'interrupteur.
- Ajoutez au XAML Grid dans les deux apps universelles :
- Ajoutez une autre RowDefinition (en bas) :
<RowDefinition Height="Auto"/>
// Ajoutez le contrôle ellipse suivant à cette rangée :
<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" />
- Ajoutez deux définitions de pinceaux de couleur dans les déclarations de la classe MainPage :
// Couleurs pour l'ellipse quand le poussoir matériel est pressé/relâché
private SolidColorBrush redBrush = new SolidColorBrush(Windows.UI.Colors.Red);
private SolidColorBrush grayBrush = new SolidColorBrush(Windows.UI.Colors.LightGray);
- Implémentez la manipulation de la LED avec ces couleurs :
- Dans le constructeur de la classe, définissez sa couleur initiale :
// Démarrer avec couleur éteinte pour l'ellipse
this.PBStatusLED.Fill = grayBrush;
// Dans PushButtonPressed(), définissez sa couleur selon l'état du bouton :
switch (pbPinValue) {
case PinState.HIGH:
this.PBStatusLED.Fill = redBrush;
break;
case PinState.LOW:
this.PBStatusLED.Fill = grayBrush;
break;
}
- Compilez, déployez et testez les apps sur les cibles… Voilà !
Maintenant améliorons ce code en utilisant l'événement numérique.
- Mettez en commentaire tout le code lié au timer, mais laissez la fonction PushButtonPressed() ; d'où la raison de la séparer du gestionnaire tick du timer.
- Ajoutez la spécification du délégué d'événement à
OnConnectionEstablished()dans l'action :
arduino.AnalogPinUpdatedEvent += Arduino_AnalogPinUpdated;
Nous pourrions essayer d'implémenter le gestionnaire d'événement ainsi :
private async void Arduino_DigitalPinUpdated(byte pin, PinState pinValue) {
if (pin == PB_PIN) {
Pushbutton_Pressed(pinValue);
}
}
Mais cela échoue car l'événement s'exécute dans un thread séparé du thread UI principal. C'est le même problème que dans .NET Windows Forms if (InvokeRequired).
- Implémentez le gestionnaire d'événement ainsi :
private async void Arduino_DigitalPinUpdated(byte pin, PinState pinValue) {
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => {
if (pin == PB_PIN) {
Pushbutton_Pressed(pinValue);
}
});
}
- Compilez, déployez et testez les apps sur les cibles. Voilà !
[8] Ajouter une entrée analogique
Cette extension ajoute une barre de progression à l'UI pour afficher le niveau d'un potentiomètre dans le matériel. L'entrée analogique se fait via A0, broche 14.
Ma carte de développement fournit un potentiomètre pour cela, sinon implémentez ce circuit :

Les broches d'entrée analogique sont broche 14 (A0) à broche 19 (A5).
arduino.pinMode(ANALOG_PIN, PinMode.ANALOG);
Le commentaire ci-dessus est pertinent. La signature du gestionnaire d'événement fournit l'index de la broche analogique (0 à 5) pas le numéro de broche.
Les valeurs analogiques vont de 0 à 1024. (10 bits)
// Note : Il faut le numéro de broche réel, pas l'index analogique :
arduino.pinMode(ANALOG_PIN, PinMode.ANALOG);
- Réactivez le timer de sondage et désactivez l'événement poussoir dans la classe MainPage.
- Dans le contrôle Grid du code XAML UI, ajoutez une autre rangée et une ProgressBar :
<ProgressBar x:Name="analogBar" Value="0" Margin="10" Maximum="255" Height="32" IsIndeterminate="False" Grid.Row="8" Foreground="Green"/>
- Ajoutez le code de la broche analogique :
- Déclarez la broche au début de la classe MainPage :
private const int ANALOG_PIN = 14;
// Mettez son mode à analogique dans OnConnectionEstablished() comme ci-dessus
- Ajoutez au gestionnaire d'événement tick du timer :
// Note : Le numéro de broche pour AnalogRead est l'index analogique
int PinValue = arduino.analogRead(ANALOG_PIN - 14);
this.analogBar.Value = PinValue;
- Compilez, déployez et testez l'app sur les cibles. Faites varier le potentiomètre et observez les changements de la ProgressBar.
Maintenant la version pilotée par événements
- Remettez en commentaire le code du timer de sondage.
- Ajoutez la spécification du gestionnaire d'événement analogique à
OnConnectionEstablished():
// Note : Il faut le numéro de broche réel, pas l'index analogique :
arduino.pinMode(ANALOG_PIN, PinMode.ANALOG);
- Ajoutez la méthode de gestionnaire d'événement
Arduino_DigitalPinUpdated:
private async void Arduino_AnalogPinUpdated(byte pin, ushort PinValue) {
// Note : Le numéro de broche est l'index analogique
if (pin == ANALOG_PIN - 14) {
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => {
this.analogBar.Value = PinValue;
});
}
}
Notez que la mise à jour UI doit à nouveau être faite de façon asynchrone.
- Compilez, déployez et testez l'app sur les cibles.
[9] Ajouter une sortie PWM
La mise en œuvre d'une sortie analogique en PWM pour piloter une LED (variée via un curseur) est laissée au lecteur.
- Broches PWM : 3, 5, 6, 9, 10, 11
- Pour définir une broche en PWM :
arduino.pinMode(PWM_PIN, PinMode.PWM) - Pour définir un niveau PWM :
arduino.analogWrite(byte, ushort) - Les valeurs analogWrite vont de 0 à 255 (paramètre ushort)
Je pourrais fournir une solution plus tard.
[1] J'ai en fait utilisé une version antérieure retirée du module Bluetooth, mais la fonctionnalité semble identique.
Code
- WindowsRemoteArduino_Win10.zip
WindowsRemoteArduino_Win10.zip C#
Version étendue de « Blinky »
Entrée, Sortie, Entrée Analogique
UI plus élaborée
Aperçu non disponible (téléchargement uniquement).
Schémas

Processus de fabrication
- Construire une télécommande universelle Raspberry Pi professionnelle avec LIRC
- Construire une porte à reconnaissance faciale sécurisée avec Windows IoT et Raspberry Pi
- Surveillance Précise de Température et Humidité avec SHT15 sur Windows 10 IoT Core
- Installation de Windows 10 IoT Core sur Raspberry Pi 3 Model B+ : Guide Étape par Étape
- Étendre GoPiGo v2 sur Windows 10 IoT Core pour Raspberry Pi 3
- Applications et appareils essentiels pour les équipes de chaîne d'approvisionnement à distance
- Construire une télécommande Android universelle avec Arduino, 1Sheeld et contrôle IR
- Maîtriser la conception de circuits imprimés pour l'Internet des objets : Guide complet
- Cisco lance une surveillance IoT gérée dans le cloud pour les environnements IT et OT