Comment lire et émettre un signal radio RF 433Mhz avec un Arduino Nano

Après le miroir intelligent, voici la télécommande radio! Ce post est le premier d’une série d’articles que je souhaite rédiger sur la réalisation d’un système de domotique relativement simple. Notre objectif sera de pouvoir contrôler des prises électriques radio (de type Etekcity) avec un Arduino. Nous verrons dans les posts suivants comment passer par un raspberry pi, puis un smartphone voire même par la voix. Par la suite, j’ajouterait (j’espère) un émetteur infrarouge pour contrôler l’air climatisé, ou la TV… Stay tuned !

 

Cet article fait partie d’une série en plusieurs parties :

> Partie 1 : Lire et émettre un signal radio 433MHz
Partie 2 : Lire un signal infrarouge
Partie 3 : Emettre un signal infrarouge
Partie 4 : Communication entre un Raspberry Pi et un Arduino
Partie 5 : Intégration via NodeJS, configuration du système complet de domotique

 

Rassemblons les morceaux

Oui parce que bon, c’est bien beau de vouloir contrôler ses lumières depuis son smartphone, mais encore faut-il avoir un peu de matériel… Il y a beaucoup de configurations différentes qui peuvent fonctionner, ma préférée reste encore de jouer avec un Raspberry Pi et un Arduino Nano. Mais ça, ça sera pour une prochaine fois, allons-y par étapes. Voici ce qu’il vous faut pour la première :

  • Un Arduino Nano : 4$ chez banggood (armez-vous de patience pour la livraison).
  • Un fer à souder et du fil, car l’Arduino vient avec ses headers non soudé.
  • Quelques câbles jumper femelle-femelle.
  • Un couple émetteur/récepteur radio 433MHz : 5$ sur amazon.
  • Et enfin last but not least, des prises télécommandées. J’ai choisi Etekcity car pas cher et efficaces, 25$ les trois prises avec la télécommande sur amazon.

 

Préparation de l’ordinateur

Avant de commencer à brancher des câbles dans tous les sens, préparons un peu notre environnement de travail: installons l’IDE d’Arduino ici : https://www.arduino.cc/en/Main/Software.

 

Ports USB série

Une fois installé, connectez votre Arduino nano à un port USB de l’ordinateur. Sélectionnez le modèle de votre carte dans Outils > Types de carte, ainsi que le processeur dans Outils > Processeur. Puis, dans Outils > Ports vous ne devez voir quelque chose qui contient « USB serial » dedans, ou « /dev/cu/wchusbseriel », sélectionnez-le.

port-serie

 

Pas de port USB série dans l’IDE Arduino?

Pour ne pas le payer super cher, vous aurez peut-être comme moi acheté un clone d’Arduino pas quelque chose de brandé. Aussi peut-être que votre ordinateur ne le reconnaîtra pas car les drivers série ne sont pas assez complets.

Pour y remédier, nous allons télécharger les drivers FTDI qui vont bien en suivant les instructions détaillées fournies par SparkFun :

  • OS X 10.9 (Mavericks) ou supérieur : Ce driver
  • OS X 10.8 (Mountain Lion) ou inférieur :  Ce driver

Normalement à partir d’ici tout devrai être bon. Installons maintenant les bibliothèques.

EDIT : Depuis la mise à jour OSX Sierra, vous avez peut être des kernel panic ou tout simplement pas de port série visible dans l’IDE.

Commencez par nettoyer votre dossier Bibliothèques / Extensions des drivers USB, puis installez le pkg donné ici : https://blog.sengotta.net/signed-mac-os-driver-for-winchiphead-ch340-serial-bridge/.

 

 

La bibliothèque RC-Switch

Vous devrez télécharger la bibliothèque RC-Switch dur le github de Suat Özgür (Sui77) : https://github.com/sui77/rc-switch. Une fois la bibliothèque téléchargée, importez-la dans l’IDE Arduino en allant dans Croquis > Inclure une bibliothèque > Ajouter la bibliothèque. Une fois que c’est fait, vous devriez la voir dans la liste :

Importation RC Switch

 

 

Interprétation du signal de la télécommande

 

Branchements

On va brancher le récepteur de cette façon : VCC > 5v / Gnd > Gnd / Data > D2. Pour le Data, j’ai choisi le pin le plus proche de Ground :

 

Scripts

Si vous vous promenez dans Croquis > Inclure une bibliothèque > rc-switch > exemples, vous pourrez alors voir les différents scripts proposés par défaut avec la bibliothèque pour les tests. Et bien servons-nous !

Les tutoriels que j’ai fait mentionnaient le script ReceiveDemo comme base de travail, seulement lorsque j’exploitait mes résultats lors de l’étape d’après qui est l’émission de ce signal que je veux recopier, aucune réactiond e mes appareils.

Mais après plusieurs heures à ne pas comprendre pourquoi rien ne fonctionnait, j’ai finit par comprendre en regardant le script ReceiveDemo_Advanced qu’il me manquait une information essentielle…

ReceiveDemo_Advanced.ino

/*
  Example for receiving
  http://code.google.com/p/rc-switch/
  If you want to visualize a telegram copy the raw data and
  paste it into http://test.sui.li/oszi/
*/
#include <RCSwitch.h>
RCSwitch mySwitch = RCSwitch();
void setup() {
  Serial.begin(9600);
  mySwitch.enableReceive(0);  // Receiver on inerrupt 0 => that is pin #2
}
void loop() {
  if (mySwitch.available()) {
    output(mySwitch.getReceivedValue(), mySwitch.getReceivedBitlength(), mySwitch.getReceivedDelay(), mySwitch.getReceivedRawdata(),mySwitch.getReceivedProtocol());
    mySwitch.resetAvailable();
  }
}

 

C’est parti !

Allez donc charger ce script, puis « téléversez-le » sur l’Arduino à l’aide du bouton en forme de flèche vers la droite. Puis, allez ouvrir le moniteur série (Outils > Moniteur série). Il est ouvert? Alors appuyez sur un bouton de la télécommande. Voici ce que vous verrez :

moniteur-serie

 

Il y a deux valeurs qui vont principalement nous intéresser ici :

  • « Binary », le code binaire du signal à envoyer
  • « Pulselenght », la longueur d’onde du signal.
    C’est l’information que je ne retrouvais pas et qu’il me manquait !

Amusez-vous a appuyer sur tous les boutons de votre télécommande. Normalement, le Pulselenght ne changera pas, mais prenez soin de noter chaque code binaire dans un fichier à part, car c’est ça qu’on va essayer d’émettre !

 

Emission du signal décodé

Branchements

Oui c’était une belle histoire, mais il est temps de ranger le récepteur dans un placard. Place à l’émetteur !
On va brancher le récepteur de cette façon : VCC > 5v / Gnd > Gnd / Data > D10.

J’ai personnellement acheté un émetteur cheap avec les intitulés pas bien en face des pins, et même si j’en ai un peu honte, dans la précipitation j’ai mis plusieurs essais avant de comprendre que j’avais inversé l’alimentation et le data… :-/

 

Scripts

Là, on va s’intéresser au script SendDemo des exemples fournis avec la bibliothèque. Ce script va émettre un signal, attendre, puis émettre un autre signal. Il propose différents formats de signaux, j’ai choisi le binaire de façon un peu arbitraire, sans raison particulière…

SendDemo.ino

/*
  Example for different sending methods
  https://github.com/sui77/rc-switch/
*/
#include <RCSwitch.h>
RCSwitch mySwitch = RCSwitch();
void setup() {
  Serial.begin(9600);
  // Transmitter is connected to Arduino Pin #10
  mySwitch.enableTransmit(10);
  // Optional set pulse length.
   mySwitch.setPulseLength(185);
  // Optional set number of transmission repetitions.
   mySwitch.setRepeatTransmit(5);
}
void loop() {
  /* using binary code */
  mySwitch.send("000000000001010100010001");
  delay(1000);
  mySwitch.send("000000000001010100010100");
  delay(1000);
}

 

Vous vous souvenez du PulseLenght si cher à mon cœur? C’est ici que ça va nous intéresser… Vous noterez que dans ma version du script, j’ai dé-commenté mySwitch.setPulseLength() et l’ai paramétré à 185. C,est le chiffre que j’ai obtenu plus tôt lors de la lecture.

Il faudra aussi penser à remplacer la valeur binaire du signal à émettre. Pour ma part j’ai choisi les deux boutons « On » et « Off » de la télécommande, boutons reliés à la prise qui contrôle ma lampe de table… Téléversez le script sur l’Arduino, et hop ! Vous avez une belle lampe qui clignote !

On et Off

 

Conclusion

Là, tout de suite, vous allez me dire que ça ne sert pas à grand chose… Mais comme on le disant, chaque chose en son temps, allons-y étape par étape. Désormais, nous savons dire à l’Arduino d’envoyer un signal radio bien spécifique lui permettant d’agir sur un récepteur, ici la prise radiocommandée.

Comme pour l’instant on ne fait que allumer et éteindre en boucle, cela signifie que la prochaine étape sera d’arriver à communiquer à l’Arduino pour pouvoir manuellement déclencher l’envoi d’un signal. Ce signal pourra d’ailleurs être soit On, soit Off, au choix. Pour ça on va le connecter à un Raspberry Pi, c’est le Pi qui va se charger de communiquer avec l’Arduino.

Cela nous permettra à la fin de la série d’articles d’utiliser homebridge sur le raspberry pi d’un côté pour un contrôle avec Siri :

 

 

 

 

 

 

 

 

 

Ou encore pour le fun de réaliser cette petite interface web :

 

Suite au prochain épisode !

 

 

 

19 commentaires

  1. merci pour ce tuto.c tres bien lorsque l’on est novice et interessé comme moi
    je voudrais essayer d’ouvrir la porte de mon garage ou ma voiture comme appli
    par contre a la compil j’ai erreur output was not declared
    ensuite si j’ai bien compris tu releves a la mano les signaux emetteur et tu les inscrit dans ta chaine emetteur par la suite?? mais dans ton exemple je ne retrouve pas les codes ecrits dans emetteur ( mySwitch.send(« 000000000001010100010001 ») ;sur la liste de la lecture serie obtenue par recepteur!!
    c n’est peut etre qu’un exemple

    merci en tout cas
    la suite !!!!!!!!!!!!

    1. Content que ça te serve 🙂 Je vais essayer de répondre à tes questions, mais je suis pas sur de toutes les comprendre ^^
      Pour ton erreur (« output was not declared ») je pense que tu devrais vérifier la partie « Sélectionnez le modèle de votre carte dans Outils > Types de carte ».
      Concernant le signal émetteur, c’est là que je suis perdu dans la question 🙂 Le code que j’ai mis c’est bien sûr celui de ma télécommande, ce n’est pas un code universel, est-ce que c’est ce que tu voulais dire? As-tu bien suivi les instruction, à savoir ouvrir le port série, et essayé les touches de ta télécommande? Aurais-tu une capture d’écran à partager?

    2. merci a toi de t’attarder sur mon prob!!

      concernant sur l’erreur, je suis bien sur arduino uno dans type de carte
      sur le code je sais que ce n’est pas un code universel mais je ne vois pas dans la video la chaine de reception que tu retransets dans emission

      1. oups !!
        mon erreur »output not declared » est ici
        void loop() {
        if (mySwitch.available()) {
        output(mySwitch.getReceivedValue(), mySwitch.getReceivedBitlength(), mySwitch.getReceivedDelay(), mySwitch.getReceivedRawdata(),mySwitch.getReceivedProtocol());
        mySwitch.resetAvailable();
        il plante sur output variable non declaée

        1. Probablement normal. As-tu utilisé le script en important directement l’exemple ReceiveDemo_Advanced ? Ce script importe un fichier output d’ailleurs, qui contient deux fonctions essentielles.
          Fais ton test en allant le cherche ici : Fichier > Exemples > RCSwitch > ReceiveDemo_Advanced et ça devrait aller

          1. merci les fonctions n’etaient pas dans le script importé
            j’ai fait le montage et testé. pas bon donc
            j’ai mis une led sur l’entree de l’emetteur pour voir si celui ci recevait les impulsions telecommande c ok ceci etant ok j’ai testé si je rentrais dans la boucle if (mySwitch.available()) {
            je n’y passe pas!!! donc ma condition available n’est pas validée??

      1. le code est exactement celui telechargé
        je pense plutot probleme hard de connexion sur Uno
        sur quelle pine recevoir signal sur Uno??
        le prob doit se situer la je crois et c’est pour cela que ma boucle d’appel output n’est pas sollicitée?

        1. j’ai donc supprimé le test du loop if (mySwitch.available()) cette ligne seulement
          et je me retrouve enfin avec unknow encoding Raw data xxx
          c mieux que rien

          1. Cette condition est là pour vérifier que tout est ok avant de recevoir les données, il est important de le laisser. Cela revient à couper le voyant moteur pour réparer une panne, la cause du problème est ailleurs. As-tu bien mis les pins au bon endroit (D2)? Alimentation en 5v?

          2. ben oui
            tout me semble ok
            pins 5v et gnd
            entree recepteur sur pin 2 bornier digital
            je suis franchement desolé mais c la faute a malchance!!!!
            je vais remettre condition mais a ce moment la je ne rentrerai plus dans ma boucle…

          1. Cette condition retournera toujours « false » tant qu’aucune donnée n’est reçue. L’exemple de réception est tellement basique qu’il est peu probable qu’il s’agisse d’un problème de code. Je pencherai donc pour soit un problème matériel avec le récepteur radio, soit que ta télécommande de teste n’est pas de la même fréquence (433 versus 315MHz)…

          2. frequence ok mais protocole??
            la puce est un HCS301 donc rolling code
            impossible a refaire avec arduino sur le meme principe rcswitch?

  2. salut super tuto, quand la suite ?

    questions : j’arrive a recevoir mais pas en émissions avez vous idee je pense avoir fait comme vous je suis sur arduino uno

    merci

    1. Hello !

      Merci pour ton commentaire 🙂 La suite est sur l’article suivant, lecture d’un signal infrarouge. J’ai terminé ma boite de domotique, maintenant il va falloir rédiger les articles!

      Pour l’émission il y a plusieurs pièges que j’ai remarqué ;
      1- vérifier la source de courant. Si tu utilises un adaptateur secteur vérifie son ampérage (parfois tu as des adaptateurs bon marché qui délivrent moins de 1A)
      2- Vérifie le pulseLenght, défini le bien dans setup() lors de l’émission avec la valeur notée lors de la réception
      3- Joue avec mySwitch.setRepeatTransmit() pour augmenter le nombre de fois que le signal est envoyé. Parfois en fonction de ton récepteur, une seule émission brève de signal n’est pas assez pour qu’il l’interprète bien. Comme tu peux le voir j’ai pour ma part du l’initialiser à 5 répétitions.

      Bonne chance !

    1. Hello,
      Ca marche avec n’importe quelle carte, il faut juste l’indiquer dans le menu outils.
      Pour le pin, il faut jetter un oeil au pinout plus bas pour comprendre. Le commentaire du code indique que l’on selectionne l’interruptur 0, soit INT0 donc le pin 2 sur l’arduino. Si tu veux utiliser un Uno, regards le pinout pour trouver l’INT0, ou utilise l’INT1 si ut préfère.

      Pinout Arduino Nano

Laisser un commentaire

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