–
Mise à jour le 22/09/2017.Lorsque vous utilisez un Arduino, vous avez peut être besoin de récupérer des informations depuis celui ci sur votre PC.
Prérequis
Vous devez avoir Visual Studio installé sur votre PC. Si vous souhaitez reproduire notre article chez vous, il vous faudra également un arduino avec un système grove GPS afin de récupérer les trames GPGGA de celui ci.
Côté Arduino
Il faudra réaliser un montage très simple : reliez le 5v et gnd du module GPS à votre Arduino. Reliez ensuite la broche TX du GPS au pin D2 et la broche RX du GPS au pin D3 de l’arduino
Envoyez ensuite le programme Arduino suivant qui permettra de récupérer les trames GPGGA du GPS et qui les route vers le port série relié au PC
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
#include <SoftwareSerial.h> //Création de la variable SoftSerial (connexion software au port serie) RX sur le pin D2 et TX sur le pin D3 SoftwareSerial SoftSerial(2, 3); //On crée un tableau de caractères qui contiendra notre trame GPS unsigned char buffer[200]; //la variable count nous servira à ne pas dépasser les 200 caractères du tableau. int count=0; void setup() { //On initialise le port série software SoftSerial.begin(9600); //On initialise le port série de l'arduino Serial.begin(9600); } void loop() { //On récupère la trame GPS getGPS(); } void getGPS() { //Si le port série contient des données if (SoftSerial.available()) { char currentchar = '.'; //Dans cette boucle, on va attendre de recontrer le caractère $ qui indique un début de ligne while(SoftSerial.available()) { //On récupère un caractère depuis le port série char currentchar = SoftSerial.read(); //Si ce caractère est $, on est alors en début de trame if(currentchar == ' |
Côté PC : Création du projet Visual Studio
Lancez visual studio puis créez un nouveau projet Windows Forms Application. Vous verrez apparaître alors une fenêtre qui est la fenêtre de votre application.
Dans la boite à outils (toolbox), sélectionnez le composant SerialPort puis glissez-le sur votre fenêtre. Vous le verrez apparaître en bas de l’écran.
Insérez également deux boutons (un pour Connecter, un pour déconnecter), un numericUpDown (pour préciser le port COM) et un textbox (qui affichera les données de l’arduino) dont l’option multiline est active.
En double cliquant sur un bouton, vous entrez dans le code de son événement de clic. C’est ici que l’on doit coder ce qui doit se produire quand on clique sur le bouton.
Voici le code permettant de se connecter ou déconnecter du port com de l’arduino :
1 2 3 4 5 6 7 8 9 10 11 12 13 |
'Evenement déclenché quand on clique sur le bouton connecter Private Sub btnConnecter_Click(sender As Object, e As EventArgs) Handles btnConnecter.Click 'On indique le nom du port com à utiliser en concaténant "COM" avec le numéro sélectionné dans le controle numericupdown SerialPort1.PortName = String.Format("COM{0}", numPortSerie.Value) 'On ouvre la connexion série SerialPort1.Open() End Sub 'Evenement déclenché quand on clique sur le bouton déconnecter Private Sub btnDeconnecter_Click(sender As Object, e As EventArgs) Handles btnDeconnecter.Click 'On ferme la connexion série SerialPort1.Close() End Sub |
Dans la connexion, on indique quel est le port à utiliser sous la forme d’une chaîne de caractères (Exemple : COM8) puis on ouvre la communication. Dans le bouton déconnecter, on ferme la connexion série.
Afin de récupérer les données envoyées depuis l’arduino vers le PC, on va s’abonner à un événement du port série.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
'Evenement déclenché quand on reçoit des données sur le port série Private Sub SerialPort1_Receiving(sender As Object, e As IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived 'On lit la ligne complète SetText(SerialPort1.ReadLine().ToString()) End Sub 'Délégué permettant de mettre à jour l'interface graphique alors qu'on n'est pas sur le même thread Delegate Sub SetTextCallback(text As String) 'Gestion par délégué de la mise à jour de l'interface graphique Private Sub SetText(text As String) 'Si on constate qu'on n'est pas sur le bon thread If txtInputArduino.InvokeRequired Then 'On fait appel au délégué qui va pointer sur cette même fonction Dim d As New SetTextCallback(AddressOf SetText) Me.Invoke(d, New Object() {text}) Else 'Cas où on provient du délégué, on est sur le bon thread pour mettre à jour l'interface graphique AfficherLatitudeLongitude(text) End If End Sub |
SerialPort1_Receiving est l’événement qui indique que le port Série virtuel du PC a reçu des données. A chaque fois qu’il se déclenche, on va lire ces données puis les envoyer à la suite du texte déjà présent dans le textbox. Etant donné que la récupération sur le port série se passe sur un autre thread (processus) que celui de l’application, on ne peut pas directement mettre à jour l’interface graphique (afficher le texte) depuis l’évenement du port série sous peine d’avoir une erreur à l’exécution. On va donc passer depuis un délégué qui va se charger de transmettre l’information et mettre à jour l’interface graphique (partie avec le Delegate et méthode SetText).
Maintenant, nous allons récupérer indépendamment la latitude et la longitude et les afficher à l’écran.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
'Partie permettant de traiter l'information transmise par l'Arduino Private Sub AfficherLatitudeLongitude(trameGPGGA As String) 'On ajoute la nouvelle trame reçue à l'affichage dans le textbox txtInputArduino.Text = String.Format("{0}{1}", txtInputArduino.Text, trameGPGGA) 'Si la trame ne commence pas par $, on quitte la fonction If Not trameGPGGA.StartsWith("$") Then Exit Sub 'On coupe la trame à chaque virgule Dim parties As String() = trameGPGGA.Split(",") 'On récupère la partie longitude et la partie latitude et on remplace le . par , pour pouvoir les utiliser en tant que valeur numérique (culture fr-FR) Dim partielatitudeBrute As String = parties(2).Replace(".", ",") Dim partielongitudeBrute As String = parties(4).Replace(".", ",") 'Si une des deux valeurs est vide ou bien n'est pas numérique, on quitte la fonction If String.IsNullOrWhiteSpace(partielatitudeBrute) OrElse Not IsNumeric(partielatitudeBrute) Then Exit Sub If String.IsNullOrWhiteSpace(partielongitudeBrute) OrElse Not IsNumeric(partielongitudeBrute) Then Exit Sub 'On remet les données à la bonne echelle (on divise par 100) Dim partielatitude As String = CDec(partielatitudeBrute) / 100 Dim partielongitude As String = CDec(partielongitudeBrute) / 100 'On affiche les données LabelLatitude.Text = String.Format("Latitude : {0}", partielatitude) LabelLongitude.Text = String.Format("Longitude : {0}", partielongitude) End Sub |
Comme la communication série récupère les données par bribes, on doit donc recomposer les trames GPGGA pour pouvoir les traiter une à une. La fonction remplirTrame se charge de récupérer les données et reformer une trame GPGGA complète. Dès que la trame est complète, on va la traiter à l’aide de la fonction AfficherLatitudeLongitude pour découper la trame, récupérer les informations puis les convertir en affichage réutilisable.
Le code source en téléchargement |
Code source complet du programme
.
Code source à télécharger.
Pour utiliser l’application, réaliser le montage Arduino/GPS puis envoyer le programme de notre article sur le module GPS Grove. Connectez l’arduino au pc, lancez le programme GPS Localiser puis choisissez le port com correspondant à l’arduino. Cliquez sur connecter et attendez que les trames GPGGA apparaissent. Vous aurez alors la latitude et la longitude dès que le GPS aura accroché les satellites.
Réalisé par Steeve / Hervé