===== 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 "$@"