Protocole de communication
Maintenant que l'on est capable d'utiliser le module radio nRF24L01+, on va pouvoir poursuivre le projet de système de surveillance des niveaux sonores aux alentours d'un aéroport. Pour rappel, l'Arduino est responsable de la récolte des données à partir de différents capteurs et les communique à une Raspberry Pi, via les airs avec le module radio et de manière régulière, pour qu'elles puissent y être traitées.
Pour que l'Arduino et la Raspberry Pi se comprennent, il faut se mettre d'accord sur un protocole de communication entre elles. Dans notre cas, on va simplement avoir besoin d'une communication unidirectionnelle de l'Arduino vers la Raspberry Pi. Plusieurs données étant envoyées par l'Arduino, il faut choisir comment elles seront structurées au sein de chaque message envoyé vers la Raspberry Pi, à partir de la structure que l'on a définie à la section 2.4.
Texte brut
Comme décrit à la section 3.1.4, la librairie RF24 que l'on utilise pour interagir avec le module radio nRF24L01+ permet d'envoyer et recevoir des chaines de caractères. La manière la plus simple de structurer un ensemble de données sous forme d'une chaine de caractères consiste à utiliser un texte brut structuré. Pour rappel, on doit envoyer une mesure de température et d'humidité relative et une indication de si un niveau sonore configuré a été dépassé ou non, en plus d'un timestamp.
Une solution consiste à séparer les données par un même caractère pour former une chaine de caractères. Par exemple, en séparant les données par des points-virgules, on pourrait avoir le message suivant :
2000;26.37;40;true
où l'on voit que le timestamp est de $2000$, que la température mesurée à ce moment était de 26,37 °C, que l'humidité relative était de 40 % et que le niveau sonore mesuré dépassait le maximal configuré. Un avantage de ce format, en texte brut, est que les messages sont faciles à construire et à lire. Un désavantage est la taille du message qui peut être assez grande, notamment à cause du booléen pour le niveau sonore et aussi si beaucoup de chiffres après la virgule sont utilisés.
Pour pouvoir générer ces messages, à partir de la structure measure
, il suffit de définir une fonction de conversion, qui utilise la fonction sprintf
pour construire la chaine de caractères. La fonction measureToStr
convertit donc la mesure se trouvant dans la variable m
et place le résultat dans la chaine de caractères str
. Pour la température, on utilise le type String
du langage Arduino pour transformer le nombre flottant en une chaine de caractères, avec la fonction c_str
(en effet, pour des raisons de performance, le descripteur %f
de C pour les nombres flottants n'existe pas dans le langage Arduino).
Format JSON
Un autre désavantage des messages en texte brut est le fait qu'ils peuvent être difficilement compréhensibles, si l'on ne connait pas le protocole utilisé. Cela peut rendre le débogage plus compliqué, notamment lorsqu'il faut analyser les messages échangés.
Le format JSON (le format JSON, pour JavaScript Object Notation, provient du monde JavaScript et permet de facilement représenter des objets), un autre format texte, permet de construire des messages plus facilement compréhensible, car plus verbeux, même sans connaitre le format de ces derniers. Sans rentrer dans les détails du format JSON, il s'agit essentiellement d'un ensemble de paires constituées d'une étiquette et d'une valeur, séparées par le caractère deux-point, elles-mêmes séparées par des virgules et le tout entre accolades.
Voici comment le message présenté ci-dessus en texte brut pourrait s'écrire en suivant le format JSON, sachant que les retours à la ligne ne sont pas nécessaires, mais utiles pour la lisibilité :
{ "timestamp": 2000, "temperature": 26.37, "humidity": 40, "soundDetected": true }
Ce message est beaucoup plus lisible que celui en texte brut, étant donné que les étiquettes choisies permettent de directement comprendre les valeurs présentes dans le message. Il est d'ailleurs beaucoup plus proche de la structure measure
que le message en texte brut.
Un désavantage évident est que la taille du message est bien plus grande qu'avec le texte brut. Un autre désavantage est qu'un tel message peut-être plus compliqué à construire et à lire, sans support particulier offert par le langage de programmation.
Pour pouvoir construire ces messages au format JSON, il suffit de nouveau de prévoir une fonction de conversion. La fonction measureToJSON
ci-dessous s'occupe de faire cela en construisant une chaine de caractères représentant la mesure se trouvant dans m
au format JSON.
Format binaire
Enfin, pour pallier le souci de taille des messages, il vaut mieux n'envoyer que les valeurs sous forme de nombres, plutôt que de passer par des chaines de caractères. La manière la plus efficace de procéder consiste à directement envoyer des messages au format binaire. Le principal désavantage sera évidemment la difficulté de débogage.
On peut très facilement envoyer les mesures faites au format binaire puisque l'on a déjà défini une structure les rassemblant et que les fonctions write
et read
de la librairie RF24 permettent en fait d'envoyer n'importe quelle séquence d'octets. Pour cela, il faut légèrement modifier les sketches émetteur et récepteur que l'on a défini plus haut.
La fonction boucle principale de l'émetteur va simplement créer une measure
et l'envoyer via la fonction write
du module radio, à qui il suffit de passer un pointeur vers la variable fraichement créée et initialisée.
Concernant le sketch récepteur, la fonction boucle principale va simplement créer une measure
vide et appeler la fonction read
en lui passant, comme paramètre, un pointeur vers cette variable fraichement créée, pour qu'elle soit initialisée avec les données reçues par le module radio.