magnify
Home Contribution Communiquer avec un GPS Bluetooth, quelques améliorations
formats

Communiquer avec un GPS Bluetooth, quelques améliorations

Dans un précédent article j’ai abordé la communication avec un périphérique Bluetooth en utilisant comme exemple la communication avec un GPS.

Comme j’étais en train de découvrir la nouvelle manière de lire des données en provenance d’un socket (StreamSocket) je n’avais pas utilisé la manière la plus simple ni la plus efficace.

Dans ce nouvel article, je vais apporter quelques améliorations à la méthode utilisée.

En creusant encore un peu le sujet, je me suis rendu compte que ma méthode était loin d’être la meilleure. Et tant mieux car perso je n’en étais pas super satisfait.

En 1er lieu, il faut passer par un DataReader pour lire les données en provenance du StreamSocket. On donne au DataReader l’InputStream utilisé par le StreamSocket pour collecter les données entrantes et on paramètre de DataReader pour qu’il effectue une lecture partielle des données.

 

DataReader wReader = new DataReader(_StreamSocket.InputStream);
wReader.InputStreamOptions = InputStreamOptions.Partial;

En d’autres termes, si on demande de lire 100 octets et qu’il n’y en a que 50 dans le buffer d’entrée, le DataReader va lire les 50 octets et rendre la main au lieu d’attendre la vie des rats que les 100 octets soient effectivement disponibles. Ca arrange bien nos affaires cette histoire.

La lecture en elle-même est très simplifiée. Il suffit de dire combien on veut lire d’octets maximum et on reprend la main quand on a lu au maximum ce nombre d’octets. Simple et rapide.

La fonction de lecture est asynchrone, donc pour l’attendre on n’oublie pas de placer le petit await qui va bien devant. La fonction retourne le nombre d’octets effectivement lus.

Si elle retourne zéro c’est que rien n’était disponible dans le buffer d’entrée. Suivant les matériels connectés ça peut vouloir dire qu’il ne cause plus pour le moment (il boude par exemple) ou alors qu’il n’est plus connecté. Dans le cas d’un GPS, qui est je vous le rappelle un appareil très bavard, le fait de ne plus recevoir de données signifie souvent qu’il n’est plus là pour le faire.

 

// Lecture de 300 octets
uint r = await wReader.LoadAsync(300);

Une fois qu’on a des données disponibles dans le buffer d’entrée, il suffit d’aller les récupérer de la manière qui convient le mieux en utilisant le DataReader et ses fonctions de récupération (ReadByte, ReadBytes, ReadDouble, etc…). C’est lui qui s’occupe d’aller puiser le bon nombre d’octets dans le buffer d’entrée pour récupérer les informations dans le format que vous souhaitez (sympa le mec).

Dans le cas du GPS nous devons récupérer les données sous la format de caractères ASCII. Malheureusement la méthode ReadString ne convient pas car elle lit la chaîne en UTF8 ou en Unicode, mais ne sais pas le faire en ASCII. En fait le format ASCII a été retiré des formats proposés dans System.Text.Encoding. Quelle idée ???

Donc nous allons récupérer les octets comme si c’était de simples caractères ASCII et construire une chaîne ASCII, à la mano, comme le faisait mon grand père.

 

// On prépare le buffer de réception
// La variable r contient le nombre d'octets lus du StreamSocket

byte[] wBuffer = new byte[r];

// On récupère les données 

wReader.ReadBytes(wBuffer);

// On transforme ces données en string ASCII

string wString = "";

for (int i = 0; i < r; i++)
{ 
    wString += (char)wBuffer[i];
}

// Dans wString on a maintenant les données lues sous forme d'une chaîne de caractères

Ensuite il suffit de traiter ces informations comme dans l’article précédent pour afficher les trames NMEA envoyées par le GPS.

Il suffit alors de reboucler pour lire le flot suivant de caractères et le tour est joué. Plus besoin de timer pour effectuer la lecture à intervalles réguliers. On est toujours en mode pooling car nous ne sommes pas notifié de la disponibilité de nouveaux octets dans le buffer d’entrée, mais ce pooling-ci est plus « souple » que celui que je vous avais précédemment proposé.

Idéalement, il faudrait gérer un timeout. En effet, comme expliqué un peu plus haut, quand le périphérique est déconnecté, il cesse d’envoyer des données, mais aucune erreur n’est levée au moment où l’on essaye de notre coté de lire de nouvelles données, on n’a seulement comme indice le fait que la fonction de lecture du DataReader retourne zéro.

Au bout d’un certain temps, il sera donc nécessaire d’en conclure que la liaison est rompue. La durée de ce timeout dépendra du comportement « normal » du périphérique auquel vous êtes connectés. Par exemple, pour le GPS Hollux que j’ai utilisé, une absence de données pendant plus d’une seconde n’est pas normale, le timeout sera donc compris en 1000 et 1500 millisecondes.

Si j’en ai le courage, j’ajouterai ce timeout dans un prochain article. En tous cas, si cela vous intéresse, n’hésitez pas à me le demander, ce sera pour moi la meilleure des motivations.

Sources de cet article.

 

 

 
 Share on Facebook Share on Twitter Share on Reddit Share on LinkedIn
No Comments  comments 

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *