HomePi – Test 01 – Lire une sonde avec l’arduino et communiquer avec le RaspberryPi

Bonjour à vous chers lecteurs geeks et moins geeks.

Je continue mes travaux sur le Raspberry Pi et l’Arduino afin de créer un système domotique complet (HomePi). Aujourd’hui, nous allons voir comment lire avec l’Arduino une sonde de température DS18B20 (voir le tutoriel pour la lire avec le Raspi ici), puis de l’envoyer via un émetteur radio de 433Mhz vers le Raspberry Pi doté lui d’un récepteur radio de 433Mhz.

Ce tutoriel risque d’être un peu long, mais je vais essayer de détailler chaque étape autant que possible (mais n’hésitez pas si vous avez des questions). Ce tutoriel est inspiré et basé sur les tutoriels d’Idleman, donc n’hésitez pas à y faire un tour.

Les buts de ce tutoriel sont les suivants :

  • Commencer à prendre en main l’arduino (reçu il y a peu)
  • Étudier la communication radio entre les 2 deux appareils
  • Étudier la faisabilité de mon projet (HomePi), notamment la partie communication avec les nœuds.

Pour ce tutoriel, il vous faudra le matériel suivant :

Bon, il est désormais temps de mettre les mains dans le cambouis et dans les câbles.

Étape 0 : pré-requis

Afin de comprendre pleinement ce tutoriel, il est conseillé :

  • d’avoir déjà pris en main votre raspberry pi, je conseille pour cela les tutoriels d’Idleman
  • d’avoir fait quelques tutos du site arduino.cc pour comprendre le fonctionnement de l’Arduino.
  • Avoir installé sur votre Raspberry Pi la bibliothéque WiringPi
  • Quelques notions de C/C++
  • Quelques notions d’onde radio (non obligatoire, mais il est toujours intéressant de savoir de quoi on parle).

Vous pouvez bien évidemment attaquer direct dans le dur, mais il est tout de même préférable d’avoir ces pré-requis afin de bien comprendre le tutoriel et de ne pas recopier bêtement.

Étape 1 : Lire la température avec l’Arduino

On utilise bien évidemment une sonde DS18B20 (voir le lien donné plus haut pour vous la procurer pour pas cher).

Cette première partie du tutoriel suppose que vous avez déjà un peu pris en main votre Arduino. Si ce n’est pas le cas, je vous conseille de commencer par les divers tutos proposés par le site arduino.cc, cela vous aidera et c’est plutôt rapide à faire au final.

Voici le montage a effectuer :

Shéma du montage
Schéma du montage (cliquez pour agrandir)

Le principe est simple. Referez vous au schéma du capteur (clic), ainsi qu’au tuto pour le lire avec le raspberry pi.

On branche la borne 1 sur le Ground de l’arduino, la branche 2 sur le port 10 de l’Arduino et la 3 sur l’alimentation 3V3. Entre les broches 2 et 3, on ajoute une résistance de 4700 Hmz. Voila pour les branchement, ce n’est pas plus compliqué que cela.

Question code, on s’en sort aussi plutôt bien puisque le travail est déjà fait par d’autre. Vous trouverez notamment un tuto sur le playground d’Arduino qui vous détail l’ensemble du fonctionnement. Leur code est basé sur une bibliothèque C++ : OneWire.h qui gère plusieurs types de capteurs (dont le DS18B20).

Voici la portion de code qui lit la température sur le capteur :

// Fonction récupérant la température depuis le DS18B20
// Retourne true si tout va bien, ou false en cas d'erreur
boolean getTemperature(float *temp){
 byte data[9], addr[8];
 // data : Données lues depuis le scratchpad
 // addr : adresse du module 1-Wire détecté

 if (!ds.search(addr)) { // Recherche un module 1-Wire
 ds.reset_search();    // Réinitialise la recherche de module
 return false;         // Retourne une erreur
 }

 if (OneWire::crc8(addr, 7) != addr[7]) // Vérifie que l'adresse a été correctement reçue
 return false;                        // Si le message est corrompu on retourne une erreur

 if (addr[0] != DS18B20) // Vérifie qu'il s'agit bien d'un DS18B20
 return false;         // Si ce n'est pas le cas on retourne une erreur

 ds.reset();             // On reset le bus 1-Wire
 ds.select(addr);        // On sélectionne le DS18B20

 ds.write(0x44, 1);      // On lance une prise de mesure de température
 delay(800);             // Et on attend la fin de la mesure

 ds.reset();             // On reset le bus 1-Wire
 ds.select(addr);        // On sélectionne le DS18B20
 ds.write(0xBE);         // On envoie une demande de lecture du scratchpad

 for (byte i = 0; i < 9; i++) // On lit le scratchpad
 data[i] = ds.read();       // Et on stock les octets reçus

 // Calcul de la température en degré Celsius
 *temp = ((data[1] << 8) | data[0]) * 0.0625; 

 // Pas d'erreur
 return true;
}

La fonction retourne un boolean et renseigne un pointeur qui contient notre température.

Voila pour la partie lecture. Jusque là, rien de bien compliqué, les sources sont sur le net et il y a de nombreux exemples. On va maintenant entamer la partie funkie de ce tutoriel : l’envoi des données depuis l’Arduino vers le Raspberry Pi par les ondes (on utilise pour cela la fréquence de 433,92 Mhz, souvent utilisée en domotique.

Étape 2 : Construction de notre signal radio

Afin de pouvoir communiquer entre l’émetteur et le récepteur, il nous faut créer un protocole radio spécifique. Nous allons donc le créer ce fameux signal, en nous basant sur les conseils donnés sur le blog d’idleman. Pour reprendre, on va construire une schéma précis de bit qui va être notre signal, on va ensuite l’encoder pour le protéger des parasites éventuels via un codage de manchester. Dans ce signal, nous allons faire passer plusieurs informations :

  • Un identifiant du kit (4 chiffres codés sur 14 bits)
  • Le type de transmission (2 chiffres codés sur 4 bits)
  • Un bit de signe
  • Les données (4 chiffres codés sur 14 bits)

Si on prend alors comme code de kit 1000 (pour l’arduino), 10 comme type de transmission et une température de +19,60 degrés.

On a alors 10001011960

Une fois passé en binaire on a alors : 000011111010001010100011111011100

On applique ensuite le codage de manchester qui consiste à transformer un 0 en 01 et un 1 en 10afin de sécuriser les échanges de données un minimum et de contrôler l’apparition de parasites (ce qui est fréquent avec les ondes radio, surtout à des fréquences aussi utilisées que 433Mhz).

On arrive donc à un signal final : 010101011010101010011001010110011001100101011010101010011010100101

Et voila !

Reste ensuite à isoler notre signal du reste des interférences et des signaux environnants. Pour isoler un signal, on utilise en général un système de verrous, qui permet de délimiter le signal. Nos verrous seront donc les suivants :

  1. Un bit de bruit pour remettre à 0 la communication
  2. Un verrou de 9900µs
  3. Un verrou 2500µs
  4. Notre signal
  5. Un bit de bruit pour remettre à 0 la communication

Ainsi, notre signal est bien délimité, et le récepteur saura que si il trouve les verrous 1 et 2, alors ce qui suit sera le signal envoyé.


Étape 3 : les branchements !

Nous avons vu quel signal envoyé et comment il sera encodé, reste donc à savoir comment le transmettre 🙂

Ci dessous, voici les photos des montages de l’émetteur et du récepteur.

Branchements pour l’émetteur 433 Mhz

Branchement de l’émetteur sur l’Arduino :

  • La broche 1 (data) va sur le pin 12 de l’Arduino,
  • La broche 2 (VCC) va sur le pin d’alimentation 3v3 de l’Arduino,
  • La broche 3 (GRDà va sur le pin Ground de l’Arduino.
  • On rajoute sur l’entrée ANT une antenne (le must étant une antenne de 17,3 cm pour maximiser la performance).

Rien de bien compliqué n’est ce pas ?

Passons maintenant aux branchements du récepteur sur le Raspberry Pi, vous allez voir, c’est encore une fois très très compliqué !

Branchements du récepteur 433 Mhz
Branchement du récepteur 433 Mhz

Le récepteur possède cette fois ci 4 broches (dont deux pour les data, mais nous n’allons n’en utiliser qu’une seule).

  • La broche 1 se branche sur le 5v du Raspberry Pi
  • La broche 2 (c’est du data mais on ne va pas s’en servir)
  • La broche 3 (data) se branche sur le pin wiringPi numéro 2 du Raspberry Pi
  • La broche 4 se branche sur le ground du Raspberry Pi
  • On rajoute une antenne de 17,3 cm pour optimiser les performances.

Voila. Dur encore n’est ce pas ?

Étape 4 : Code pour l’Arduino

On a vu comment relever la température fournie par le capteur DS18B20, il faut maintenant l’envoyer et donc construire le signal qui sera fourni à l’émetteur et transmis au récepteur sur le Raspberry Pi.

Cliquez ICI pour télécharger le script à téléverser sur l’Arduino (ou sur la puce atmega si vous n’utilisez qu’une puce atmega).

Vous retrouvez dans le code les fonctions suivantes :

  • getTemperature : C’est la fonction documentée plus haut, qui sert à relever la température sur la sonde DS18B2O
  • itob et itobTemperature qui servent à transformer des données numériques en tableaux de bits
  • buildSignal qui va construire les différentes parties du signal
  • sendPair et sendBit qui servent à envoyer via l’Arduino les bits de notre signal, sendPair sert au passage d’encodeur de Manchester puisqu’il envoi non pas 1 bit mais 2 bits.
  • transmit qui permet d’envoyer le signal en recevant en paramètre une température
  • Les fonctions obligatoires setup et loop

Au final le fonctionnement est plutôt simple : dans la fonction setup, on initialise le signal, puis la fonction loop (qui comme son nom l’indique est une boucle perpétuellement appelée par la puce) qui toutes les X secondes relève la température via la fonction getTemperature et envoie le signal via la fonction transmit.

Et voila. Notre température est lue régulièrement et le signal est envoyé. Il ne nous reste plus qu’à le recevoir et en faire ce que l’on souhaite 🙂

Vous pouvez contrôler les logs de ce qu’il se passe quand l’Arduino est connecté via le logiciel qui vous a servi à téléverser le code dans la puce atmega.

Étape 5 : Code pour le Raspberry Pi

On va cette fois passer par un peu de code C++ coté Raspberry Pi pour lire le signal radio reçu, puis par un peu de code PHP pour l’enregistrer en base de données. Il est bien sur tout à fait possible de faire l’enregistrement en BdD directement via le C++, mais par confort et par habitude, je suis resté sur du PHP. Une bonne partie du code est honteusement repompée sur le code fournit par idleman dans ses tutos, que j’ai adapté.

Vous pouvez récupérer le code ICI (le rar ou le zip). Ce fichier zip contient les fichiers suivants :

  • common.php : sécurisation des super-variables
  • db.php : connexion à la base de donnée mysql, pensez à y changer vos identifiants !
  • Functions.class.php : quelques fonctions php utiles
  • node : l’exécutable qui va lire le signal radio
  • node.cpp : le code source C++ qui permet de générer l’exécutable
  • node.php : le code php qui enregistre en base de donnée la température
  • olga.php (optionnel) : le code PHP utilisé par mon interface vocale SARAH

Si vous modifiez le code C++, vous pouvez ensuite recompiler le code via la ligne de commande suivante :

g++ node.cpp -o node -lwiringPi

Pour exécuter le fichier exécutable, utiliser le code suivant :

./node /var/www/node/node.php  7

Et hop, le tour est joué ! Voici le type d’affichage que l’on obtient.

Capture d'écran de l'exécution du script
Capture d’écran de l’exécution du script

Voila, on arrive donc à la fin de la partie globale de ce tutoriel, j’espère qu’il vous a été utile. Les 2 chapitres suivants sont optionnels, même si évidemment, je vous invite à les lire 🙂

Étape 6 : Améliorations envisagées

Dans un premier temps, le code qui est actuellement d’une qualité plus que passable et qui n’est pas ultra optimisée, nécessite un peu de travaille. Car l’optimisation du code va être une clé essentielle pour la rapidité du système et l’économie d’énergie

Gestion de l’alimentation.

C’est sans doute LE point le plus important à travailler sur ce montage. Pour le moment l’Arduino est alimenté via l’usb connecté à l’ordinateur, c’est surtout une solution de facilité. Pour rendre le nœud indépendant, il faut donc fournir une alimentation autonome au système.

Les émetteurs et récepteurs 433 Mhz sont aussi grandement influencés par le fait d’avoir une alimentation indépendante ou non. Coté nœud, l’alimentation qui fournit l’Arduino servira donc aussi à alimenter l’émetteur / récepteur de manière indépendante. Je n’ai pas encore fait le test moi même, mais il semble apparemment que les performances du signal radio s’en retrouvent grandement accrues. Dans un système comportant plusieurs nœuds, il sera donc rapidement nécessaire d’optimiser au maximum l’alimentation pour augmenter les performances des signaux.

Coté Raspberry Pi, si il possède sa propre alimentation, il peut s’avérer intéressant aussi de fournir à l’émetteur / récepteur 433 Mhz sa propre source d’alimentation pour optimiser la communication radio.

Kit radio complet.

Dans le montage présenté par ce tutoriel, l’émetteur est situé sur le nœud Arduino et le récepteur est connecté au Raspberry Pi. Il faudra améliorer le tout en fournissant à chaque nœud un kit émetteur ET récepteur et faire la même chose pour le Raspberry Pi. Une des idées principales de mon projet homepi, c’est que le Raspberry Pi a un rôle centrale et que c’est lui qui interroge les nœuds disséminés dans votre maison. C’est donc un peu plus compliqué que ce que j’ai pu faire dans ce tutoriel.

Je pense que le prochain tutoriel sera consacré à faire évoluer le présent tutoriel pour ajouter cette logique de question / réponse radio commandée par le Raspberry Pi.

Se passer de l’Arduino

Si dans cette démonstration, j’utilise un Arduino complet, au final, on est bien loin d’en avoir besoin. On n’utilise que quelques ports, donc, pour des questions d’optimisation de la place mais surtout de la consommation électrique, il est tout à fait possible de se contenter d’utiliser soit la puce atmega328 de l’arduino, soit des puces ATtiny, comportant moins de pattes. Je vais sans doute tester plusieurs puces pour voir laquelle est la plus adaptée à mon projet. Ou alors créer plusieurs types de noeud en utilisant plusieurs puces. Bref, vous aurez sans doute droit à un tuto pour expliquer comment la programmer via l’arduino.

Étape 7 : Et si on couplait ça à SARAH ?

En suivant le blog d’Idleman, j’avais eut la chance de tomber sur ce formidable outil que représente SARAH.

Kézako ?

S.A.R.A.H. est une interface TextToSpeech développée par un français et qui repose sur les bibliothèques vocales de Windows (mouarf).

Le principe est assez simple : On lance un exécutable qui se chargera d’analyser ce que le micro capte, pour y déceler des phrases clés que vous aurez définis via un ensemble de fichier XML. Le must ? il est possible de configurer comme réponses à une phrase clé, l’envoi d’une requête HTTP (ou autre) vers votre cher Raspberry Pi, qui se chargera lui, de renvoyer une phrase qui sera lue par votre interface vocale.

Exemple ?

Moi : SARAH, quelle est la température dans le salon ?

Sarah : Il fait 20,12 degrés dans le salon.

Grâce à la configuration de mes fichiers XML, j’arrive à découper la phrase de la manière suivante : SARAH, quelle est la température dans le salon ? SARAH sait qu’on lui parle, qu’on lui demande une information (la température) pour une pièce donnée (le salon). Elle envoie alors une requête HTTP au Raspberry Pi en passant en paramètre ces 2 points de configuration, le Raspberry Pi traite la demande et renvoie une phrase qui sera lue par l’interface vocale, après avoir interrogé sa base de données.

Magique non ?

J’ai commencé à mettre en place une démo de SARAH couplée au Raspberry Pi et au montage décrit dans ce tutoriel, n’hésitez pas à me le demander, dans ce cas je l’ajouterais ici pour compléter.

Conclusion

Voila, ce tutoriel est désormais terminé. On a pu voir comment utiliser ces deux magnifiques bestioles que sont l’Arduino et le Raspberry Pi, et qui vous nous servir comme base pour notre projet domotique maison HomePi.

Après ce premier test, je suis désormais convaincu que c’est cette solution technologique que je vais adopter, même si il va falloir améliorer la communication radio, notamment par l’adjonction d’une source d’électricité indépendante, pour être à même de couvrir une grande maison sans trop d’emmerdes. Le prochain tutoriel aura surement pour but d’améliorer la communication et d’enrichir la dite communication par une logique de questions – réponses entre le Raspberry Pi master et ses noeuds esclaves basés sur des puces d’Arduino.

Si vous avez la moindre question n’hésitez pas. De même, étant particulièrement novice, si vous constatez des erreurs, merci de me les signaler. Cela me permettra de corriger plus rapidement.

Laisser un commentaire

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