Étape 6: Le logiciel de Windows...
Le logiciel de Windows a été écrit à l’aide de Microsoft Visual Studio 2015 mise à jour 1. C’est une application axée sur la boîte de dialogue MFC C++ native créée à l’aide de l’Assistant de boîte de dialogue MFC. L’interface - utilisateur de la boîte de dialogue a été créé à l’aide de l’éditeur de ressources. Le corps du code est généré par l’Assistant. Je soulignerai uniquement les éléments qui démontrent la communication avec l’Arduino. Le reste du code est disponible dans github ici :
https://github.com/alsliahona/CO2LaserWaterFlowMonitor/
Trouver l’Arduino port série « COM »
Maintenant que nous avons largement progressé au-delà des jours de MODEMs, il n’est pas fréquent d’avoir plusieurs ports COM en cours d’utilisation sur PC Windows. Il est toutefois possible que vous ayez des périphériques USB comme votre Arduino qui utilisent un COM port comme une interface série. Nous pouvons énumérer tous les ports COM disponibles sur le PC facilement à l’aide d’une boucle qui appelle QueryDosDevice. Une fois que nous avons une liste de ports COM nous pouvons présenter la liste de l’utilisateur ce qui leur permet de sélectionner celui qui est leur contrôleur de flux de l’eau. S’il y a qu’un seul élément dans la liste nous pouvons l’ouvrir automatiquement. Pour commencer puis, nous ajoutons un conteneur à la classe CCO2WaterFlowDlg. C’est sur la ligne 50 du CO2WaterFlowDlg.h, comme un std::map de deux chaînes. La première chaîne (la clé) est le port COM que nous afficher et ouvrir. L’autre chaîne est le nom du périphérique DOS, dont nous gardons surtout pour le diagnostic.
La méthode déclarée ligne 54 est utilisée pour remplir le conteneur. Il est implémenté dans CO2WaterFlowDlg.cpp, lignes 70-78 :
BuildCOMPortMap() est appelée lorsque l’application démarre et s’est construite une instance de CCO2WaterFlowDlg, comme vous pouvez le voir sur la ligne 94 ci-dessus. À ce stade, tout dispositif de COM présents sur le système sera dans notre conteneur.
Lorsque la boîte de dialogue initialise d’abord elle vérifie dans OnInitDialog() pour voir si il y a des ports COM disponibles. Si ce n’est pas le cas, une invite s’affiche à l’utilisateur, leur demandant de plug-in, le contrôleur de vitesse de flux. Ce message se répéter jusqu'à ce que l’utilisateur clique sur Annuler, ou un dispositif de COM est présent. Voir la boucle sur les lignes 146-155 ci-dessous :
La liste des périphériques disponibles s’affichera dans la liste déroulante (ComboBox). Pour cela, lorsque RefreshCOMList() est appelé sur la ligne 161 ci-dessus. Le code pour cela est assez standard MFC pour peupler un ComboBox. Il est indiqué ci-dessous :
Lignes 296 301 claires entrées dans la zone de liste déroulante, tout en lignes 304 par l’intermédiaire de 309 ajoutent chaque élément du conteneur à la zone de liste déroulante. Un autre récipient, m_COMSelectionMap est maintenu qui associe le port COM de l’identificateur d’entrée de zone de liste déroulante. Lorsque l’utilisateur clique sur Ouvrir, cela servira à extraire le nom du port COM pour ouvrir.
À la ligne 310, le dernier élément ajouté à la zone de liste modifiable est sélectionné.
Si seulement un point figure dans la liste (ligne 312), cet élément est automatiquement ouvert en simulant un utilisateur clic sur le bouton Ouvrir (ligne 316).
Ouverture du port COM
Lorsque l’utilisateur clique sur le bouton Ouvrir, ou lorsque OnBnClickedButtonOpen() est appelé par RefreshCOMList() l’élément actuellement sélectionné de la zone de liste déroulante est utilisée pour obtenir le nom du port COM (lignes 221 et 222 ci-dessous) :
Sur la ligne 223 à la tentative faite pour ouvrir le port série. En cas d’échec l’utilisateur vous demandera et seront autorisés à sélectionner un nouvel élément. Si toutefois nous réussir à ouvrir le port COM, lignes 230-232 permet de désactiver les boutons Open et Scan Ports et active le bouton définir le seuil. Une fois que le port COM a été ouvert, une minuterie est réglée au feu toutes les 1/8 de seconde. Le gestionnaire de minuterie utilise m_SerialPort pour lire la dernière mise à jour (si disponible) de l’eau Flow Monitor et il met à jour l’état affiché dans la boîte de dialogue.
Les ScanPorts bouton ne fait rien plus que rappellent systématiquement BuildCOMPortMap() et RefreshCOMList().
La classe ArduinoSerial
La classe de ArduinoSerial s’occupe de tout associé d’ouverture, de clôture, lecture et écriture à l’Arduino via le port série. Il est spécialement conçu pour l’eau Flow Monitor, mais peut être facilement adapté pour les besoins de remplacement. Il est défini dans ArdSerial.h comme suit :
Notez que la classe est automatique lors de l’initialisation car nous ne voulons pas essayer d’ouvrir le port COM jusqu'à ce que nous savons ce qu’il faut sélectionner. Lorsque Close() est appelée le port COM sera fermé que m_hSerial est passé à CloseHandle() et m_bConnected sera mis en revenir à false. Parce qu’il s’agit d’une classe RAII, il sera automatiquement nettoyer (par exemple fermer le handle) quand c' est le destructeur est appelé--pour cela appeler Close().
Nous avons vu précédemment où la méthode Open() est invoquée dans OnBnClickedButtonOpen() de CCO2WaterFlowDlg.cpp [ligne 223 du CO2WaterFlowDlg.cpp]. Vous remarquerez que m_SerialPort est une instance de ArduinoSerial comme l’a annoncé sur la ligne 52 de CO2WaterFlowDlg.h :
CreateFile et réglage des paramètres COM
Ouverture de l’appareil, lorsque nous connaîtrons le port COM, il suffit d’appeler CreateFile suivie d’appels à GetCOMState et SetCOMState qui définissent le débit en bauds et autres paramètres de série. Lignes 26 à 50 ci-dessous montrent l’appel CreateFile et l’invite de l’utilisateur en cas d’échec :
Avec le port ouvert nous obtenir l’état de COM et réglez-le pour utiliser une vitesse de 9600 bauds (n’hésitez pas à changer cela, si vous aimez, mais correspond à la modification dans votre sketch Arduino!) Tout le programme d’installation restant du port COM est illustré ci-dessous. Bien qu’il ressemble à beaucoup de code, il n’est pas grand chose à expliquer :
Notez l’appel à PurgeComm sur ligne 87 et le sommeil en ligne 89. Chaque fois que vous branchez sur le port série de l’Arduino l’appareil se réinitialise.
Lecture et l’écriture vers/depuis l’Arduino
Parce que nous avons délibérément gardé la communication avec l’Arduino très simple, le ArduinoSerial lu et méthodes d’écriture sont limitées à la lecture complète, null résilié la ligne de texte et d’écrire un octet unique. Vous avez peut-être remarqué la déclaration de notre tampon de lecture sur la ligne 45 de ArdSerial.h ainsi que la fonction de membre privé que readavailable() déclarée à la ligne 47. ReadAvailable est utilisée pour ajouter de nouvelles données du port série dans notre mémoire tampon. Il ressemble à ceci :
(Notez le commentaire sur la ligne 124 est un report de l’exemple de l’Arduino Serial ici :
http://playground.arduino.cc/Interfacing/CPPWindows). Ligne 122 un tampon temporaire est alloué à la taille de quels matches les octets accessibles en lecture indiquée par l’appel à ClearCommError à la ligne 114. À la ligne 126 ces octets sont lus dans notre tampon temporaire (vArray). Et sur les lignes 131 à 134, ces octets sont ajoutées au m_vBuffer.
ReadAvailable() est appelée chaque fois qu’on l’appelle ReadNullZString(), et ReadNullZString transfère simplement la première chaîne terminée par null dans la mémoire tampon à la sortie strRead :
L’écriture à l’Arduino est très simple--et c’est en grande partie parce que nous devons ne jamais envoyer un octet unique, utilisé pour mettre à jour la valeur de seuil :
L’attachant à l’Interface utilisateur
La minuterie qui a été mentionnée précédemment, qui déclenche toutes les 1/8 de seconde appellera m_Serial.ReadNullZString(). Lorsqu’une chaîne est disponible il sera ensuite analyser la chaîne et mettre à jour l’Interface utilisateur. Ceci est illustré dans la partie ci-dessous. (Parcourir le code github pour voir le reste du code)
Une chose importante à noter... Le « débit » affiché est basé sur les spécifications pour le capteur de vitesse de débit. Si vous utilisez un capteur de vitesse de flux différents, ajuster les maths en démarrant à la ligne 275 selon les spécifications de la sonde.
Fixer le seuil
La dernière chose à couvrir est comment nous envoyer le nouveau seuil à l’Arduino. Vous avez probablement déjà deviné basé sur le code ci-dessus, que nous appelons simplement m_SerialPort.WriteByte() avec le nouveau seuil. Vous serait correct. Le code est très simple, comme vous pouvez le voir ci-dessous :
En ligne 329, la valeur de seuil est lire à partir de l’interface utilisateur et convertie en un octet à la ligne 330 et envoyée à l’Arduino à la ligne 331. Vous vous souviendrez de l’esquisse de l’Arduino que ceci interrompt la boucle principale, régler le seuil d’alarme et puis redémarrez la boucle principale.