realisations:keyboards:mpcpad

MPC Pad

11/2019 Ce pad a pour vocation à remplacer ma télécommande infrarouge de XBox du garage reliée à Popeye car le driver noyau ne compile plus depuis un bon moment :-(.

J'ai besoin de 3 touches pour piloter la musique : play/pause, next et up. A l'aide d'un Pro Micro ATmega32u4, j'ai câblé 3 switchs, imprimé en 3D un petit boitier et des keycaps avec les symboles que je voulais.

Coté firmware, j'ai de nouveau utilisé qmk pour envoyer les touches F13, F14 et F15. En configurant lirc, je pilote mpc, un client pour le lecteur de musique mpd.

Vue intérieur du MPC Pad
Agrandir
Vue intérieur du MPC Pad

Voici une photo des keycaps custom que j'ai fait : j'ai d'abord imprimé les “capuchons” verts et bleus puis j'ai utilisé un marqueur noir pour faire ressortir les symboles.

Keycaps imprimés en 3d avec up, play/pause et next
Agrandir
Keycaps imprimés en 3d avec up, play/pause et next

Les sources du firmware sont sur mon gitlab : https://gitlab.com/coliss86/mpcpad

En arrivant ici, le plus dur est fait, quoi que…

Pour commencer, il faut bien identifier le pad à sa connexion sur un linux pour lui assigner un nom /dev fixe.

Voici un exemple de log de connexion :

[ven. nov.  6 14:18:54 2020] usb 3-1.2: new full-speed USB device number 26 using xhci_hcd
[ven. nov.  6 14:18:54 2020] usb 3-1.2: New USB device found, idVendor=4b1d, idProduct=4321
[ven. nov.  6 14:18:54 2020] usb 3-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ven. nov.  6 14:18:54 2020] usb 3-1.2: Product: MPC control pad
[ven. nov.  6 14:18:54 2020] usb 3-1.2: Manufacturer: Coliss86
[ven. nov.  6 14:18:54 2020] usb 3-1.2: SerialNumber: 0
[ven. nov.  6 14:18:54 2020] input: Coliss86 MPC control pad as /devices/pci0000:00/0000:00:14.0/usb3/3-1/3-1.2/3-1.2:1.0/0003:4B1D:4321.0012/input/input40

Règle udev pour fixer le nom de chemin du device /dev/mpc_pad

/etc/udev/rules.d/90-usb-devices.rules
ATTRS{idVendor}=="4b1d", ATTRS{idProduct}=="4321", KERNEL=="event*", SYMLINK="mpc_pad"

Recharger la configuration de udev :

sudo udevadm control --reload-rules

Déconnecter et reconnecter le macro-pad. Un lien symbolique /dev/mpc_pad est créé pointant vers le device /dev/input/eventXX.

C'est maintenant où ça devient moins drôle : la configuration de lirc. Si tout marche du premier coup, c'est top, sinon, le débug est pénible.

Commencer à arrêter et désactiver les services lirc inutilisés :

$ sudo systemctl stop lircmd.service lircd-uinput.service
$ sudo systemctl disable lircmd.service lircd-uinput.service

Voici un exemple de fichier de configuration de lircd :

/etc/lirc/lirc_options.conf
[lircd]
nodaemon        = False
driver          = devinput
device          = /dev/mpc_pad
output          = /var/run/lirc/lircd
pidfile         = /var/run/lirc/lircd.pid
plugindir       = /usr/lib/x86_64-linux-gnu/lirc/plugins
permission      = 666
allow-simulate  = No
repeat-max      = 600
 
[lircmd]
uinput          = False
nodaemon        = False

Ce macro pad possède 3 touches qui envoient F13, F14 et F15, voici la configuration du client irexec : à chaque appui, une log sera écrite dans les logs, ça permet de vérifier rapidement si la chaîne est bonne :

/etc/lirc/irexec.lircrc
begin
    prog   = irexec
    button = KEY_F13
    config = echo "KEY_F13"
end
 
begin
    prog   = irexec
    button = KEY_F14
    config = echo "KEY_F14"
end
 
begin
    prog   = irexec
    button = KEY_F15
    config = echo "KEY_F15"
end

Relancer le service lircd :

sudo systemctl restart lircd

Puis relancer le service irexec et non les 2 en même temps, irexec démarre avant que lircd ait pu ouvrir la socket /var/run/lirc/lircd et ne réagit pas :

sudo systemctl restart irexec

Consulter les logs de irexec :

journalctl -f  /usr/bin/irexec

Appuyer sur les touches du macro pad, les logs doivent s'enrichir :

-- Logs begin at Tue 2019-07-16 23:15:53 CEST. --
nov. 06 14:05:57 olive irexec[12967]: KEY_F13
nov. 06 14:05:57 olive irexec[12967]: KEY_F14
nov. 06 14:05:58 olive irexec[12967]: KEY_F15

Reste à changer les commandes pour mpc :

/etc/lirc/irexec.lircrc
begin
    prog   = irexec
    button = KEY_F13
    config = mpc next
end
 
begin
    prog   = irexec
    button = KEY_F14
    config = mpc toggle
end

Si rien ne se passe, voici comment débugger et vérifier que la bonne réception des événements. Au préalable, il faut stopper lircd et irexec.

Vérifier que le macro pad est reconnu en lançant lsinput :

lsinput
/dev/input/event0
   bustype : BUS_USB
   vendor  : 0x4b1d
   product : 0x4321
   version : 273
   name    : "Coliss86 MPC control pad"
   phys    : "usb-0000:00:14.0-1/input0"
   uniq    : "0"
   bits ev : (null) (null) (null) (null) (null)
[...]

Ici, le macro pad est reconnu sous /dev/input/event0. Cette valeur peut varier d'un boot à l'autre.

Ensuite, lancer l'utilitaire mode2 : il se branche directement sur le device et affiche les signaux reçus.

sudo mode2 -d /dev/mpc_pad -H devinput
Using driver devinput on device /dev/mpc_pad
Trying device: /dev/mpc_pad
Using device: /dev/mpc_pad
Running as regular user pad
<appui sur la touche F13>
code: 0x29a5a65f0000000035260c0000000000040004006a000700
code: 0x29a5a65f0000000035260c00000000000100b90001000000
code: 0x29a5a65f0000000035260c00000000000000000000000000
code: 0x29a5a65f00000000671a0e0000000000040004006a000700
code: 0x29a5a65f00000000671a0e00000000000100b90000000000
code: 0x29a5a65f00000000671a0e00000000000000000000000000

Le macro pad est bien lu, l'étape suivante consiste à relancer lircd, exécuter irw qui affiche les signaux interprétés par lircd et appuyer sur toutes les touches du macro pad pour vérifier la bonne reconnaissance :

irw
00000000800100b7 00 KEY_F13 devinput
00000000800100b8 00 KEY_F14 devinput
00000000800100b9 00 KEY_F15 devinput

Finalement vérifier le fichier de configuration /etc/lirc/irexec.lircrc de irexec à partir des noms de touches donnés par irw ci-dessus.