Un ‘notificateur’ en USB

Alors qu’il fouillait « L’Armoire à Goodies » à la recherche de cadeaux pour les Auditeurs, Yann de Futuradios a exhumé une espèce de boite en forme d’enveloppe connectable en USB qui s’allume pour notifier de la présence de messages (mail, réseaux réseaux sociaux)…

Yann a donné le gadget en question à mon fils Yvan pour voir s’il y a moyen de l’utiliser à la radio, par exemple pour afficher en studio l’arrivée d’une dédicace.

Bien que le gadget ci-dessous soit à la base de cet article les concepts sont utilisables avec la LED située sur la carte du Raspberry ou avec un autre gadget.

La « chose » est fournie avec un mini cdrom contenant un logiciel dédié fonctionnant sous Windows, je ne l’ai pas installé puisqu’il s’agit de l’utiliser sur un des Raspberry Pi installés dans le studio…

Je m’attendais à ce que la « chose » soit reconnue comme un HID (Human Interface Device) et j’avais commencé à me documenter sur le sujet… C’est donc en m’attendant au pire que j’ai branché le connecteur USB. La commande ‘dmesg’ renvoie ceci:

[  218.872752] usb 1-1.4: new low-speed USB device number 5 using dwc_otg
[  219.014859] usb 1-1.4: New USB device found, idVendor=1294, idProduct=1320
[  219.014877] usb 1-1.4: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[  219.014888] usb 1-1.4: Product: MAIL
[  219.014901] usb 1-1.4: Manufacturer: MAIL
[  219.026698] hid-led 0003:1294:1320.0002: hidraw0: USB HID v1.10 Device [MAIL  MAIL ] on usb-3f980000.usb-1.4/input0
[  219.027199] hid-led 0003:1294:1320.0002: Riso Kagaku Webmail Notifier initialized

On voit la séquence classique de connexion d’un équipement USB et « Ô Surprise » on voit également que le driver ‘hid-led’ a reconnu notre appareil… Le code du driver est disponible sur github hid-led.c

Dans /sys/class/leds on retrouve les 2 LED présentes sur le Raspberry et 3 LED ‘riso_kagaku0’, une pour chaque couleur RGB, chacun de ces liens pointant vers un répertoire. Notez au passage la numérotation des LED.

 pi@raspberrypi:~ $ cd /sys/class/leds/
 pi@raspberrypi:~ $ ls -l /sys/class/leds
 total 0
 lrwxrwxrwx 1 root root 0 May  6 20:55 led0 -> ../../devices/platform/leds/leds/led0
 lrwxrwxrwx 1 root root 0 May  6 20:55 led1 -> ../../devices/platform/leds/leds/led1
 lrwxrwxrwx 1 root root 0 May  6 20:55 riso_kagaku0:blue -> ../../devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/0003:1294:1320.0003/leds/riso_kagaku0:blue
 lrwxrwxrwx 1 root root 0 May  6 20:55 riso_kagaku0:green -> ../../devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/0003:1294:1320.0003/leds/riso_kagaku0:green
 lrwxrwxrwx 1 root root 0 May  6 20:55 riso_kagaku0:red -> ../../devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/0003:1294:1320.0003/leds/riso_kagaku0:red

Dans le répertoire correspondants aux LED deux fichiers sont intéressants, il s’agit de ‘brightness’ et ‘max_brightness’, qui vont permettre de positionner la luminosité et de connaître la valeur maximale de la luminosité.

pi@raspberrypi:~ $ ls -l /sys/class/leds/riso_kagaku0\:green/
total 0
-rw-r--r-- 1 root root 4096 May  7 19:26 brightness
lrwxrwxrwx 1 root root    0 May  7 19:26 device -> ../../../0003:1294:1320.0003
-r--r--r-- 1 root root 4096 May  7 19:26 max_brightness
drwxr-xr-x 2 root root    0 May  7 19:26 power
lrwxrwxrwx 1 root root    0 May  7 19:26 subsystem -> ../../../../../../../../../../../class/leds
-rw-r--r-- 1 root root 4096 May  7 19:26 trigger
-rw-r--r-- 1 root root 4096 May  6 19:39 uevent

Dans le cas de notre gadget la luminosité maximale est de 1, il est possible de positionner et de relire la luminosité. Les LED sur la carte du Raspberry ont un max_brightness à 255.

pi@raspberrypi:~ $ cat /sys/class/leds/riso_kagaku0\:green/max_brightness 
1
pi@raspberrypi:~ $ cat /sys/class/leds/led0/max_brightness 
255

pi@raspberrypi:~ $ cat /sys/class/leds/riso_kagaku0\:green/brightness 
0
pi@raspberrypi:~ $ echo 1 | sudo tee /sys/class/leds/riso_kagaku0\:green/brightness
1
pi@raspberrypi:~ $ cat /sys/class/leds/riso_kagaku0\:green/brightness                       
1

Nous avons allumé la LED verte (‘green’), visiblement il y a un petit soucis (et pas uniquement lié à mon daltonisme)… Le bleu et le vert sont inversés:

En fait le problème de ces gadgets est qu’il existe de nombreuses contrefaçons, pardon, de nombreux modèles ressemblants. D’ailleurs dans le code du driver, on trouve les lignes suivantes qui sont intéressantes:

static bool riso_kagaku_switch_green_blue;
module_param(riso_kagaku_switch_green_blue, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(riso_kagaku_switch_green_blue,
"switch green and blue RGB component for Riso Kagaku devices");
   [.../...]
	if (riso_kagaku_switch_green_blue)
		return RISO_KAGAKU_IX(r, b, g);
	else
		return RISO_KAGAKU_IX(r, g, b);

Ce paramètre est visible par la commande ‘modinfo’:

pi@raspberrypi:~ $ modinfo hid-led 
filename:       /lib/modules/4.14.79-v7+/kernel/drivers/hid/hid-led.ko
description:    Simple USB RGB LED driver
author:         Heiner Kallweit 
license:        GPL
srcversion:     BB1E27E615F4DDF35EBB58E
alias:          hid:b0003g*v000004D8p0000F372
alias:          hid:b0003g*v00000FC5p0000B080
alias:          hid:b0003g*v000027B8p000001ED
alias:          hid:b0003g*v00001D34p0000000A
alias:          hid:b0003g*v00001D34p00000004
alias:          hid:b0003g*v00001294p00001320
depends:        
intree:         Y
name:           hid_led
vermagic:       4.14.79-v7+ SMP mod_unload modversions ARMv7 p2v8 
parm:           riso_kagaku_switch_green_blue:switch green and blue RGB component for Riso Kagaku devices (bool)

Nous pouvons consulter et modifier la valeur de ce paramètre pour vérifier que notre gadget affiche la bonne couleur.

pi@raspberrypi:~ $ cat /sys/module/hid_led/parameters/riso_kagaku_switch_green_blue         
N
pi@raspberrypi:~ $ echo Y | sudo tee /sys/module/hid_led/parameters/riso_kagaku_switch_green_blue
Y
pi@raspberrypi:~ $ cat /sys/module/hid_led/parameters/riso_kagaku_switch_green_blue              
Y

pi@raspberrypi:~ $ echo 1  | sudo tee /sys/class/leds/riso_kagaku0\:green/brightness
1
pi@raspberrypi:~ $ echo 0  | sudo tee /sys/class/leds/riso_kagaku0\:green/brightness 
0
pi@raspberrypi:~ $ echo 1  | sudo tee /sys/class/leds/riso_kagaku0\:blue/brightness  
1

Le problème c’est qu’à chaque redémarrage du Rasperry les couleurs vont être inversées, ‘hid_led’ étant un module kernel comme un autre il est possible de fixer ses paramètres de la même manière:

pi@raspberrypi:~ $ cat << EOF | sudo tee /etc/modprobe.d/hid_led.conf
options hid_led riso_kagaku_switch_green_blue=Y
EOF
pi@raspberrypi:~ $ sudo rmmod hid_led
pi@raspberrypi:~ $ sudo modprobe hid_led
pi@raspberrypi:~ $ cat /sys/module/hid_led/parameters/riso_kagaku_switch_green_blue
Y
pi@raspberrypi:~ $ echo 1  | sudo tee /sys/class/leds/riso_kagaku0\:green/brightness

Un petit 'goodie' au passage, une commande pour afficher la valeur courante des 3 couleurs:

pi@raspberrypi:~ $ for c in red green blue ; do echo -n "$c: " ; cat /sys/class/leds/riso_kagaku0\:$c/brightness; done
red: 0
green: 0
blue: 1

Vous avez certainement remarqué un fichier appelé 'trigger' dans le répertoire de chacune des LED, il permet de faire gérer la LED automatiquement par le système en fonction d'un déclencheur. Les divers déclencheurs sont listés ci-dessous. Celui entre crochets est le déclencheur actif (ici 'none' c'est à dire aucun):

pi@raspberrypi:~ $ cat /sys/class/leds/riso_kagaku0\:red/trigger
[none] 
rc-feedback 
kbd-scrolllock kbd-numlock kbd-capslock kbd-kanalock kbd-shiftlock kbd-altgrlock kbd-ctrllock kbd-altlock kbd-shiftllock kbd-shiftrlock kbd-ctrlllock kbd-ctrlrlock
timer oneshot heartbeat 
backlight 
gpio 
cpu cpu0 cpu1 cpu2 cpu3 
default-on 
input 
panic 
mmc0 
rfkill-any

Les déclencheurs sont les suivants

  • rc-feedback: l'état du récepteur de télécommande infrarouge si le Raspberry en est équipé (cas des media-centers par exemple)
  • kbd: l'état du clavier
  • timer: faire clignoter la LED
  • oneshot: allumer la LED un temps donné
  • heartbeat: faire clignoter la LED comme un battement de coeurs
  • cpu: activité des CPU
  • panic: en cas de kernel panic
  • mmc0: activité de la carte mémoire du Raspberry Pi
  • rfkill-any: mode avion

La sélection d'un déclencheur peut faire apparaître de nouveaux fichiers dans le répertoire de la LED concernée, c'est le cas du déclencheur 'timer' par exemple, deux nouveaux fichiers 'delay_off' et 'delay_on' permettent de spécifier les temps d'allumage et d'extinction en millisecondes:

pi@raspberrypi:~ $ echo none | sudo tee /sys/class/leds/riso_kagaku0\:red/trigger     
none
pi@raspberrypi:~ $ ls -l /sys/class/leds/riso_kagaku0\:red/                      
total 0
-rw-r--r-- 1 root root 4096 May  8 14:09 brightness
lrwxrwxrwx 1 root root    0 May  8 14:09 device -> ../../../0003:1294:1320.0005
-r--r--r-- 1 root root 4096 May  8 14:09 max_brightness
drwxr-xr-x 2 root root    0 May  8 14:09 power
lrwxrwxrwx 1 root root    0 May  8 14:09 subsystem -> ../../../../../../../../../../../class/leds
-rw-r--r-- 1 root root 4096 May  8 14:11 trigger
-rw-r--r-- 1 root root 4096 May  8 14:09 uevent
pi@raspberrypi:~ $ echo timer | sudo tee /sys/class/leds/riso_kagaku0\:red/trigger    
timer
pi@raspberrypi:~ $ ls -l /sys/class/leds/riso_kagaku0\:red/                       
total 0
-rw-r--r-- 1 root root 4096 May  8 14:09 brightness
-rw-r--r-- 1 root root 4096 May  8 14:11 delay_off
-rw-r--r-- 1 root root 4096 May  8 14:11 delay_on
lrwxrwxrwx 1 root root    0 May  8 14:09 device -> ../../../0003:1294:1320.0005
-r--r--r-- 1 root root 4096 May  8 14:09 max_brightness
drwxr-xr-x 2 root root    0 May  8 14:09 power
lrwxrwxrwx 1 root root    0 May  8 14:09 subsystem -> ../../../../../../../../../../../class/leds
-rw-r--r-- 1 root root 4096 May  8 14:11 trigger
-rw-r--r-- 1 root root 4096 May  8 14:09 uevent
pi@raspberrypi:~ $ cat /sys/class/leds/riso_kagaku0\:red/delay_on
500
pi@raspberrypi:~ $ cat /sys/class/leds/riso_kagaku0\:red/delay_off
500
pi@raspberrypi:~ $ echo 100 | sudo tee /sys/class/leds/riso_kagaku0\:red/delay_on      
100

Dans le cas du déclencheur 'heartbeat' il est possible d'inverser le battement de coeur (deux extinctions rapides au lieu de deux allumages rapides):

pi@raspberrypi:~ $ echo heartbeat | sudo tee /sys/class/leds/riso_kagaku0\:red/trigger    
heartbeat
pi@raspberrypi:~ $ ls -l /sys/class/leds/riso_kagaku0\:red/                           
total 0
-rw-r--r-- 1 root root 4096 May  8 14:09 brightness
lrwxrwxrwx 1 root root    0 May  8 14:09 device -> ../../../0003:1294:1320.0005
-rw-r--r-- 1 root root 4096 May  8 14:22 invert
-r--r--r-- 1 root root 4096 May  8 14:09 max_brightness
drwxr-xr-x 2 root root    0 May  8 14:09 power
lrwxrwxrwx 1 root root    0 May  8 14:09 subsystem -> ../../../../../../../../../../../class/leds
-rw-r--r-- 1 root root 4096 May  8 14:22 trigger
-rw-r--r-- 1 root root 4096 May  8 14:09 uevent
pi@raspberrypi:~ $ cat /sys/class/leds/riso_kagaku0\:red/invert
0
pi@raspberrypi:~ $ echo 1 | sudo tee /sys/class/leds/riso_kagaku0\:red/invert
1

Vous pouvez expérimenter le déclencheur 'oneshot':

pi@raspberrypi:~ $ ls -l /sys/class/leds/riso_kagaku0\:red/                         
total 0
-rw-r--r-- 1 root root 4096 May  8 14:09 brightness
-rw-r--r-- 1 root root 4096 May  8 14:25 delay_off
-rw-r--r-- 1 root root 4096 May  8 14:25 delay_on
lrwxrwxrwx 1 root root    0 May  8 14:09 device -> ../../../0003:1294:1320.0005
-rw-r--r-- 1 root root 4096 May  8 14:25 invert
-r--r--r-- 1 root root 4096 May  8 14:09 max_brightness
drwxr-xr-x 2 root root    0 May  8 14:09 power
--w------- 1 root root 4096 May  8 14:25 shot
lrwxrwxrwx 1 root root    0 May  8 14:09 subsystem -> ../../../../../../../../../../../class/leds
-rw-r--r-- 1 root root 4096 May  8 14:25 trigger
-rw-r--r-- 1 root root 4096 May  8 14:09 uevent
pi@raspberrypi:~ $ cat /sys/class/leds/riso_kagaku0\:red/delay_off        
100
pi@raspberrypi:~ $ cat /sys/class/leds/riso_kagaku0\:red/delay_on
100
pi@raspberrypi:~ $ echo 1 | sudo tee /sys/class/leds/riso_kagaku0\:red/shot
1

Il existe de nombreux autres gadgets similaires... A vous de vous amuser avec.

Laisser un commentaire

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

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.