Outils pour utilisateurs

Outils du site


rbpi:rbpi_lirc_telecommande_infrarouge

Montage électronique

Ce montage est lié aux GPIO 17 et 18

 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 :

  1. Le condensateur C2 n'est pas indispensable. Il sert à augmenter la stabilité de la tension d'alimentation du récepteur IR.
  2. 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 : 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 <AttenteAvantPremierPulse>
    pulse <pulseBit1>  space <spaceBit1>
    pulse <pulseBit2>  space <spaceBit2>
    ...
    pulse <pulseBitN>  space <spaceBitN>

<AttenteAvantPremierPulse>, <pulseBitI> et <spaceBitI> 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 <AttenteAvantPremierPulse>

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/<nomTelecommande>.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 <gap length> : A (typically long) space which follows the trailing pulse. Cela signigie que la fin d'un signal doit être suivie d'un

    space <gap length>

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 :

  1. on convertit sa valeur hexa en binaire.
  2. Puis on traduit les bits à partir de la définition de one et zero précédente.
  3. Mais préalablement on a exécuté header
  4. enfin à la fin de l'envoi du signal, on envoi ptrail
  5. 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 "$@"
rbpi/rbpi_lirc_telecommande_infrarouge.txt · Dernière modification: 2021/02/10 19:06 (modification externe)