Électronique | Informatique
Niveau: Avancé
Jonathan Schemoul
Montage avec la Leonardo Partie 1: Réception en 433 MHz
Vous avez sans doute entendu parler ou vu des détecteurs de fumée, d'ouverture de porte, des télécommandes, des prises murales, etc. sans fil ?
Que ce soit les modèles chers que vous trouvez en magasin ou les modèles chinois bon marché, la plupart, s'ils ne sont pas avancés, utilisent la bande de fréquence 433 MHz (n'essayez pas ceux en 315, ils sont illégaux en France). Certains autres sont en 2.4 ghz, mais nous les laisserons de coté pour l'instant.
En ce qui concerne ces capteurs en 433 MHz, il se trouve qu'ils utilisent pour la plupart un protocole très simple, introduit par des circuits intégrés chinois à bas coût, les PT2262 côté émission et les PT2272 côté réception (d'autres plus exotiques comme les SC5262 / SC5272, HX2262 / HX2272, EV1527, RT1527, FP1527 ou encore HS1527 peuvent être trouvés et fonctionneront aussi).
Plutôt que de nous lancer dans l'acquisition de ces chips, on va utiliser notre microcontrôleur, plus que capable de le faire, pour décoder et encoder les signaux, grâce à la librairie RC-Switch pour Arduino , ou RCSwitch-pi pour la Raspberry Pi .
Regardons de plus près ce que nous avons à disposition :
Montage détaillé Niveau détecteurs :
| |
| Détecteur PIR | Détecteur d'ouverture de porte |
Regardons ce détecteur d'ouverture de porte de plus près :
Gros plan sur le détecteur d'ouverture de porte On voit bien le PT2262 pour l'encodage et à gauche des jumper pour choisir le code (ainsi chaque émetteur aura un code différent). Pas besoin de déduire le code de ces jumpers, on va faire un petit programme Arduino qui nous les dira au fur et à mesure de leur activation.
Télécharger RCswitch_2.3.zip et extraire le contenu dans le sous-repertoire "libraries" (s'il n'existe pas, créez le) de votre répertoire "sketchbook", pour que cela donne :
Le récepteur est simple, il suffit de le connecter au courant (+5v et GND) et à un pin de l'Arduino ayant une interruption.
Récepteur Voici un petit tableau des interruptions :
| Carte | int.0 | int.1 | int.2 | int.3 | int.4 | int.5 |
|---|---|---|---|---|---|---|
| Uno, Ethernet | 2 | 3 | ||||
| Mega2560 | 2 | 3 | 21 | 20 | 19 | 18 |
| Leonardo | 3 | 2 | 0 | 1 |
Sur notre Leonardo, si nous voulons connecter notre récepteur sur l'interrupt 0, il nous faut le connecter sur le pin 3 :
Montage Pour cela, nous allons lancer l'IDE Arduino et charger l'exemple de RCSwitch, "ReceiveDemo_Simple".
Pour le Leonardo, il faut ajouter "while (!Serial) ;" avant d'écrire sur le port série (lié à l'utilisation de l'USB après le lancement) :
Le code dans Arduino IDE Envoyons le croquis sur la carte, et lancons le moniteur série (Outils > Moniteur Série, après avoir vérifié que le port était le bon dans Outils > Port série).
Actionnez votre senseur (ici le détecteur d'ouverture de porte, en écartant les deux parties) :
Montage Et magie, des codes s'affichent dans le moniteur série :
Retours dans le port série Ce code, 13464924 dans cette capture d'écran, est l'id unique de votre senseur, 24bit est la taille de celui-ci et 1 le protocole utilisé (ici celui du PT2262).
Si l'on active un autre senseur (le capteur de mouvement ici, il s'allume en rouge lorsqu'il détecte un mouvement) :
| |
| Détection de mouvement | Deux codes |
On voit que l'on reçoit un nouveau code : 12449942 .
Note : si vous ne voyez rien dans la console avec un Leonardo, c'est quelque chose qui arrive souvent, n'hésitez pas à ouvrir un autre moniteur série que celui livré avec l'IDE Arduino. Par exemple, putty fait très bien l'affaire même sous Linux. La commande "putty -serial /dev/ttyACM2 -sercfg 9600" permet d'ouvrir ttyACM2 en 9600 baud. (remplacer /dev/ttyACMx par COMx sous windows :))
De là à garder ces codes et à donner une information humainement compréhensible, il n'y a qu'un pas.
Essayons d'envoyer une information utile sur le port série
#include <RCSwitch.h>
#define couloir 12449942
#define porte 13464924
RCSwitch mySwitch = RCSwitch();
void setup() {
Serial.begin(9600);
mySwitch.enableReceive(0);
}
void loop() {
if (mySwitch.available()) {
int value = mySwitch.getReceivedValue();
while (!Serial) ;
switch (value) {
case porte:
Serial.println("Quelqu'un a ouvert la porte
!");
break;
case couloir:
Serial.println("Quelqu'un marche dans le couloir !");
break;
default:
Serial.print("Dispositif inconnu: ");
Serial.println(value);
break;
}
mySwitch.resetAvailable();
}
}
D'abord dans setup() on initialise mySwitch sur l'interrupt 0, ensuite, dans le loop() lorsque l'on reçoit un message, on agit selon ce qui est reçu. On envoie un message simple "Quelqu'un a ouvert la porte !" ou "Quelqu'un marche dans le couloir !" selon le cas.
Voici ce que l'on reçoit sur le port série :
Capture du port série Comme vous pouvez le voir, on a l'information, mais elle se répète. C'est dû à la nature du protocole, qui ne permet pas de vérifier la réception de l'information. Du coup, elle est envoyée plusieurs fois pour être sûr de sa réception.
Pour régler ce problème, il suffit d'ajouter un timer sur la réception, pour ne l'avoir qu'une seule fois :
#include <RCSwitch.h>
#define couloir 12449942
#define porte 13464924
RCSwitch mySwitch = RCSwitch();
// On limite à un évènement par seconde long
#define debounceDelay 1000
// On a deux détecteurs, donc on a deux timers.
last_times[2] = {0,0};
void setup() {
Serial.begin(9600);
mySwitch.enableReceive(0);
}
bool debounce(int number) {
if ((last_times[number] == 0) ||
((millis() - last_times[number]) > debounceDelay)) {
last_times[number] = millis();
return true;
}
return false;
}
void loop() {
if (mySwitch.available()) {
int value = mySwitch.getReceivedValue();
// on remet à zero le timer
while (!Serial) ;
switch (value) {
case porte:
if (debounce(0))
Serial.println("Quelqu'un a ouvert la porte !");
break;
case couloir:
if (debounce(1))
Serial.println("Quelqu'un marche dans le couloir !");
break;
default:
Serial.print("Dispositif inconnu: ");
Serial.println(value);
break;
}
mySwitch.resetAvailable();
}
}
Notre fonction debounce permet, pour un détecteur donné (de 0 à 1 ici), de dire si c'est un nouvel événement ou pas. Voici ce que cela donne si j'ouvre la porte, marche jusqu'à une autre porte puis ouvre cette autre porte inconnue :
Capture du port série Comme vous pouvez le voir, nous n'avons pas de timer sur l'émetteur inconnu mais on en a un sur ceux qui sont connus.
Dans la deuxième partie nous verrons comment envoyer des signaux à une prise en 433 MHz, et envoyer et recevoir des signaux entre Arduino selon le même principe.