Un peu de théorie :

remotes.jpg, mai 2021

L'objectif d'une télécommande Infrarouge, est de permettra la transmission de plusieurs octets vers un équipement. Sur les protocoles les plus simples, il y aura un octet d'adresse de périphérique, et un octet de données, mais certains protocoles codent l'adresse sur 2 octets, ou ajoutent un troisième octet de code de sous fonction dans l'équipement. Un octet peut prendre les valeurs 0 à 255.

Pour permettre l'envoi de données avec de la simple lumière, ces données doivent être sérialisées, c'est à dire transmises bit à bit dans leur représentation binaire. Ainsi le nombre décimal 252 (0xAA en hexadécimal) se représentera 0b10101010 en binaire. En envoyant de la lumière pour un 1 et pas de lumière pour un zéro, et en transmettant les bits uns à uns, on a un moyen de faire de la transmission de données.

C'est d'ailleurs ce procédé qui est utilisé dans le Lifi, ou réseau informatique par la lumière ( voir https://en.wikipedia.org/wiki/Li-Fi ). Mais c'est une autre histoire...

Bits, Bytes, Octets, MSB et LSB :

Pour ceux qui ne maitrisent pas ces conversions, tous les systèmes d'exploitation modernes disposent d'une calculatrice intégrée, dont on peut changer le mode d'affichage pour faire ce type de conversions (ex sous Windows 10, en choisissant le mode "Programmeur en haut à gauche). A noter que l'on adjoint souvent un préfixe permettant de savoir dans quelle base le nombre est écrit (0x = hexadécimal, 0d = décimal, 0o = Octal, et 0b = binaire). Il est ainsi plus facile de savoir à quelle représentation on a affaire.

Lorsque nous notons des nombres, le chiffre qui a le plus de poids est à gauche. Il s'appelle le MSB (ou most significant Bit/Byte). Celui qui a le moins de poids s'appelle le LSB (ou Less Significant Bit/Byte). A noter que l'on peut parler de MSB pour des octets (Byte) lorsqu'il en a plusieurs, aussi bien que pour des Bits (valeur la plus élémentaire en binaire).

Ainsi lorsque nous notons 0xABCD, le MSB (ou octet de poids fort) est 0xAB, et 0xCD correspond à l'octet de poids faible. De la même manière, lorsque l'on note 0b10000000 le 1 correspond au MSB et le zéro le plus à droite au LSB.

Désolé pour ces notions, mais nous en aurons besoin plus tard...

Convertir des bits en lumière et introduction de la modulation:

Nous avons donc un moyen de convertir une valeur numérique en train d'impulsion lumineuses. Effectivement, on pourrait se contenter d'émettre dans l'infrarouge avec un protocole simpliste (ex : 1 = de la lumière, 0 = pas de lumière) à la façon du morse. Malheureusement, c'est une fausse bonne idée. En effet, même si l’œil n'est pas capable de détecter l'infrarouge, nous baignons dedans... Lumière solaire, etc.. seraient autant de perturbations qui rendraient le code invalide. C'est très précisément pour cela qu'a été introduite la notion de modulation.

Une modulation à haute fréquence est introduite sur le signal. Celle ci peut être à 30 kHz, 33 kHz, 36 kHz, 38 kHz, 40 kHz, et 56 kHz. Les plus fréquentes sont à 36 ou 38Khz. Les récepteurs infrarouge intègrent un étage de démodulation, qui permet de disposer d'une bonne immunité au bruit (lumières environnantes parasites qui elles ne sont pas modulées..).

Merci à SBProjects.com pour le gif et toutes les infos sur l'infrarouge :

irmod.gif, mai 2021

La chaine complète de traitement se comporte comme suit :

Arduino-IR-Remote-Receiver-Tutorial-IR-Signal-Modulation.png, mai 2021

Note importante : Il va être important de savoir a quelle fréquence de modulation une télécommande émet, car il faudra choisir le récepteur avec démodulateur intégré de la même fréquence, sous peine d'avoir une portée très limitée. A noter que même si la différence de fréquence de modulation semble faible (ex : 36 versus 38 Khz), l'étage de démodulation est suffisamment performant pour pratiquement exclure la modulation adjacente...

Encodage des uns et des zéros

Différents types d'encodage existent pour coder des uns et des zéros à partir d'un signal électrique ou lumineux :

Distance d'impulsion : une impulsion de longueur fixe, est suivie d'un espace dont la longueur est représentative d'un un ou un zéro.

pulse-distance.png, mai 2021

Largeur d'impulsion : une impulsion de largeur variable est suivie d'un espace de longueur fixe. La largeur de l'impulsion représente un un ou un zéro.

pulse-width.png, mai 2021

Encodage par position d'impulsion (NRZ) : le temps est divisé en espaces de longueur fixe. La présence d'une impulsion représente un 1, tandis que son absence représente un zéro.

pulse-position.png, mai 2021

Encodage Manchester (Biphase) : Chaque bit est divisé en 2 demi bits. La transition d'un zéro à un un représente un 1 zéro logique, tandis que la transition d'un 1 à un zéro représente un 1 logique.

manchester.png, mai 2021

Beaucoup de codages infrarouge reposent sur le codage par largeur d'impulsion. C'est par exemple le cas de Nec, RC6, et Denon sur lesquels j'ai pu investiguer

MSB et LSB dans une transmission IR

Le dernier point restant à voir est l'ordre de transmission des bits. En effet, selon les protocoles, ce n'est pas constant.... Le protocole Nec, par exemple, transmet les LSB (ou bits de poids faible) d'abord... Cela oblige à une petite gymnastique pour remettre les bits dans l'ordre. C'est l'inverse pour les protocole RC6.

Exemple de décodage avec le protocole NEC

Le protocole de transmission Infrarouge de NEC utilise l'encodage de distance d'impulsion pour chaque bit. Chaque impulsion fait 562.5µs, à une fréquence de porteuse de 38kHz (26.3µs). Les bits sont transmis comme suit :

  • '0' logique – une impulsion de 562.5µs suivie par un espace de 562.5µs soit un temps total de transmission de 1.125ms
  • '1' logique – une impulsion de 562.5µs suivie d'un espace de 1.6875ms soit un temps de transmission total de 2.25ms

Lorsque une touche est appuyée sur la télécommande, un message est transmis avec dans l'ordre :

  • Une impulsion de 9ms pour matérialiser le démarrage de la trame (16 X la longueur d'un bit de données)
  • Un espace de 4.5ms
  • Les 8 bits d'adresse du périphérique
  • L'inverse bit à bit de l'adresse logique
  • Les 8 bits de la commande
  • L'inverse bit à bit de la commande
  • Une impulsion finale de 562.5µs pour signifier la fin de la transmission

Les 4 octets sont transmis avec le LSB (ou bit de poids le plus faible) d'abord. Le schéma ci dessous illustre le format d'une transmission NEC avec une adresse de 00h (00000000b) et une commande 0xAD (0b10101101):

NECMessageFrame.png, mai 2021

Les bits de la commande ou de l'adresse sont transmis dans l'ordre ( LSB ) 1 0 1 1 0 1 0 1 ( MSB ). Il faut dont les lire de droite à gauche pour reformer la commande originale ( MSB ) 1 0 1 0 1 1 0 1 ( LSB ) , soit 0xAD ou 173 en décimal.

Code de répétition :

Si la touche de la télécommande reste appuyée, un code de répétition est envoyé, typiquement 40ms après l'impulsion de fin de message.. Ce code de répétitionn sera envoyé à des intervalles de 108ms jusqu'à ce que la touche soit relancée. Ce code de répétition est constitué, dans l'ordre :

  • D'une impulsion de départ de 9ms
  • D'un espace de 2.25ms
  • D'une impulsion de 562.5µs pour marquer la fin de la transmission

Voici un exemple avec deux répétitions du code :

NECRepeatCodes.png, mai 2021

Protocole NEC1 ou NEC2 ?

Une particularité du protocole NEC est que la longueur des trames est constante puisque pour chaque un transmis il y a aussi un zéro. Chaque octet étant transmis 2 fois (une fois normalement et une fois en complément à 1), cela permet de vérifier que la réception n'a pas été endommagée.

Toutefois, ce protocole étant très utilisé sur de nombreux périphériques, il est apparu qu'un seul octet pour l'adresse devenait insuffisant. Le complément de commande a donc été remplacé dans une évolution du protocole par un 2e octet d'adresse, en sacrifiant la redondance et la transmission de longueur fixe. Cette 2e version est souvent appelée NEC2, et la première NEC1.

Les 2 versions du protocole sont activement utilisées.

Réalisation d'un dispositif de capture et décodage de codes infrarouges

Il y a beaucoup de choses publiées sur internet concernant la capture, le décodage, l'émission de codes infrarouge. Je voulais un dispositif réutilisable avec un logiciel d'analyse qui permette de faire de l'analyse sur de multiples télécommandes. Le logiciel IR Scrutinizer (oui, non à chier..) associé au périphérique de capture DIY à base d'Arduino m'ont parus être un bon compromis. Fonctionnant en Java sur toutes les plateformes, il permet la capture, visualisation, fabrication de fichiers de config et même émission de codes.

Le périphérique de capture quand à lui est facile à fabriquer, utilisables sur n'importe quel ordinateur et même en périphérique externe pour LIRC sous Linux...

Le matériel et le logiciel embarqué

Le matériel est très facile à fabriquer. Reposant sur une Arduino Nano, il permet la réception via 2 récepteurs :

  • L'un pour l'analyse de trames, sans démodulateur, ce qui permet d'analyser la fréquence de la porteuse.
  • L'un pour la réception de codes, avec un démodulateur 38Khz

Il dispose également de leds infrarouge pour émission de signaux infrarouge, soit les signaux capturés, et même des signaux générés à l'aide du générateur intégré.

Enfin, plusieurs leds permettent de visualiser l'état du périphérique.

Sa réalisation est détaillée ICI : http://www.harctoolbox.org/arduino_nano.html. J'ai trouvé le matériel sur le site TME.eu, à l'exception du récepteur démodulé "TSOP34438" que j'ai remplacé par un "TSOP34338" pratiquement équivalent.

A noter qu'il repose sur le programme AGIRS ( https://github.com/bengtmartensson/AGirs ) qui supporte beaucoup plus de fonctionnalités, comme Arduino Leonardo ou Pro micro, Arduino Mega avec Shield ethernet, etc.. Donc pour ceux qui veulent aller plus loin, c'est possible... et c'est prévu.

C'est d'ailleurs ce que j'ai fait sur arduino Pro Micro (compatible Leonardo) en ajoutant une led de status aux 3 déjà gérées, et un buffer sur les leds Infrarouge afin de leur faire cracher 100 ma. L'émetteur est désormais assez puissant pour taper à une distance de 6/7 mètres.

Vue de l'émeteur / récepteur Agirs à base d'Arduino pro micro:

agirs.jpg, mai 2021

Logiciel de capture de trames et décodage : IRScrutinizer

Installation du logiciel et premiers pas

Il va tout d'abord télécharger et installer le logiciel à partir du site http://www.harctoolbox.org/downloads/index.html (exemple "IrScrutinizer 1.1.3 setup.exe for Windows" ).

Ensuite à va vous falloir lancer le logiciel et configurer le périphérique de capture. Pour cela allez dans l'onglet "Sending Hw" (1), le sous onglet "Girs Client" (2), sélectionnez le port série ou le dispositif Agirs est raccordé (3), et cliquez sur "connect" (4). Un message avec la version d'Agirs devrait apparaitre en (5).

irscrutinizer-config.png, mai 2021

Placez la télécommande à capturer devant les capteurs :

positionnement-telecommande.jpg, mai 2021

Il est maintenant temps de procéder à votre première capture. Allez dans l'onglet "Scrutinize signal"(1). Appuyez ensuite sur "record" (2) puis sur une touche de la télécommande. Après capture et décodage, 'lécran se présente comme suit :



irscrutinizer-capture.png, mai 2021

Le code reconnu est affiché en (3).. Ici, nous avons un protocole NEC1, avec 1 octet d'adresse et un octet de commande. Une fenêtre de visualisation montre ce qui a été reconnu (4). On voit également en (5) les longueurs en microsecondes des impulsions, ainsi que la fréquence de modulation (ici 38.461Khz).

Dans le graphe, on voir une impulsion à la fin qui est un "repeat code", comme expliqué dan sle décodage Nec plus haut. On le retrouve indiqué dans la valeur décodée ( NEC1: {D=1,F=128}, beg=0, end=71, reps=1 )

A noter que dans le menu "Options", j'ai coché "Verbose", ce qui me permet d'avoir dans le champ "IRP" une version un peu plus bavarde, notamment avec la version binaire de ce qui a été récupéré :

{38.5k,543,msb}<1,-1|1,-3>(8901u,-8,A:32,1,-39.574m,8901u,-3,1,-65m){A=0b10000000011111110000000111111110}

Si nous nous attachons à cette version binaire, et extrayons 8 par 8 les bits, puis les retournons (n'oubliez pas: NEC transmet les LSB en premier..) nous avons :

  • A=0b10000000011111110000000111111110
  • Premier octet : 10000000 . Remis avec le LSB à droite : 00000001. Valeur d'adresse = 0x01 soit 1 en décimal.
  • Deuxième octet : 01111111 . C'est bien le strict complément à un du 1er octet. fin de traitement.
  • Troisième octet : 00000001 . Remis avec le LSB à droite : 10000000. Valeur de touche appuyée = 0x80 soit 128 en décimal.
  • Quatrième octet : 11111110 . C'est bien le strict complément à un du 1er octet. fin de traitement.

Nous retrouvons donc bien ce qui nous est indiqué comme valeur décodée ( NEC1: {D=1,F=128}, beg=0, end=71, reps=1 )

Voici un exemple de décodage réalisé avec le protocole NEC2, c'est à dire une une adresse d'équipement (D), une adresse de sous système (S) et un code de fonction (F), ici avec la touche Power d'une télécommande d'un Ampli AV NAD :

nec1.png, mai 2021

Décodages complexes

Pour d'autres protocole, c'est parfois plus difficile de comprendre. J'ai par exemple mis un moment sur le protocole Denon (variante du protocole Sharp), qui est moins bien documenté sur internet :

denon.png, mai 2021

J'ai trouvé sur le net une doc qui n'est pas spécifique à mon appareil, mais donne des infos sur le protocole : AVRX1000_E300_IR_CODE_V01.pdf . Le MSB serait transmis en premier, et les 15 bits utiles seraient regroupés comme suit :

C1~C5 : SYSTEM ADDRESS= constante à 01000
C6~C11 : Data 
C12,C13 : Extension bit : constante à 1 1
C14: constante à  0  
C15 : constante à 0

Autre particularité, il semblerait que la transmission se fasse en 3 fois : la première et la troisième avec le code normal, et la 2e avec les bits C6 à C15 inversés. On peut aisément le vérifier dans le flot de données récupérées décodées (en gras les bits inversés )

A=0b10000100011100, B=0b10001011100011, C=0b10000100011100

Notre transmission semble ne faire que 14 bits alors que le document de décodage dit qu'il en fait 15... Si nous ajoutons un leading zero pour le décodage et nous remettons en forme les bits pour mieux le comprendre, cela donne :

C1 ~C5 : 01000 : System address = 8 en décimal pour un amplificateur... OK, ca tombe bien c'est la télécommande de mon ampli :). C6 à C11 : 010001 : Power Off d'après le tableau dans le PDF (c'est bien la touche que j'ai appuyée) C12,C13 : 11 C14 : 0 C15 : 0

Il s'agit donc bien d'un protocole Denon, sur un ampli, et de l'appui sur la touche power off . On voir donc bien l'intérêt de disposer d'un logiciel de décodage...

Usage avancé :

Lorsque vous avez bien compris le fonctionnement de votre télécommande, vous pouvez effectuer la capture de chacune des touches dans l'onglet "Scrutinize remote". Il suffit de se placer dans "Paramétric remote", cliquer sur Capture, et appuyer sur chacune des touches puis taper un nom de fonction et un commentaire pour décrire la touche.

A noter que l'arrêt de la capture se fait en rappuyant sur "Capture", et en refaisant une capture en appuyant sur une touche de la télécommande. Vous pouvez avec bouton de droite éditer le contenu du tableau par exemple pour supprimer des lignes surnuméraires.

Une fois cette capture faite, vous allez pouvoir aller dans l'onglet "Export", Choisir "L'export format", et faire "export Param Remote" pour créer un fichier de sauvegarde ou de config. Le logiciel supporte même la production directe de code Arduino... Sympa!.

Si votre télécommande n'est pas décodée (c'est à dire pas reconnue par l'un des décodeurs intégrés), vous pouvez passer en mode "Raw remote" dans "Scrutinize remote", et "Export raw remote" dans l'onglet export. Ceci aura pour effet de générer des timings d'impulsion au lieu du vrai protocole, mais c'est par contre très intéressant pour mimer des télécommandes inconnues.

L'onglet "Generate" va vous permettre de générer des codes IR pour les protocoles connus ou inconnus (mode raw). Votre périphérique de capture Agirs étant également en capacité d'envoyer des codes, cela vous permettra de vérifier que votre équipement réagit bien à ce que vous avez capturé / généré.

A noter que si vous désirez sauver des données capturées (par exemple dans l'onglet Scrutinize remote") il est souhaitable de choisir comme format d'export GIRR, qui vous permettra de réimporter lors d'une autre session de travail avec tous les paramètres.

Conclusion

C'est tout pour ce premier volet décodage et génération de codes IR. Tout n'est pas dit, mais le site de l'auteur de IR Scrutinizer fourmille d'infos que je vous recommande de consulter...

Sommaire des articles de la série: