Lire un signal infrarouge : Arduino nano et TSOP38238

Après avoir vu comment lire puis recopier un signal 433MHz pour contrôler ses lumière, attaquons-nous maintenant à la partie où on va essayer de contrôler sa télévision avec un simple LED infrarouge en commençant par décoder le signal de la télécommande. Je voulais contrôler l’air climatisé avec ça, mais l’approche de l’hiver m’a fait préférer le confort de rester sous le plaid quand je cherche la télécommande plutôt que le fait de réguler la clim !

 

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

 

Rassemblons les morceaux

Cette expérience sera peut être une des moins onéreuses avecun total de 8$, peut être 10$ si on rajoute le prix des câbles jumper… Voici la liste de courses :

  • Un Arduino Nano : 4$ chez banggood (comme toujours : 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 et femelle-mâle.
  • Un récepteur infrarouge, par exemple le TSOP38238 de sparkfun à 2$

ir-remote-concept

Préparation du hardware

Disclaimer : Pour cette partie de mon projet de petite boite de domotique, je me suis largement inspiré de ce tutoriel d’Adafruit. Disons que cet article est plus pour moi la synthèse de ce que j’ai glané ci et là comme informations, traduite en français.

Le montage pour lire le signal est plutôt simple. Voyez plutôt :

 

ir-receiver

 

Si vous regardez le TSOP avec le côté bombé devant vos yeux, il faut mettre le pin gauche sur le 5V, le milieu sur le GND (ground) et le pin de droite sera votre signal, pour moi ça sera le pin 11 de l’arduino. Voyez le pinout du TSOP382 :

Ir receiver pinout

 

La bibliothèque IR Remote

Hypothèse de départ : Je vais supposer dans la suite de ce tutoriel soit que vous avez lu le précédent sur l’émission/réception radio (ou du moins ce court paragraphe sur la préparation de l’IDE Arduino), soit que vous avez déjà eu le plaisir de travailler avec !

Il existe pas mal de bibliothèques différentes, j’ai choisi celle-ci parce qu’elle était mentionnée dans le tutoriel que j’ai moi même suivi lorsque j’ai appris tout ceci.

Télécharger IR Remote

Pour lire le signal de la télécommande de la télévision, je suis allé charcher le script de base IRrecvDump.ino que vous trouverez dans Arduino-IRremote/examples/IRrecvDump :

/*
 * IRremote: IRrecvDump - dump details of IR codes with IRrecv
 * An IR detector/demodulator must be connected to the input RECV_PIN.
 * Version 0.1 July, 2009
 * Copyright 2009 Ken Shirriff
 * http://arcfn.com
 * JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
 */
#include <IRremote.h>
int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);
decode_results results;
void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
}
// Dumps out the decode_results structure.
// Call this after IRrecv::decode()
// void * to work around compiler issue
//void dump(void *v) {
//  decode_results *results = (decode_results *)v
void dump(decode_results *results) {
  int count = results->rawlen;
  if (results->decode_type == UNKNOWN) {
    Serial.print("Unknown encoding: ");
  }
  else if (results->decode_type == NEC) {
    Serial.print("Decoded NEC: ");
  }
  else if (results->decode_type == SONY) {
    Serial.print("Decoded SONY: ");
  }
  else if (results->decode_type == RC5) {
    Serial.print("Decoded RC5: ");
  }
  else if (results->decode_type == RC6) {
    Serial.print("Decoded RC6: ");
  }
  else if (results->decode_type == PANASONIC) {
    Serial.print("Decoded PANASONIC - Address: ");
    Serial.print(results->panasonicAddress,HEX);
    Serial.print(" Value: ");
  }
  else if (results->decode_type == JVC) {
     Serial.print("Decoded JVC: ");
  }
  Serial.print(results->value, HEX);
  Serial.print(" (");
  Serial.print(results->bits, DEC);
  Serial.println(" bits)");
  Serial.print("Raw (");
  Serial.print(count, DEC);
  Serial.print("): ");
  for (int i = 0; i < count; i++) {
    if ((i % 2) == 1) {
      Serial.print(results->rawbuf[i]*USECPERTICK, DEC);
    }
    else {
      Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC);
    }
    Serial.print(" ");
  }
  Serial.println("");
}
void loop() {
  if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX);
    dump(&results);
    irrecv.resume(); // Receive the next value
  }
}

 

Il y a deux lignes de code notables, qui ont leur importance :

Ligne 18, pour indiquer le numéro du pin de l’arduino sur lequel est connecté le TSOP38238 :

int RECV_PIN = 11;

Ligne 26, le débit de données (en bits par secondes, ou bauds) de la console série de l’IDE :

Serial.begin(9600);

 

Le reste peut être laissé en l’état, et c’est le moment d’appuyer sur plein de boutons ! Téléchargez le script sur l’arduino, puis ouvrez le moniteur série.

Ensuite, pointez votre télécommande sur le TSOP38238 et admirez la succession de chiffres qui apparaissent sur le moniteur !

img_9741

 

Interprétation du signal infrarouge

Un signal infrarouge c’est une espèce de poussées d’une série de micro-impulsion infrarouge et de micro "silences". Finalement, cela marche quasiment comme un code barre, ou du code binaire, du morse, ou… Bref, vous voyez quoi !

Une histoire de protocole

Le récepteur va juste lire ces séries d’impulsions et de silences. Le micro-contrôleur et sa bibliothèque peuvent ensuite interpréter ceci et essayer de les faire correspondre à un protocole de marque en particulier, genre NEC, SONY, LG, etc.

Si il y parvient, il va proposer le code hexadécimal correspondant à la commande reçue dans le protocole de la marque. Au cas où il n’y arrive pas, il va proposer une série de chiffres qui sont finalement les temps d’impulsions et les temps de silence, un peu comme si il indiquait la largeur des bandes noires et blanches d’un code barre. C’est ce qu’on va appeler le raw data, ou la donnée crue.

L’infrarouge : un monologue

Dans tous les cas, il faut bien considérer que la commande infrarouge est à sens unique. Il est impossible pour la télécommande (ou le micro-contrôleur) de savoir dans quel état se trouve l’objet qu’il commande.

Prenez une télécommande de climatiseur par exemple. Cette télécommande vous affiche la température, le mode, etc. Puis vous allez changer la température. La télécommande va renvoyer son état au complet : La puissance de l’air, la température, le mode, etc.

Il faut bien garder cela en tête lorsque l’on cherche à lire le signal de la télécommande pour le recopier. Ici, si votre objectif est de contrôler un climatiseur, alors ce que vous allez enregistrer c’est l’état global dans lequel le climatiseur doit se trouver. En d’autres termes, lorsque vous lisez la commande "température +1 degré", en réalité vous lisez en réalité la commande "mode froid, température à 29 degrés, flot d’air force 5/6, volets en position demi ouverts".

Heureusement, une télécommande de téléviseur, elle, n’envoie que la commande en tant que telle : chaîne +1, source, flèche droite, touche entrée, etc. Mais cela veut dire aussi que si vous n’avez pas déjà une touche "HDMI 3" par exemple, vous ne pourrez pas commander la télévision pour aller directement sur ce mode. C’est pour ça que mon interface de contrôle (que je détaillerai dans un futur article), reproduit les touches de la télécommande au lieu d’avoir des boutons pour chaque source :

 

 

Exploitation du résultat

Une fois que l’on sait ce qu’on cherche à reproduire, voici ce que peut donner la lecture du signal

Decoded NEC(1): Value:FD807F (32 bits) Raw samples(68): Gap:40826 Head: m8850 s4450 0:m500 s600 1:m550 s550 2:m500 s600 3:m550 s600  4:m500 s600 5:m500 s600 6:m500 s600 7:m550 s550  8:m500 s1750 9:m500 s1700 10:m500 s1700 11:m550 s1650  12:m550 s1700 13:m500 s1700 14:m500 s600 15:m550 s1700 16:m500 s1700 17:m500 s600 18:m500 s600 19:m500 s600  20:m550 s600 21:m450 s650 22:m500 s600 23:m500 s600  ...etc.

Ici dans mon cas, IR Remote a reconnu le protocole NEC. C’est étrange car mon téléviseur est de la marque LG… Après quelques recherches rapides, j’ai compris que LG utilisait le même protocole 32 bits que NEC, donc tout est normal ! J’ai fait cette manipulation pour les boutons de ma télécommande de TV puis pour la télécommande de mon home cinéma.

Comme la librairie IR Remote à reconnu le protocole de mes télécommandes, voici les deux éléments à noter sur un bloc note :

  • Dans l’exemple le code hexa de la commande, FD807F.
    Plus tard on le préfixera de "0x", ainsi : 0xFD807F. La raison est longue à expliquer, mais la version courte c’est que le parseur qui va lire cette valeur doit savoir qu’il va traiter une constante et non un identifiant ou un mot réservé. Le "x" accolé au "0" signifie que c’est une notation hexadécimale, sinon on traiterait de l’octal.
  • Toujours dans l’exemple, le nombre de bits, ici 32.

Nous nous servirons de ces deux valeurs lorsque nous attaqueront le prochain article visant à envoyer le signal infrarouge pour par exemple allumer la télévision. A suivre donc !

 

 

 

Laisser un commentaire

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