===== Montage électronique ===== Ce montage est lié aux GPIO 17 et 18 {{ :ir_emitter_receiver.png?direct&400 | Schema IR}} ==== Premier schéma : le récepteur ==== Quand le récepteur recoit un signal IR (impulsions IR cadencées à une certaine fréquence), il transmet un HIGH au PIN 18, que le RBPI lira donc. Quand il ne recoit rien, le RBPI lit 0. Remarques : - Le condensateur C2 n'est pas indispensable. Il sert à augmenter la stabilité de la tension d'alimentation du récepteur IR. - L'alimentation peut être du 5V (lire datasheet du produit acheté) ==== Deuxième schéma : émetteur, dans une version à double étage de transistor ==== Le GPIO 17 commande l'émission ou non du signal. Lorsqu'il est HIGH, le transistor NPN Q2 devient passant car sa diode Base/Emetteur est alimentée par une tension. Le point à l'émetteur de Q2 voit alors une tension de 5V - Vce2, i.e proche de 5. \\ Par conséquent, Q1 devient passant aussi et ferme donc le circuit impliquant l'allumage des LEDs. \\ Si je ne dis pas de bêtise, le courant passant dans R1 = 5V-Vce2-Vbe1 / R1 \\ Si Vce=0.3V et Vbe=0.7V, le courant vaudra 4/100=40mA.\\ Il ne faut pas qu'il soit trop grand, c'est un courant de commande.\\ Par contre, il l'est largement suffisamment pour commander le courant collecteur-->émetteur, qui vaut normalement B*courant base/émetteur, (B est le gain, l'ordre de grandeur varie en général de 10 à 100 au max). Mais comme Vce1 vaut 0.3V aussi (on va dire que les Vce sont en général quasinul, je ne sais pas trop pourquoi ...) on a un courant total tranversant le circuit des LED qui vaut min(5V-Vce1-Uled/R4, B*courant base/émetteur). \\ Le min étant bien évidemment 5V-Vce1-Uled/R4 ==> 4.7/R4 = 20mA. \\ En fait moi j'ai encore diminué la résistance d'alimentation des LED pour avoir un max de puissance d'émission. ===== Mise en place de LIRC et outils liés sur mon RBPI2 ===== ==== Choix des gpio ==== J'ai choisi comme émetteur GPIO 24 et comme récepteur le GPIO 23. Pour visualiser les modes et valeurs des GPIO (en utilisant la lib wiringPi), on fait #gpio readall --> montre que les pins 23 et 24 (BCM) doivent être respectivement en mode IN et OUT Extrait des GPIO (gpio readall) : | BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM | +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+ | . | . | . | . | 0 | 9 || 10 | . | . | . | . | . | | 17 | 0 | GPIO. 0 | OUT | 0 | 11 || 12 | 0 | IN | GPIO. 1 | 1 | 18 | | 27 | 2 | GPIO. 2 | IN | 0 | 13 || 14 | | | 0v | | | | 22 | 3 | GPIO. 3 | IN | 0 | 15 || 16 | 0 | IN | GPIO. 4 | 4 | 23 | | | | 3.3v | | | 17 || 18 | 0 | OUT | GPIO. 5 | 5 | 24 | Visuel plus sexy des GPIO du RBPI2 tiré du blog d'idleman : [[http://images.google.fr/imgres?imgurl=http://pi4j.com/images/j8header-2b-large.png&imgrefurl=http://pi4j.com/pins/model-2b-rev1.html&h=1530&w=843&tbnid=gj_vZOALhVgJCM:&tbnh=91&tbnw=50&docid=1s2C61VHqmyqDM&usg=__C2qfoRXZZGjd9dUgyJzLoPgpQZ0=&sa=X&ved=0ahUKEwisoKmunZvNAhXGCSwKHYXRBFEQ9QEIHjAA|GPIO RBPI2]] ==== Installation ==== L'OS était un raspbian (jessie je crois), Lirc en version 0.9.4 ** Configuration des GPIO utilisé par le module lirc_rpi ** > vi /boot/config.tx, , puis remplacer la ligne suivante dtoverlay=lirc-rpi par dtoverlay=lirc-rpi,gpio_in_pin=23,gpio_out_pin=24 > vi /etc/modules, puis remplacer la ligne suivante lirc_rpi par lirc_rpi gpio_in_pin=23 gpio_out_pin=24 > Redémmarer le raspberrypi Autre option, à chaud : sudo service lirc stop --> pour etre sur que le module lirc_rpi n'est pas utilise par lirc sudo modprobe -r lirc_rpi --> décharge le module du kernel actif sudo modprobe lirc_rpi gpio_in_pin=23 gpio_out_pin=24 debug=1 --> 23 sera le recepteur et 24 l'émetteur ** Remarque avant de commencer ** J'avais installé une autre version de lircd pour mon dongle IRDROID. C'est la version /usr/local/sbin/lircd Du coup which lircd donne --> /usr/local/sbin/lircd ==> Du coup dans la suite des fois il faut mettre /usr/bin/ devant les exécutables !!! ** Tester le bon fonctionnement de la réception : ** sudo /etc/init.d/lirc stop mode2 -d /dev/lirc0 Remarque : En cas de succès mode2 affiche à l'écran la trace suivante pour chaque signal : space pulse space pulse space ... pulse space , et sont en microsecondes Dans une configuration lirc de télécommande en mode raw (flags RAW_CODES|CONST_LENGTH), on retrouve pour chaque bouton les valeurs ci-dessus exceptée la première : space ** Enregistrer les signaux d'une télécommande : irrecord ** D'abord, il faut arrêter le daemon lircd s'il est actif. sudo service stop lirc Ensuite, taper ceci et se laisser guider irrecord -d /dev/lirc0 /home/pi/tests/.conf Remarques : - irrecord permet de reprendre un fichier de conf existant pour rajouter des signaux - des options permettent : - -f : de forcer l'enregistrement en mode raw (pas de tentative de générisation des codes) - -n : permet d'éviter la vérification du namespace des boutons quand on les renseigne au moment de l'enregistrement (sans cette option, si pas dans le namespace, irrecord demande de retaper un nom valide) Une fois l'enregistrement, il est possible d'inclure le fichier de conf enregistré dans la conf globale de lirc en faisant ceci : Include "/home/pi/src/Infrared/IR_remotes/remotes/HK_AVR500_LearnedFrom_LircRbpi.conf" Remarque : au lieu d'enregistrer des télécommandes, on peut essayer trouver des télécommandes déjà enregistrées sur le site de LIRC : [[http://lirc.sourceforge.net/remotes/]] ** Lancer le démon lirc ** \\ (Pour ma part, j'ai du au préalable désactiver mon démon lirc_maintain qui supprimait la socket /var/run/lirc/lircd. En effet, j'avais aussi installé une version de lircd spécifique (ne contenant que usb_irtoy) pour tester mon dongle android, qui malheureusement ne fonctionne pas bien sur mon RBPI ... Ce lircd est installé dans /usr/local/bin/lircd. Comme ce démon s'arrêtait fréquemment, j'avais tenté des workaround permettant de le relancer, mais malgré ça, ça finissait par planter complètement le dongle, qui devenait invisible à l'OS ... sacré bug de merde ) sudo /usr/sbin/lircd --nodaemon -o /var/run/lirc/lircd -d /dev/lirc0 irw /var/run/lirc/lircd Normalement le service de lircd (nommé lirc) est installé par l'install via apt-get. ==> il suffit de vérifer que le service défini dans /etc/init.d invoque bien le bon binaire démon. ** Emission code IR : irsend, qui s'appuie sur la socket de lircd ** irsend -d /var/run/lirc/lircd SEND_ONCE "Samsung_BN59_LearnedFromIRDroid.conf" "KEY_POWER" irsend -d /var/run/lirc/lircd SEND_ONCE "Samsung_BN59_LearnedFromIRDroid.conf" "KEY_POWER" -c 50 --> envoie 50 fois --> Ca fonctionne ; j'ai modifié dans le schéma électronique la valeur de la résistance en amont des LEDS modifiée à 25 Ohm. ==> courant traversant résistance = ( 9V - 2V ) / 25 Ohm = 280 mA ==> courant traversant les LED = 90mA (les phases 1-->0 sont fréquentes, on joue là dessus) Test OK avec ma TV samsung qui est à 5/6 mètres, avec mon PC portable (équipé d'un récepteur Speedlink) Possibilité de faire plus propre avec des émetteur récepteur groove : [[http://anderson69s.com/2015/08/04/raspberry-pi-dupliquer-sa-telecommande-ir/]] __**Remarques :**__ Pour certains produits (coté récepteurs), comme celui de mon purificateur d'air Klarstein modèle 10021654 , il est nécessaire d'envoyer 2 fois le signal : irsend -d /var/run/lirc/lircd SEND_ONCE "Karstein_Purificateur" "SPEED" --count=2 En effet, selon [[http://winlirc.sourceforge.net/technicaldetails.html]] : gap : A (typically long) space which follows the trailing pulse. Cela signigie que la fin d'un signal doit être suivie d'un space Pour que le trailing space puisse être reconnu, il faut renvoyer le signal une 2e fois immédiatement !!! Sinon, aucun logiciel ne pourra __détecter__ quand le trailing space du 1er message se termine !! **__Exemple d'une remote dans un fichier de conf de LIRC__** # brand: Harman Kardon # model no. of remote control: AVR 500 # devices being controlled by this remote: begin remote name AVR500_LircRbpi bits 32 flags SPACE_ENC|CONST_LENGTH eps 30 aeps 100 header 9048 4463 one 620 1618 zero 620 511 ptrail 620 repeat 9048 2197 gap 108057 toggle_bit_mask 0x0 begin codes on 0x010E03FC off 0x010EF906 vol_up 0x010EE31C vol_down 0x010E13EC back 0x010EED12 end codes end remote __Explication rapide et incomplète mais un bon début pour comprendre :__ \\ '__SPACE_ENC__' signifie que la valeur de chaque bit est coté par la durée des pulsations ; \\ '__one 620 1618__' signifie que 0 est codé par une pulsation IR de 620us suivi d'une attente de 1618 us\\ '__zero 620 511__' signifie que 1 est codé par une pulsation IR de 620us suivi d'une attente de 1618 us\\ '__bits 32'__ indique que tous les signaux de cette télécommande contiennent 32 bits \\ '__header__ 9048 4463' : correspond à un pulse IR de 9048us et une attente de 4463us --> ca permet de mieux identifier cette télécommande. Cette phase exécuté au début d'émission de chaque signal de cette télécommande.\\ '__gap__ 108057' : correspond à la durée totale du signal, mais cette valeur peut varier se le contexte\\ '__repeat__ 9048 2197' et toggle_bit_mask 0x0 sont des codes liés à la notion de répétition d'un signal. Il semblerait que cela permette d'éviter de renvoyer entièrement le signal ...\\ '__ptrail__ 620' correspond à un pulse de fin d'une durée de 620us, envoyé à la fin du signal. Ca permet la aussi de rendre le signal IR encore plus unique, et donc d'améliorer les chance d'identification.\\ On peut aussi trouver parfois des infos comme celles-ci '__pre_data_bits 16__' : cela signifie que tous les signaux commenceront pas 16bits d'entête \\ '__pre_data 0x10E__' : la valeur de l'entête de 16bits à coder sera 0x10E, i.e en binaire 0000000100001110 \\ '__eps__' et '__aeps__' sont des valeurs de tolérance concernant les durées des pulses utilisé par l'algorithme LIRC de reconnaissance des signals recu par le récepteur IR. Ensuite la section begin codes contient les signaux associés aux boutons d'une télécommande \\ \\ Au final, par exemple le signal '__on__' est 0x010E03FC.\\ Pour l'envoyer : - on convertit sa valeur hexa en binaire. - Puis on traduit les bits à partir de la définition de __one__ et __zero__ précédente. \\ - Mais préalablement on a exécuté __header__ - enfin à la fin de l'envoi du signal, on envoi __ptrail__ - et enfin si des flags de repeat sont positionnés et qu'on veut envoyer des choses plusieurs fois alors ... ? ===== Mise en place de LIRC et outils liés sur mon RBPI3 ===== Mon os : * Linux raspberrypi 5.4.51-v7+ #1333 SMP Mon Aug 10 16:45:19 BST 2020 armv7l GNU/Linux * Raspbian GNU/Linux 10 (buster) Version de lirc ( sudo apt-cache policy lirc ) : * 0.10.1-6.2~deb10u1+rpt1 ==== Mise en place ==== === Dans le fichier /boot/config.txt === dtoverlay=gpio-ir,gpio_pin=23 dtoverlay=gpio-ir-tx,gpio_pin=24 La ligne gpio-ir permet d'activer le module kernel gpio_ir_recv, et de lui passer les bon paramètres. \\ La ligne gpio-ir-tx permet d'activer le module kernel gpio_ir_tx, et de lui passer les bon paramètres. On comprendra facilement que le module gpio_ir_recv est celui qui met en oeuvre la réception des codes InfraRouge, et que le module gpio-ir-tx est celui qui permet de mettre en oeuvre l'envoie de commande InfraRouge. === Dans le fichier /etc/lirc/lirc_options.conf === #driver = devinput driver = default #device = auto device = /dev/lirc0 logfile = /var/log/lirc.log === Rebooter et vérifier que les modules === lsmod | grep gpio doit retourner les lignes suivantes : gpio_ir_tx 16384 0 gpio_ir_recv 16384 0 ==== Principe de fonctionnement et rappel ==== La commande suivante ls -l /dev/li* doit retourner les lignes suivantes. crw-rw---- 1 root video 251, 0 Feb 10 12:09 /dev/lirc0 crw-rw---- 1 root video 251, 1 Feb 10 12:09 /dev/lirc1 Remarques : Le device /dev/lirc1 est normalement activé par le module gpio_ir_recv. \\ Le device /dev/lirc0 est normalement activé par le module gpio_ir_tx. ==== Tests de la réception ==== La commande suivante permet de tester que le récepteur est bien branché. Des lignes doivent défiler sur la sortie standard quand vous pointez votre télécommande IR sur votre récepteur IR et que vous appuyer sur un bouton. sudo mode2 -d /dev/lirc1 -H default Si cela fonctionne, l'étape suivante consiste à faire apprendre ses télécommandes. Par exemple en tappant la commande suivante et en se laissant guider par le wizard. irrecord -u -d /dev/lirc1 -H default /home/pi/myNewRemote.conf La liste de toutes les télécommandes qui peuvent être utilisées par lircd sont dans ce fichier : /etc/lirc/lircd.conf.d/devinput.lircd.conf Donc si vous voulez que votre télécommande puisse être utilisée/connue par LIRC, vous devez copier le contenu de votre fichier à la fin de /etc/lirc/lircd.conf.d/devinput.lircd.conf ==== Test d'envoi ==== Rappel : LIRCD est un daemon qui écoute sur une socket locale ; souvent, elle située ici : /var/run/lirc/lircd Elle permet un échange full-duplex : === Envoi de signal === Lorsque que l'utilisateur pousse un truc dessus (via irsend par exemple), ce qu'elle recoit (la commande d'envoie) est consommé par lircd, qui se charge d'envoyer la commande en regardant le fichier des télécommandes (devinput.lircd.conf). Comme nous avons défini plus haut dans lirc_options.conf que le device d'envoie est /dev/lirc0. La commande suivante devrait faire le travail : irsend --count=30 -d /var/run/lirc/lircd SEND_ONCE "samsungsmarttv" "power" === Automatisation/Handling de réception de signal === A l'inverse, quand un signal est recu, lircd recoit le signal du device /dev/lirc0 et le transmet sur sa socket /var/run/lirc/lircd. Les programmes comme irw ou irrexec écoutent sur cette socket et consommeront alors les messages envoyés par lircd. irw /var/run/lirc/lircd Néanmoins, dans cette dernière version, rien ne se passera, voir la suite : ==== Le hic ==== Depuis cette dernière version de lirc mis en oeuvre, on constate que les nouveaux modules kernel gpio_ir_recv et gpio_ir_tx imposent l'utilisation de 2 devices /dev/lirc0 et /dev/lirc1. L'un pour l'envoi, et l'autre pour la réception de signaux. Nous avons utilisé /dev/lirc0 dans notre conf précédente lirc_options.conf. Comme /dev/lirc0 correspond au device chargé d'envoyé (mis en oeuvre par gpio_ir_tx), nous ne pouvons utiliser notre démon lircd que pour envoyer des signaux. Si nous avions voulu nous en servir pour faire du irw, ou plutôt du irexec ou du kodi ou autre, il aurait fallu définir /dev/lirc1 dans lirc_options.conf Cela signifie que pour conserver les fonctionnalités de lirc qui permettait non seulement d'envoyer des signaux, mais de "handler" la réception de signaux, il faut manuellement créer un 2e service lircd. Le mode opératoire serait le suivant : E1 : Add these rules in /etc/udev/rules.d/71-lirc.rules to get stable /dev/lirc-rx and /dev/lirc-tx device names: ACTION=="add", SUBSYSTEM=="lirc", DRIVERS=="gpio_ir_recv", SYMLINK+="lirc-rx" ACTION=="add", SUBSYSTEM=="lirc", DRIVERS=="gpio-ir-tx", SYMLINK+="lirc-tx" ACTION=="add", SUBSYSTEM=="lirc", DRIVERS=="pwm-ir-tx", SYMLINK+="lirc-tx" E2 : Change the device and listening address in /etc/lirc/lirc_options.conf: device = /dev/lirc-rx listen = 0.0.0.0:8766 E3 : Copy lirc_options.conf to lirc_tx_options.conf and edit these lines: device = /dev/lirc-tx output = /var/run/lirc/lircd-tx pidfile = /var/run/lirc/lircd-tx.pid listen = 0.0.0.0:8765 connect = 127.0.0.1:8766 E4 : Create /etc/systemd/system/lircd-tx.service (from the output of systemctl cat lircd) and edit it to be: [Unit] Documentation=man:lircd(8) Documentation=http://lirc.org/html/configure.html Description=Second lircd, the transmitter Wants=lircd-setup.service After=network.target lircd-setup.service lircd.service [Service] Type=simple ExecStart=/usr/sbin/lircd --nodaemon --options-file /etc/lirc/lirc_tx_options.conf ; User=lirc ; Group=lirc ; Hardening opts, see systemd.exec(5). Doesn't add much unless ; not running as root. ; ; # Required for dropping privileges in --effective-user. ; CapabilityBoundingSet=CAP_SETEUID ; MemoryDenyWriteExecute=true ; NoNewPrivileges=true ; PrivateTmp=true ; ProtectHome=true ; ProtectSystem=full [Install] WantedBy=multi-user.target E5 : Create /etc/systemd/system/lircd-tx.socket (from the output of systemctl cat lircd.socket) and edit it: [Socket] ListenStream=/run/lirc/lircd-tx [Install] WantedBy=sockets.target Also=lircd-tx.service Start lircd-tx: sudo systemctl daemon-reload sudo systemctl start lircd-tx sudo systemctl enable lircd-tx E6 : Create /usr/local/bin/irsend and make it executable: #! /bin/sh exec /usr/bin/irsend --device=/var/run/lirc/lircd-tx "$@"