.:  Home  :. .:  Productions  :. .:  Misc  :.
 

Pédale Vite

Pédalier d’effets DIY pour guitare

 

Project main page / page principale du projet : [English] [Français]

Historique

Les paragraphes qui suivent retracent les idées, choix techniques et aléas qui ont parsemé l’élaboration de Pédale Vite, en particulier dans sa première version, depuis début 2016.

Le cœur du pédalier
----------

J’ai choisi d’architecturer le pédalier autour d’un Raspberry Pi 3, qui vient tout juste de sortir à l’heure où j’écris ces lignes. La machine de la taille d’une carte à puce est bon marché, US$ 35, importée par Farnell pour 38 € TTC ou en magasin d’électronique pour des prix équivalents.

 

Le processeur, un A53 (architecture ARMv8-A) cadencé à 1,2 GHz, devrait être suffisamment puissant pour traiter le son. J’ai maintenant un tout petit peu d’exprérience en programmation ARM avec les instructions vectorisées Neon, et je pense pouvoir m’en tirer sans trop de difficulté.

La RAM (1 Go) a l’air suffisante pour le système, le programme et toutes ses données.

Le Pi embarque un lecteur de cartes Micro-SD et dispose donc d’une mémoire de masse conséquente et modifable. On trouve facilement des cartes 8 ou 16 Go pour une bouchée de pain.

Le port GPIO permet de l’interfacer au monde extérieur (ou plutôt intérieur : pédales, LED…) Les ports USB 2 permettent d’y brancher une carte son de bonne qualité à faible latence. Il y a en plus un port Ethernet et de quoi brancher un écran, la maintenance devrait être simple.

La consommation du Pi 3 seul est relativement faible, 4 W. Il s’alimente par prise micro-USB, mais on peut aussi brancher directement du 5 V sur une des broches du GPIO. Une alimentation de 2 A est recommandée pour assurer celle des périphériques USB. Pour l’instant je ne vais pas m’embêter et prendre un transfo standard de 2,5 A.

Toujours par simplicité, je vais utiliser le système « par défaut », Raspbian, une disrtibution Linux basée sur Debian (Jessie au moment de l’écriture de ces lignes) et spécifiquement développée pour le Pi.

J’ai un peu hésité entre le Pi 3 et l’Odroid C2. Ce dernier est à la fois très similaire et nettement plus puissant que le Pi. Il a cependant le désavantage d’être moins bien distribué et d’avoir une communauté de bidouilleuses beaucoup plus réduite. Les Linux hors Android ont l’air supportés, mais un peu expérimentalement. Je crains donc de rencontrer plus d’obstacles en cours de route. Par contre, les deux ont des hardware très proches, jusqu’à la géométrie de la carte, ce qui rend envisageable la substitution de l’un par l’autre (différences notables : pas de SPI hardware, mais ADC intégré). Ça pourra faire partie d’une extension au projet. Addendum 1 : il semble en fait que le C2 soit bloqué à 1,5 GHz maxi, ce qui en réduit l’intérêt… Addendum 2 : depuis, le N2 est sorti et semble présenter une évolution particulièrement convaincante en terme de puissance. J’en ai acquis un pour faire des tests. À suivre.

Le son
----------

Il me faut des convertisseurs numérique-analogique dans les deux sens. Une carte son, quoi. Elle doit avoir les caractéristiques suivantes :

Le problème de la qualité de l’entrée est crucial. Pour distordre le son, on procède habituellement en l’amplifiant de manière démesurée ce qui le fait saturer. Le gain de l’amplification est très important, on peut monter facilement à +60 dB et au-delà. Si le signal de la guitare est entâché de bruit de fond, le bruit va être amplifié aussi. Quand la guitare joue, ce n’est pas un problème parce qu’elle masque le bruit. Mais quand elle ne joue pas, ou qu’on arrive en fin d’une note tenue longtemps, le volume du bruit avoisine ou dépasse celui de la guitare, et c’est lui qu’on entend hyper-amplifié.

Il est donc important que le DAC de la carte ainsi que l’électronique en amont soient aussi silencieuses que possible. Une fois le son numérisé, on peut toujours ajouter un noise gate ou débruiter le son avant distorsion, mais ce sont des solutions paliative qui seront insuffisantes en cas d’électronique de piètre qualité.

Je voudrais aussi faire tenir la carte dans le pédalier, pour que celui-ci soit fait d’un bloc. Il est toutefois possible de la mettre à l’extérieur, c’est d’ailleurs plus simple en terme de réalisation. Mais pratiquement et esthétiquement, c’est quand même moins bon.

Pour l’instant j’ai fixé mon choix sur une PreSonus Audiobox USB. D’après ce que je peux lire de ses caractéristiques et des forums audio/linux, elle est tout à fait adaptée et donne ample satisfaction. En plus elle est peu onéreuse (autour de 85 € TTC). On peut descendre les buffers très bas, à 64 samples, ce qui doit donner une latence totale entrée-sortie de l’ordre de quelques millisecondes en 44,1 kHz. Reste à voir ce qu’elle vaut vraiment en terme de bruit de fond, qui est un critère spécifique difficile à évaluer sur papier. Je ne m’attends pas à un résultat aussi bon qu’avec ma Fireface UCX, ce n’est pas du tout la même gamme de prix. Je n’ai pas non plus trouvé de chiffre indiquant combien elle tire de courant sur l’USB. Elle devrait au moins passer seule, puisque j’ai lu que des personnes l’utilisaient avec le Pi.


Ce n’est peut-être pas la meilleure carte réunissant toutes les conditions énoncées, mais en l’absence de plus d’informations je n’ai pas envie de prendre trop de risques, compte tenu du prix de ce genre de matériel. Au moins je suis à peu près sûr que celle-ci va fonctionner.

Rien qu’avec cette carte et le Pi, je dois pouvoir commencer à tester la faisabilité du projet. Je passe commande pour faire mes premiers essais.

La pédale d’expression
----------

L’idée, c’est d’avoir une pédale wha-wha avec la possibilité de pouvoir l’introduire à n’importe quel point de la chaîne d’effets. Généralement je la mets avant la disto, et dans la plupart des utilisations je pourrais garder ma vieille Cry Baby en amont du pédalier. Cependant il est toujours amusant de placer des effets encore en amont (une réverb par exemple, pour donner un son hyper nuageux), ce qui m’impose de passer la wha dans le pédalier en numérique. La pédale n’a alors plus à être une wha, il ne s’agit plus que d’un bête contrôleur. On peut alors utiliser cette pédale pour contrôler au pied n’importe quel paramètre d’un effet.

Comme la plupart de ses sœurs, la carte audio que j’ai choisie dispose d’une entrée MIDI. J’ai donc pensé prendre une pédale contrôleur MIDI, mais les modèles que j’ai trouvés étaient hors de prix. C’est surprenant, j’ai peut-être mal cherché.

En tout cas je me suis rabattu sur les pédales d’expression, dites aussi pédales de volume. Dans leurs versions les plus simples, elles sont constituées d’un potar actionné au pied et directement branché à l’aide d’un ou deux jacks. Finalement je trouve cela mieux d’avoir un composant purement passif. Une pédale MIDI aurait soulevé un problème additionnel lié à son alimentation.

Du coup, il s’agit d’un appareil suffisamment simple pour que je pense le fabriquer intégralement. Cependant la robustesse de la pédale est un point clé. Les avis que j’ai pu récolter m’on dissuadé de construire le corps moi-même. Cela demande une mécanique parfaitement pensée, de l’outillage et des matériaux pas toujours faciles à travailler (métal épais). En général, on conseille sur les forums dédiés de sacrifier une Cry Baby d’occasion et d’installer sa propre électronique à la place. Au final, l’avantage DIY a l’air assez maigre.

J’ai donc opté pour une Yamaha FC-7 à 60 € TTC. Elle m’a l’air solide et dispose de bons retours. Le potar fait 50 kΩ. La prise est un jack stéréo (anneau = point variable).


Je note quand même que l’interrupteur de bypass sur la Cry Baby est un gros avantage pratique en faveur de cette solution. Il s’agit en fait de deux pédales en une, permettant d’activer ou de désactiver l’effet, le pied déjà ou encore posé sur la pédale. J’y reviendrai peut-être ultérieurement.

Voilà pour la pédale. Le hic, c’est que le Pi n’a pas d’entrée analogique. Il va donc falloir en bricoler une en ajoutant un ADC et en branchant la pédale dessus comme pont diviseur entre le +3,3 V et la masse. Rapide calcul de conso : P = U²/R, soit 0,2 mW. Ça gère.

Si on surveille un peu l’addition, on en est maintenant à moins de 200 € TTC de matos en comptant le Pi, la carte son et la pédale. Malheureusement, on peut difficilement descendre plus bas avec du neuf. Si on veut compresser le budget, il faut passer par l’occasion. Heureusement ce sont probablement les plus gros postes dans le budget qui ne va pas enfler démesurément. D’autre part chacun de ces appareils est réutilisable séparément, moyennant un démontage limité du pédalier pour deux d’entre eux.

Fonctionnement général
----------

Je pense que le pédalier peut fonctionner en deux modes qui peuvent être complémentaires  un mode programme, où une pédale active toute une chaîne d’effets et de paramètres, et un mode effet, où une pédale active ou désactive un effet fixe de la chaîne. Les deux modes peuvent être combinés, par exemple une zone du pédalier est affectée au mode programme, et l’autre au mode effet, la ligne de séparation étant choisie par la personne utilisatrice.

On pourra consacrer une pédale à l’accordeur. Pour faire simple, on prendra 3 LED qui indiqueront si la note jouée est trop basse, trop haute ou juste. En jouant avec l’intensité lumineuse des LED, on doit pouvoir donner une information plus précise.

J’imagine que dans un premier temps, je peux me contenter de faire un pédalier qu’on puisse utiliser de manière totalement autonome, mais qui demande une liaison informatique pour être programmé. Cette solution me paraît acceptable à court terme. En revanche il faudrait que l’interface du pédalier puisse rapidement évoluer pour permettre de le paramétrer sans recourir à un ordinateur. Il est indispensable pour le ou la musicienne de pouvoir créer et moduler ses sons sans avoir à s’encombrer de matériel informatique supplémentaire dans le local de répétition.

Il me faut donc prévoir dès à présent les éléments d’interface utilisateurs nécessaires : écran, boutons, etc. quitte à ne pas les utiliser immédiatement.

Le boîtier
----------

Je vais organiser le pédalier en deux rangées de six pédales — de simples interrupteurs. La surface sera légèrement inclinée de façon à faciliter l’accès du pied à la deuxième rangée. Le châssis doit être robuste, il doit pouvoir encaisser des coups de pieds sans broncher, et même peut-être supporter le poids d’une personne. La surface sera donc métallique, probablement avec une ossature bois parce que c’est quand même plus simple à travailler. Il sera suffisamment grand pour accueillir tous les éléments, notamment :

L’épaisseur de la carte son choisie est conséquente et va se répercuter sur la hauteur du pédalier. On essaiera de la glisser au fond, là où il y a le plus d’espace vertical.

Il faudra prévoir un espacement entre les pédales suffisant pour être confortable et ne pas nécessiter de visée très précise, tout en gardant le pédalier compact et transportable dans un sac à dos. À vue de nez, 8 cm d’espacement horizontal et 12 cm en profondeur forment un compromis honnête.

Il me faut des éléments d’interface, à savoir :

Les connecteurs, idéalement placés sur le panneau arrière :

Mais il serait encore plus pratique de laisser la façade entière du Pi avec ses ports USB, ce qui permettrait de brancher dessus clavier et souris et de pouvoir se passer d’un ordinateur externe et d’une config réseau. Cependant, pour que la manipulation soit effective, il faudrait aussi pouvoir brancher un écran. Malheureusement la prise HDMI est située sur un autre côté. On essaiera donc soit de placer le Pi dans un angle de façon à récupérer les deux côtés utiles, soit de câbler une rallonge depuis le port HDMI, en en profitant pour le convertir en DVI, quand même plus pratique à mon avis.

Partie logicielle
----------

Comme évoqué précédemment, le système d’exploitation est la Raspbian de base. Je verrai avec les tests s’il est nécessaire ou utile de patcher le noyau pour qu’il devienne real time.

Je verrai aussi quelles modifications apporter (services à supprimer ou à remplacer) pour accélérer le démarrage. Le pédalier doit être fonctionnel aussi rapidement que possible après l’allumage.

Dans la même veine, je prévoirai un mécanisme d’extinction à chaud. Il existe des solutions pour forcer le système en lecture seule après le démarrage, ce qui devrait permettre de débrancher l’appareil en cours de fonctionnement sans risquer de corrompre la mémoire de masse. Au pire j’ajouterai un bouton de pré-extinction, mais ça ne correspond pas à la logique d’utilisation de ce genre de matériel.

En termes de possibilités offerte, c’est encore vague dans ma tête. Il y a tellement de choses possibles et intéressantes à faire ! Je note plein d’idées mais je commencerai par quelque chose de simple. J’ai déjà commencé à écrire quelques scénarios et à tracer des diagrammes fonctionnels de l’interface utilisateur.

Le logiciel proprement dit sera codé en C++. J’utiliserai Jack2 pour m’interfacer sur la carte son, au moins dans un premier temps. J’attaquerai directement les drivers ALSA un peu plus tard. L’interfaçage avec le GPIO du Pi sera fait en principe avec la bibliothèque WiringPi, ou sera attaqué directement en cas de lacune de la lib. Le GPIO a l’air bien documenté malgré de nombreuses coquilles dans la doc constructeur. Ce sera peut-être nécessaire pour faire de la PWM « semi-hard » par DMA afin de faire varier la luminance des diodes sans bouffer trop de CPU.

Je vais prendre une architecture sous forme hôte/plug-ins pour le traitement audio, ce qui va me donner de la souplesse et de l’évolutivité. Je verrai à quel point il est nécessaire de recourir au multi-threading pour le traitement, sachant que ce genre d’application « en chaîne » s’y prête difficilement ce qui est fort dommage. Peut-être en pipe-linant le signal par tranches de 16 samples ? On verra bien. J’utiliserai un système de messages lock-free pour la communication asynchrone entre threads (GPIO / audio / contrôle / tâches de fond).

Je vais m’arranger pour que le programme soit facilement testable sur un PC standard sans avoir besoin de tout retransférer sur le Pi à chaque modification.

Difficile d’en dire beaucoup plus à ce point, il faudra commencer par faire des tests et avoir le hardware au point.

Installation

Les principaux composants reçus, il est temps de passer au montage et à l’installation de la bestiole.

Matériel :

Préparation du système
----------

Je télécharge NOOBS qui contient Raspbian 1.9.0, datée du 2016-03-18. Comme indiqué sur la doc, il va falloir transférer NOOBS sur la carte SD.

J’ai donc récupéré une carte Micro-SD de 16 Go qui est censé être lisible par le Pi. Elle est livrée avec son adaptateur au format SD classique. Je suis les instructions d’installation.

Tout d’abord formater la carte :

Transférer ensuite le contenu de l’archive de NOOBS sur la carte sans créer de répertoire intermédiaire. Un fichier comme INSTRUCTIONS-README.txt par exemple doit se trouver directement à la racine.

Le système est maintenant prêt à être installé. Retirer la carte Micro-SD de la machine et l’insérer dans le lecteur du Pi. Brancher clavier, souris, écran et alimentation. On peut maintenant booter sur le Pi.

Démarrage et configuration de base
----------

On allume le Pi, l’écran de NOOBS arrive. Choisir l’installation de Raspbian. Attendre que la copie soit finie, puis redémarrer.

On est maintenant sous Raspbian. Commençons par faire quelques réglages. On va avoir besoin d’activer les interfaces SPI et I2C pour communiquer avec les différents composants nécessaires. Par ailleurs il vaut mieux régler le clavier et la langue du système, selon le matériel que l’on a. Aller dans Menu > Preferences > Raspberry Pi configuration :

Valider puis redémarrer. Vérifier dans les préférences que les choix ont bien été pris en compte.

Petite note : sur un ordinateur classique connecté au réseau régulièrement ou contenant des données un peu sensibles, j’aurais pris des précautions de sécurité (désactivation du login automatique, changement du mot de passe et des privilèges, etc.), mais là il me faut quelque chose de simple, je garde donc la configuration d’installation. Je désactiverai sûrement des services type WiFi ou Bluetooth un peu plus tard quand je serai dans un contexte d’utilisation, pour éviter que le pédalier ne soit piratable à distance.

Installation de l’Audiobox USB sur le Raspberry Pi 3

Comme je m’y attendais un peu, installer et configurer la carte son n’a pas été très facile. Les informations que j’ai pu glaner sur les forums ou divers sites dédiés sont souvent incomplètes, parfois contradictoires, et généralement inadaptées à la version du système en ma possession.

En gros, la reconnaissance de l’Audiobox USB et son installation se sont faites sans aucun problème. Il n’y a rien d’autre à faire que de brancher la carte. C’est un point plutôt rassurant.

Par contre, il a été beaucoup plus difficile de demander au système d’utiliser la carte USB plutôt que le périphérique audio interne. Je n’ai même pas réussi à faire le changement complètement, j’ai simplement pu trouver un compromis acceptable. Je suppose que des réglages un peu infantilisants ont été faits dans Raspbian de façon à ce que les personnes qui utilisent le Pi comme media center retrouvent toujours le son sur le port HDMI, quoi qu’elles connectent aux ports USB. Comme je suis loin d’être un expert en configuration Linux et que je n’ai pas envie d’y passer des heures, je me suis arrêté à ce dont j’avais strictement besoin.

Voici les principales sources d’informations dont je me suis servi :

Je ne vous donne pas tous les tatonnements effectués pour arriver aux résultats suivants, juste les étapes essentielles. On commence par brancher la carte. Évidemment la carte n’est pas listée dans les préférences audio, ce serait trop facile… On ouvre donc un terminal et on tape :

aplay -l

La carte son USB doit y être listée. Ensuite on édite :

sudo nano /lib/modprobe.d/aliases.conf

Commenter la ligne qui met en retrait les cartes USB :

#options snd-usb-audio index=-2

Puis :

sudo nano /etc/modprobe.d/alsa-base.conf

En principe le fichier n’existe pas et est créé pour l’occasion. Le remplir avec le paramétrage suivant :

# This sets the index value of the cards but doesn't reorder.
options snd_usb_audio index=0
options snd_bcm2835 index=1
# Does the reordering.
options snd slots=snd-usb-audio,snd-bcm2835

Je ne suis pas sûr de comprendre le mélange de tirets et d’underscore, je ne fais que recopier comme un singe. Redémarrer pour que les paramètres soient pris en compte. Rouvrir le terminal et taper :

cat /proc/asound/modules

La liste doit montrer l’USB audio en position 0. Récupérer un fichier wav quelque part (via une clé USB par exemple). Brancher la sortie de la carte son, puis :

aplay -v fichier.wav

Le son ne joue probablement pas encore au bon endroit. Si maintenant on précise :

aplay -v -D plughw:0,0 fichier.wav

Ça doit jouer correctement, sans craquement. On va essayer de faire mieux pour ne plus avoir à préciser le device :

aplay -L

Chercher le nom du device USB, situé après Card=. Puis :

sudo cp ~/.asoundrc /etc/asound.conf

Remplacer le contenu par les lignes suivantes et changer les <number of your card> avec le nom du device USB :

pcm.!default plughw:<number of your card>
ctl.!default plughw:<number of your card>

On redémarre encore.

Maintenant si on édite encore ~/.asoundrc, on remarque que notre modification a été remplacée ou corrigée automatiquement durant le redémarrage. L’interface bcm2835 est de nouveau présente. Ça ne marche toujours pas, et c’est là que je m’arrête. Je n’ai pas réussi à trouver ce qui corrige ~/.asoundrc dans notre dos. Si quelqu’un a une solution pour ça, je suis preneur. De toute façon on a notre device USB en position 0, et on peut y faire référence explicitement. Ça nous suffira.

Si malgré tout on veut forcer l’audio USB au niveau système, on peut toujours désactiver complètement le bcm2835. Pour cela, éditer /boot/config.txt et commenter la ligne suivante :

#dtparam=audio=on

Premiers essais

Bout de programme utilisant Jack
----------

Maintenant qu’on sait que la carte marche, on va pouvoir tester son comportement avec Jack, et plus particulièrement Jack2 qui est livré correctement patché avec Raspbian. Commençons par installer les bibliothèques de développement. On se connecte au net, on s’assure que la connection marche (en lançant le navigateur par exemple), puis dans un terminal :

sudo apt-get install libjack-jackd2-dev

On commence par lancer le service Jack pour la session:

jackd -P70 -p16 -t2000 -dalsa -p64 -n3 -r44100 -s &

-p64 c’est la taille des buffers en samples, et -n3 le nombre de ces buffers. Les paramètres sont à varier en fonction des résultats obtenus (voir la suite). Chez moi ça passe bien comme ça.

J’ai écrit un programme minimaliste qui copie l’entrée audio sur la sortie, très inspiré d’un des programmes d’exemple de Jack, test-jack-01.cpp. On le compile, on lance Jack et on le teste :

g++ --std=c++11 -I. -Wall `pkg-config --cflags --libs jack` test-jack-01.cpp
./a.out

Ça marche ! Le son ressort de la carte sans craquement, le système n’a pas l’air peiner à fournir des buffers de 64 samples. La qualité de son m’a l’air correcte. Les entrées sont très sensibles, il faut mettre leur gain au minimum si on veut être sûr de ne pas saturer l’ADC avec la guitare.

Deuxième essai en modifiant très légèrement le code du traitement audio. On ajoute un gain de 1000 (+60 dB) suivi d’une saturation par tanh(). Ça devrait nous donner une distorsion très simple. On recompile et on relance : le son a l’air très correct. Il y a quand même un souffle distinct, mais j’ai l’impression qu’il tient en partie de la médiocre qualité de ma câblerie d’essai. C’est un point que j’investiguerai plus tard.

Et la latence dans tout ça ?

Trois buffers de 64 samples, ça fait en principe 192 samples de latence, soit 4,35 ms à 44100 kHz. Dans les faits ça va être un peu plus parce que les buffers ne concernent que sur la partie code client. Il faut rajouter la latence de l’électronique, de l’interface, du système…

Il existe un petit utilitaire, jack_delay, qui permet de mesurer le roundtrip, c’est-à-dire la durée d’un cycle de sortie de d’entrée d’un son. Pour l’installer :

tar xjf jack_delay-0.4.0.tar.bz2
cd jack_delay
nano Makefile

Commenter la ligne qui fait planter GCC chez moi :

#CPPFLAGS += -march=native

Sauver et :

make

On relie la sortie gauche à l’entrée gauche de la carte son à l’aide d’un câble, puis on lance le test.

sudo ./jack_delay -O system:playback_1 -I system:capture_1

J’obtiens 13,37 ms de latence ce qui est plus élevé que mes premières estimations… Ça reste toutefois très acceptable : la durée correspond à celle du son parcourant 4,5 m.

Par curiosité, je relance le test avec l’option -E et j’obtiens 7,57 ms de latence hors application. La différence entre les deux mesures fait exactement 256 samples. J’avais pensé à tort que 3 buffers donnaient la latence utilisateur totale, mais il faut manifestement rajouter un buffer dans la somme. Après investigation, c’est effectivement le cas sur les périphériques USB pour lesquels ALSA ajoute implicitement soit un buffer, soit 24 ms — le plus petit des deux.

Côté électronique
----------

La carte son marchant correctement, on peut continuer. Je vais faire des montages de test sur plaque d’expérimentation sans soudure, ce qui me permettra d’évaluer chaque type de circuit électronique, chaque fonctionnalité nécessaire et de cerner et résoudre toutes les difficultés techniques afférentes.

Ci-dessous, une vue d’ensemble de ma plaquette comprenant tous les montages de test à la fois :

 

C’est un peu bordélique ! À ce moment je n’avais que du fil rouge et noir sous la main. D’autre part j’avais oublié de prendre des fiches HE14 mâles du coup je me retrouve à devoir planter du fil dénudé dans les trous de la plaque, ce qui n’est ni propre ni pratique.

Je me suis fait un petit boîtier en carton avec un emballage de chocolat orange vif pour protéger le Pi. Il me laisse le connecteur GPIO accessible. Comme il me manquait de la matière, j’ai dû prendre les mesures au plus juste ce qui fait qu’il ferme mal. J’ai aussi oublié de laisser un trou pour les LED. Et puis j’aurais dû penser à perforer le carton sous les trous du PCB afin de laisser passer vis et entretoises lors du montage final. Il me reste une plaque de carton orange, un jour je referai peut-être le boîtier plus proprement, mais il y a peu de chance que ça arrive.

Interrupteur sous interruptions
----------

Je vais commencer par faire fonctionner des boutons. Dans le pédalier réel, ces boutons correspondront aux pédales et aux boutons de l’interface utilisateur. Ce sont des boutons momentanés de type « Off-(On) », c’est-à-dire qu’ils ont deux positions, une en coupe circuit et l’autre en contact. Les parenthèses indiquent que la position de contact n’est pas stable, elle revient automatiquement à une position de repos quand on relâche le bouton. Bref, ils fonctionnent comme un bouton de sonnette.

Le but de la manipulation suivante est de récupérer à tout moment dans le programme l’état des boutons, et de savoir quand ils changent de position.

Le Pi a une interface dédiée pour communiquer avec l’extérieur, le GPIO. On va donc connecter nos boutons à des broches du GPIO. Je ne vais pas réinventer la poudre, il existe de bonnes bibliothèques permettant d’accéder aux fonctions du GPIO. WiringPi est écrite en C et très simple d’utilisation. Commençons par l’installer :

git clone git://git.drogon.net/wiringPi
cd wiringPi
git pull origin
./build

Le GPIO est en réalité un périphérique intégré au SoC Broadcom qui compose l’essentiel du Pi. Il dispose de nombreuses entrées et sorties, mais seules quelques unes d’entre elles ont été connectées à des broches réelles du connecteur P1 dans le Pi. Du coup, il existe au moins deux systèmes de numérotation permettant d’identifier ces entrées/sorties :

Au cours des révisions du Pi, certains ports GPIO ont changé de broche, et le connecteur s’est agrandi de 26 à 40 broches. Il en résulte une grande confusion quant à l’identification des signaux. Des tables de correspondance figurent sur cette page. Pour ma part, j’utiliserai essentiellement la numérotation par broches physiques. Si je dois utiliser la numérotation interne, j’utiliserai « GPIO » comme préfixe. Le pédalier n’étant pas conçu pour marcher sur les premières versions du Pi, je pense que c’est la manière la plus simple de résoudre ce problème. De plus, WiringPi permet d’utiliser très naturellement cette numérotation.

Revenons-en aux interrupteurs. En faisant quelques tours sur le net, on se rend compte qu’il y a différentes approches. Parfois les gens connectent directement leur interrupteur entre une broche du GPIO et la masse, que ce soit tel quel ou en activant le pull-up interne du GPIO. Parfois ils connectent une simple résistance de pull-up liée au +3,3 V, et parfois encore il y a une seconde résistance côté broche.

Je vais utiliser cette dernière approche. En effet il est indispensable de brancher le bouton en pull-up, car l’entrée du GPIO est en haute impédance, et quand elle n’est connectée à rien, elle est considérée comme flottante, sans valeur déterminée. Le fait de connecter la broche au +3,3 V permet de lui donner un potentiel fixe. Quand l’interrupteur est pressé et que le contact est fait avec la masse, seul un faible courant passe au travers de la résistance de grande valeur (10 kΩ), ce qui évite surchauffe et consommation excessive.

Il se trouve que le GPIO a la possibilité de fournir lui-même ces résistances de pull-up (ou de pull-down) de 50 kΩ. Cependant j’ai trouvé plusieurs avis dissuadant de faire ainsi, la valeur de 50 kΩ étant jugée trop élevée en pratique, donnant des courants trop faibles et des interrupteurs trop sensibles aux parasites. Je ne sais pas à quel point ces source sont fiables, toujours est-il que j’ai pris la décision de monter mes propres résistances.

Comme il est possible de configurer tous les ports du GPIO indifféremment en entrée et en sortie, il existe un risque de provoquer un court-circuit fatal si la broche à laquelle l’interrupteur est connecté est configurée par mégarde en sortie et que l’interrupteur fait contact. J’ajouterai donc une seconde résistance de 1 kΩ côté broche afin de protéger le circuit dans de telles circonstances.

Le montage de test est le suivant. J’ai connecté un interrupteur à la broche 7 (GPIO 4).

 

Ça ne figure pas dans le montage, mais j’ai aussi enfilé des manchons en plastique autour des broches +5 V afin de les isoler. En effet le GPIO fonctionne en 3,3 V sans aucune protection. Rentrer en contact avec du 5 V le détruirait à coup sûr. Un accident est très vite arrivé, il suffit qu’un objet métallique se balade sur les broche. Il vaut donc mieux prendre toutes les précautions possibles. Les manchons sont de simples résidus de dénudage de fil électrique.

Petite note sur les diagrammes en passant. Ils sont dessinés avec le logiciel Fritzing qui semble très en vogue au sein de la clientelle micro-controleurs et nano-ordinateurs. Malheureusement il utilise la numérotation interne GPIO pour décrire les borches sur les schémas, ce qui me complique les connexions. En plus, sa manière de numéroter physiquement les broches n’est pas la même que celle des la documentation officielle du Pi…

Bref, j’ai créé un petit programme de test. Celui-ci place des callbacks sur les fronts montants et descendants de la broche 7. À chaque front détecté et validée par le GPIO, une interruption est générée, la valeur courante du bouton est lue et affichée. Le programme nécessite d’être exécuté en superviseur pour pouvoir accéder au GPIO.

g++ --std=c++11 -I. -Wall -lwiringPi test-io-01.cpp
sudo ./a.out

Ça marche, le programme répond quand on presse ou relâche l’interrupteur. Il répond trop bien, même, puisqu’un seul mouvement va déclancher jusqu’à trois événements à la file, et peut-être même plus. C’est ce qu’on appelle un rebond, lié au caractère elastique des contacts du bouton.

Élimination du rebond de l’interrupteur
----------

Il existe plusieurs manières d’éliminer les rebonds. L’une est électrique, en réalisant un filtre passe-bas par ajout d’un condensateur. L’autre est logicielle, en fixant un temps d’attente minimum entre deux impulsions. C’est cette dernière solution que je vais utiliser, plus simple à calibrer et à mettre en œuvre.

Ce programme, à compiler de la même façon que le précédent, semble donner des résultats fiables pour un temps de protection de 30 ms.

Notons que les temps de rebond diffèrent pour chaque interrupteur. J’ai utilisé un petit bouton très simple pour mes essais sur la plaque d’expérimentation, mais la situation sera sûrement différente avec les boutons au pied des pédales. Il faudra donc recalibrer le rebond avec le matériel final.

Allumage des LED
----------

J’ai besoin de quelques LED. Elles sont censées donner diverses informations utiles, comme la disponibilité du pédalier, si le signal sature en sortie, etc. Mais je compte aussi les utiliser pour l’accordeur, indiquant si le son et trop grave, juste ou trop aigu (rouge-vert-rouge).

Quels modèles de diodes ? Je dois faire mon choix en fonction de ces données :

Je pourrais m’affranchir de la plupart de ces contraintes avec un montage à transistor, mais bon j’ai la flemme et je veux garder les choses au plus simple pour l’instant. On dira que ce sera pour une version ultérieure.

Il faut donc que je prévoie des diodes fonctionnant quelque part entre 1,3 V et 2,7 V, et tirant peu de courant en fonctionnement nominal, de préférence sous les 2 mA. Par contre j’aimerais qu’elles soient quand même aussi brillantes que possible, pour qu’on puisse les voir en plein jour.

Je trouve donc des LED rouges à (1,6 V, 1 mA) donnant 3 mcd d’intensité lumineuse. Pour la verte, le meilleur modèle que je puisse trouver est à (1,9 V, 2 mA) donnant 2,3 mcd. Les deux diodes font 5 mm de diamètre. Je peux compenser le manque de luminosité de la verte en la poussant à 2,6 mA, intensité qu’elle devrait tenir sans broncher. La caractéristique du constructeur indique que la tension associée fait environ 1,925 V. Mais je ne suis plus dans le mode de fonctionnement garanti du GPIO. Si je constate au cours des essais que ça pose problème, je pourrai toujours pousser le drive des pads à 4 mA.

Je peux maintenant calculer les résistances nécessaires pour chaque type de diode. Sachant que Upad = ULED + R·ILED, on obtient Rrouge = 1,7 kΩ et Rverte = 528 Ω. J’arrondis par le bas (soyons fous) à 1,5 kΩ et 470 Ω. En terme de puissance résistive dissipée, on tourne autour de 1,5 mW et de 2,5 mW respectivement. Ce n’est pas terrible, mais il n’y a rien de catastrophique non plus. La consommation totale pour les trois diodes rampe sous les 14 mW.

Le montage de test est très simple, je connecte les LED aux broches 11 (GPIO 17), 13 (GPIO 27) et 15 (GPIO 22).

 

Le programme de test l’est tout autant, je fais cycler l’allumage de chaque LED par intervalle d’une seconde. Encore une fois, tout marche sans problème, je peux passer à la suite. Bien qu’ayant une faible consommation, les diodes se voient très correctement en intérieur à l’éclairage électrique. Elles sont quand même faiblardes en plein jour.

LED à luminosité variable
----------

Maintenant que j’arrive à allumer des LED, je vais essayer d’en faire varier l’intensité lumineuse, ce qui sera utile pour obtenir un meilleur retour avec l’accordeur. Cependant le GPIO ne dispose pas de sortie analogique, il n’est donc pas possible de moduler l’intensité électrique qui traverse les LED.

Il est toutefois possible d’utiliser des impulsions à largeur variable (Pulse Width Modulation, PWM). Cela consiste à produire un signal rectangulaire périodique très rapide, dont les durées des plateaux à 1 et à 0 permettent de moduler l’intensité lumineuse perçue. Le procédé rappelle un peu le concept de trame en imprimerie, mais opère ici dans le temps plutôt que dans l’espace.

Malheureusement, le GPIO du Pi ne possède qu’un port permettant de faire de la PWM en hardware. Il faut donc passer par une solution software. De son côté, WiringPi dispose de fonctionnalités permettant de faire de la PWM soft. L’inconvénient, c’est que cette modulation demande d’occuper (un peu) le CPU pour parvenir à ses fins. Si on peut éviter, c’est mieux.

Il existe heureusement une solution intermédiaire consistant à piloter les ports GPIO depuis le DMA (Direct Memory Access). Cette solution a l’avantage de fournir une bonne précision tout en étant minimaliste en terme d’occupation CPU. Elle est implémentée par diverses bibliothèques, comme RPIO en Python par exemple, ou Pi-Blaster.

Alors là j’ai un peu galéré. Les quelques bibliothèques que j’ai trouvées se ressemblent toutes puisqu’elles sont basée sur ServoBlaster. Cependant aucune ne marchait sur mon Pi 3, qui je le rappelle, est encore tout jeune. J’ai finalement mis la main sur le code original de ServoBlaster, mais à jour. Celui-ci marchait correctement, et j’ai fini par comprendre ce qui n’allait pas chez les autres :

Finalement je suis arrivé à un programme de test très brouillon, un patchwork consanguin issu des bibliothèques précitées. Il allume et éteint progressivement les 3 LED les unes après les autres. Ce test permet par ailleurs de constater que la luminosité perçue n’est pas proportionnelle à l’intensité lumineuse. Pour la compilation, c’est comme d’habitude en ajoutant mailbox.c dans les fichiers sources.

Au début j’avais des flash parasites quand je réduisais progressivement la largeur de l’impulsion. Ça arrivait quand la « wavetable » était modifiée au moment où le DMA était en train de lire la zone comprise entre la fin de la nouvelle impulsion et la fin de la précédente. J’ai dû modifier du code pour assurer la cohérence du signal lors de ces changements.

La pédale d’expression
----------

La pédale d’expression est en fait un vulgaire potentiomètre. Si je veux récupérer ses données, il faut que j’alimente ses deux pôles extrêmes (liés aux broches sleeve et tip du jack) et que je branche le curseur (ring) à un convertisseur analogique-numérique (ADC). Le potar se comporte alors comme un pont diviseur de tension, le signal sortant du curseur ayant une tension relative (pas forcément proportionnelle) à sa position. L’ADC se charge alors de convertir la valeur de la tension en un nombre exploitable par l’ordinateur.

Pour ce genre d’application, le circuit intégré MCP3008-I/P a l’air très populaire. Il est excellent marché et facile à utiliser. Il dispose de 8 entrées analogiques et sort des valeurs de 10 bits à une fréquence maximale de 200 kéchantillons/s sur l’interface série SPI. Ça tombe bien, notre Pi a une interface SPI intégrée au GPIO.

Il existe divers guides de montage, je me suis inspiré de celui-ci pour la partie connectique. Je connecte le circuit en tant que premier des deux périphériques SPI, en reliant CS à la broche ¯CE0 du GPIO.

 

Par contre, à la différence de l’article que j’ai cité, mon potar n’est pas un simple potar soudé au circuit, mais une pédale extérieure qu’on peut brancher ou débrancher. Je dois alors prendre quelques précautions liées au fait que je ne maîtrise pas cette partie du circuit. En particulier, je dois prévoir que les deux bornes du potar peuvent être momentanément mises en contact pour diverses raisons : câble défaillant, erreur de branchement… Cela aurait pour effet de court-circuiter le +3,3 V et la masse, ce qui serait dommageable pour le Pi.

Du coup j’ai rajouté une résistance d’au moins 1 kΩ en série côté 3,3 V. Cet ordre de grandeur est suffisamment faible devant la résistance du potar pour ne pas trop faire chuter la tension à ses bornes. Je branche alors la broche VREF du 3008 sur la liaison résistance-potar plutôt que sur le 3,3 V, de façon à ce que la course du potar couvre toute la plage de valeurs de l’ADC.

Cette protection n’est pas encore parfaite. En principe, il faudrait que je prévoie qu’on puisse brancher par erreur une source audio à pleine puissance sur la prise de la pédale et que le potentiel à la borne analogique de l’ADC puisse dépasser significativement de l’intervalle AGND–VREF. Mais c’est une autre paire de manches, et dans un premier temps je vais me contenter de ma petite résistance.

Le programme de test est encore une fois assez simple. WiringPi prend en charge la partie communication par SPI. La doc du 3008 donne le protocole qui permet de récupérer une valeur. Ça marche en bidirectionnel, c’est-à-dire que pour lire une valeur sur l’interface SPI, il faut y écrire en même temps. Pour lire une valeur, il faut envoyer les données suivantes :

La doc spécifie que le timing est important, et que l’horloge principale ne doit pas tomber sous les 10 kHz sous peine de décharge de la capacité qui bloque la valeur échantillonnée en cours de numérisation. Raison de plus pour passer par l’interface SPI hardware qui permet de gérer ça sans souci. Nous fixons donc sa fréquence à 1 MHz, la doc spécifiant 1,35 MHz comme limite supérieure pour une tension d’alim de 2,7 V.

Le test marche correctement. Seul petit problème : la valeur est entâchée de bruit et fluctue significativement alors que la pédale est immobile. Je n’ai que 6 ou 7 bits stables, pas plus. En fait, il y a des choses indiquées sur la doc du 3008 qu’on ne retrouve pas dans le montages amateurs qu’on voit sur internet… Notamment l’ajout de capacités de 1 μF pour déparasiter l’alimentation VDD ainsi que VREF. Et comme ma pédale donne un signal utile à très basse fréquence (au plus quelques centaines de Hz), je rajouterais bien une capa sur le curseur pour une stabilisation maximale. On peut aussi voir ça comme un filtre anti-aliasing. Compte tenu de la résistance qui varie entre 0 et 50 kΩ, quelque chose entre 10 nF et 0,1 μF devrait faire l’affaire pour obtenir une bande passante limitée grosso-modo à une centaine de Hz.

Je referai des tests ultérieurement, une fois que j’aurai reçu lesdites capacités. Au pire, il y a toujours la possibilité de filtrer numériquement les résultats, mais si je préfère ici commencer par rendre le signal échantillonné aussi précis que possible.

Addendum : j’ai finalement placé mes capa aux endroits prévus. Ça n’a malheureusement quasiment pas réglé le problème. Par contre je me suis dit que toutes ces broches d’entrée en l’air, ça devait sûrement faire antenne. Je les ai reliées à la masse AGND, et mon signal est soudainement devenu beaucoup plus stable. Avec les capa en plus, il est devenu parfaitement lisse, il ne reste plus que des oscillations à +1 ou −1, quand le signal est à mi-chemin entre deux valeurs quantifiées. Ce dernier point sera pris en charge côté numérique. Je peux donc maintenant bénéficier pleinement des 10 bits de l’ADC.

L’écran
----------

Pour afficher les diverses informations relatives à l’état du pédalier ou à l’édition des programmes, j’ai choisi un petit afficheur pas trop cher, abondamment disponible et relativement bien supporté.

Il s’agit d’un écran LCD issus de téléphones portables Nokia 5110 ou 3310. Sa résolution de 48 × 84 est relativement faible mais suffisante. Je le pivoterai pour obtenir un format d’image horizontal. En terme de dimensions il est un peu petit, mais pour l’usage prévuu, ça devrait suffire. Il est monochrome et rétroéclairé, ce dernier point étant indispensable à mon sens.

L’écran est vendu dans diverses enseignes (Adafruit, Sparkfun, Semageek…) sous forme breakout, c’est-à-dire soudé et précablé sur une plaque connectable facilement, en général avec des trous ou des broches à pas de 0,1 pouce. Attention, le câblage du breakout peut différer selon les marchands. Dans tous les cas, on retrouve 8 broches exposées, c’est simplement leur ordre qui est variable.

L’écran est équipé du contrôleur Philips PCD8544. On trouve sur le net divers codes d’exemple pour afficher du texte ou des graphismes. Ces codes ont tous en communs deux aspects : d’une part, ils se basent sur un montage utilisant des broches standard du GPIO, et d’autre part rien ne contrôle le timing des opérations, on fait au plus vite.

Je fais un premier câblage et un premier essai selon ces modalités. Le rétro-éclairage est laissé à fond, branché directement sur le 3,3 V. Je commence par tester des grilles où tout est éteint ou allumé. Les réglages de contraste ont l’air très sensible. Je les ajuste afin d’atteindre quelque chose de lisible. J’utilise un bias de 4 (codé 3) comme suggéré dans le manuel, et un contraste de 0x3A trouvé à taton.

Le programme de test marchote. L’écran affiche des choses, mais souvent corrompues. Parfois il devient fou et ses paramètres changent sans crier gare.

Me doutant qu’il s’agit d’un problème de timing, je lis le manuel et remarque que le signal d’horloge ne doit pas dépasser 4 MHz. Sur les blogs et forums, certaines personnes se plaignent aussi d’avoir l’affichage corrompu, mais sans obtenir de réponse. Mon hypothèse est que les Raspberry Pi de première génération sont suffisamment lents pour que le signal d’horloge généré manuellement reste sous la barre des 4 MHz. Mais sur des machines plus récentes comme la mienne, la vitesse limite est franchie et le signal se corrompt.

Obtenir un timing précis tout en gardant un haut débit de transmission me semble difficile. Heureusement, le gros des données transite par un protocole série qui est très semblable au SPI. Non seulement utiliser le SPI me permet d’économiser des broches du GPIO, mais en plus je dispose ainsi d’une horloge qui me permet d’envoyer les données à une cadence fixe sans contorsion au niveau du CPU.

Comme l’ADC de la pédale d’expression occupe déjà le sélecteur ¯CE0, je sélection l’écran via la broche ¯CE1. Je fixe le signal d’horloge à 1 MHz. Je ne sais pas si les deux périphériques d’un même port SPI peuvent être cadencés à des fréquences différentes, mais 1 MHz me semble suffisant pour que je ne juge pas nécessaire de creuser la question.

Le câblage est excessivement simple et ne nécessite rien d’autre que du fil.

 

Dans cette configuration, mon test se passe bien. Je fais défiler divers motifs sur l’écran, ce qui me permet de trouver l’orientation de son repère de coordonnées, parce que rien n’indique clairement où sont le haut et le bas.

Pas assez d’entrées
----------

Si on fait le compte des interrupteurs, on a quand même 12 pédales et 6 boutons destinés à l’édition des programmes. Cela fait 18 broches de GPIO à attribuer. Or le port physique n’est pas si étendu que ça, sur les 40 broches il y a déjà plus d’une quinzaine qui concernent l’alimentation, la masse, divers protocoles de communication… J’avais aussi commencé la conception du circuit avec l’écran entièrement câblé en GPIO, ce qui me prenait encore quelques broches. Il m’aurait probablement été possible de tout caser ainsi, mais cela aurait tenu très juste et je voulais quand même garder quelques broches de libre en cas de pépin ou pour des extensions futures.

Il me fallait donc trouver une solution. En cherchant un peu, j’ai trouvé la puce qu’il me fallait : un extenseur de ports. En l’occurrence le MCP23017, peu onéreux et bien documenté. Il permet d’obtenir 16 broches d’entrée/sortie à partir des deux broches I2C (un autre protocole série) du GPIO. Le 23017 ne pourra pas me servir pour tous les boutons, mais presque.

Je me suis inspiré de cette page pour un début de câblage. Comme pour les boutons directement reliés au GPIO, j’ai choisi d’insérer mes propres résistances de pull-up plutôt que d’activer celles intégrées qui font 100 kΩ.

J’affecte le numéro de périphérique 0 sur le port I2C en reliant A0, A1 et A2 à la masse.

Le 23017 dispose de 2 broches pour générer des interruptions, par exemple sur un front montant ou descendant d’une entrée. Je vais utiliser le mode mélange afin de générer une interruption globale pour toutes les entrées que je recueillerai sur une broche unique du GPIO.

Comme je m’intéresse à la totalité des 16 entrées, la configuration par défaut en doubles registres de 16 bits est adaptée.

Dans ma platine d’essai, je n’ai intégré que deux boutons, un sur chacun des deux ports 8 bits. Ça me permet a minima de vérifier la position des octets et des bits que je reçois.

 

Encore une fois, WiringPi dispose d’une interface pour piloter le port I2C. Mon programme de test inclut directement le dispositif anti-rebond. Tout se déroule sans anicroche.

Premiers assemblages

Je crois que j’ai tous les éléments nécessaires me confirmant la viabilité du projet sur le plan technique. Je peux passer à la construction d’un prototype en carton, qui va me permettre de jauger les volumes et les placements. Je pourrai ainsi corriger d’éventuelles erreurs avant d’attaquer la construction métallique. Je vais commencer par réaliser les cartes électroniques.

Réalisation des cartes
----------

J’utilise des plaques de protoypage simple face à pastilles carrées, ce qui me permet de faire un câblage beaucoup plus libre qu’avec des bandes. J’en ai trouvé de 160 × 100 mm², que je vais recouper à la scie à métaux.

Je perce les trous de fixation de 3 mm de diamètre à la chignole. Ils sont situés au milieu de blocs de 3 × 3 pastilles. Le trou central sert de guide à la mèche car je n’ai pas de colonne de fixation sous la main.

Carte principale

J’utilise un connecteur HE-10 de 2 × 20 broches pour relier le Pi à la carte à l’aide d’une vieille nappe IDE récupérée dans mes stocks de matos informatiques. J’ai utilisé divers autres connecteurs pour relier les sous-cartes et interrupteurs, essentiellement du HE-14 qui peut se couper sur mesure, et ainsi que des petits connecteurs à guide.

Je trouve préférable d’avoir des connecteurs plutôt que de souder directement les fils, car les manipulations et changements de boîtiers vont être plus aisées. Par exemple dans un premier temps, je ne vais pas relier les cartes aux interrupteurs à pied. Je vais utiliser à la place de petits interrupteurs que je placerai sur une plaque d’essai.

 
 

On voit là mes grands talents de soudeur du dimanche 29 février, ça doit bien faire rire les chevronné·e·s du fer qui me lisent. Ce fut laborieux et le résultat n’est pas très glorieux. J’espère ne pas avoir trop de problème de mauvaise soudure par la suite. Je vais devoir rajouter de l’adhésif isolant pour protéger certains câbles qui sont passés un peu trop près du fer.

J’ai soudé les fils sans isolant servant de piste (en gris dans le schéma) après les composants. Erreur, ça a été assez pénible, je commencerai plutôt par eux la prochaine fois. Pour m’aider, j’ai pris une capture d’écran du schéma de montage, qu’on voit habituellement côté composants. Avec un éditeur d’images, je l’ai retournée en miroir dans le sens horizontal afin d’avoir le plan de câblage dans le bon sens.

Dans la catégorie erreur de débutant, j’ai aussi soudé les fils de jonction (avec isolant) côté pistes. Ben je ne le referai plus. Comme en plus j’ai été un peu juste sur les longueurs de câble, ça a été une galère pas possible pour reprendre des soudures sitées sur le trajet des fils déjà posés. Ajouter à cela des gaines qui ne sont pas résistantes à la chaleur et qui se rétractent dès que le fil qu’elles entourent commence à chauffer.

Carte des LED

 

Avant toute chose, il me faut un support dans lequel encastrer les LED. Une plaque de matière quelconque (bois ou autre) de quelques milimètres d’épaisseur devrait convenir. Là j’ai utilisé une récup de plastique alvélolé. Grosso-modo, je dois faire en sorte que les LED ne dépassent que légèrement du panneau. La difficulté est positionner correctement les LED, à la bonne hauteur par rapport au circuit, avant des les souder. Je dois donc monter l’ensemble et faire la soudure une fois tout en place.

Comme j’ai le connecteur d’un côté et les LED de l’autre, côté cuivre, il faut que laisse une certaine distance entre les LED et la plaque pour pouvoir passer le fer.

Écran

Pour l’écran c’est très simple, il suffit de souder un connecteur HE-14 mâle de 8 broches dans les trous prévus à cet effet. En haut ou en bas, peu importe.

Petit inconvénient tout de même, les languettes métalliques qui attachent l’écran à la plaque empêchent de tourner deux des écrous de fixation de taille M3. Le problème est mineur dans mon cas, puisque les boulons que j’ai choisis sont terminés par une tête de vis à l’autre extrémité. Sinon il aurait fallu rajouter une entretoise pas trop épaisse pour que les écrous s’arrêtent au dessus des languettes.

Un pédalier en carton
----------

Ci-dessus le début du prototype. J’ai dessiné les emplacements de la plupart des éléments.

J’ai ajouté quelques boutons afin de vérifier qu’il y a assez de place pour ne pas trop faire d’erreur avec les pieds. Je constate qu’il vaut mieux que je décale la seconde ligne vers le haut d’environ 2 cm pour que ce soit confortable, par rapport à ce que j’avais prévu.

Les boutons occupent aussi de l’espace à l’intérieur. Je peux voir quelle place il me reste pour placer tous les éléments prévus : Pi, circuits, écran, panneau de LED, boutons d’édition, interface audio, câblerie, renforts.

Je continue de réfléchir également sur les dispositifs de fixation. Je pense visser la plupart des éléments au plafond, à l’exception de l’interface audio et du transfo du Pi qui seront fixés au fond. Je me demande encore comment les attacher car il n’y a aucune prise. J’utiliserai probablement des colliers de serrage mais c’est quelque chose que je vais devoir tester.

Encore des tests
----------

Je commence maintenant une série de tests plus complets, qui incluent à la fois le traitement audio, les entrées utilisateur et et l’affichage. Je commence avec une pédale qui active ou désactive une distorsion toute simple, et une seconde pédale qui active ou désactive l’accordeur.

J’ai déjà soudé la plaque principale ainsi que la plaque des LED. J’ai câblé les connecteurs pour les LED, l’écran et le jack de la pédale d’expression. Il ne me manque que le câblage des interrupteurs et boutons d’interface. Je les ferai plus tard, quand j’aurai établi le placement précis des câbles. Pour l’instant j’utilise deux interrupteurs posés sur une plaque sans soudure.

La permière série de tests se passe relativement bien. Je constate quand même les points suivants :

Je décide de régler immédiatement le dernière problème en remplaçant l’interruption par un thread de polling. La surcharge CPU sera très mineure et le besoin de précision temporelle est suffisamment faible pour que la solution soit parfaitement acceptable.

C’est alors que je rencontre un nouveau problème : l’affichage de l’écran est corrompu de manière aléatoire et irrégulière. Après quelques essais et l’examen du code de wiringPi, je me rends compte que les accès aux périphériques SPI ne sont pas immunes aux problèmes de concurrence. L’ADC de la pédale rentrait en conflit avec l’écran.

Pour situer le problème, les périphériques SPI partagent tous les mêmes broches. La sélection de l’interlocuteur se fait par une broche spécifique au périphérique qui est mise à l’état bas le temps de la communication. Toutes les communications sont donc multiplexées temporellement. Quand deux threads parlent chacun à un périphérique sans aucune protection, il est possible que la broche de sélection de l’un bascule pendant qu’un message est envoyé à l’autre, et que des messages arrivent à des destinataires inattendus.

J’ai donc ajouté un mutex dédié au port SPI pour sérialiser les accès, ce qui a effectivement résolu le problème.

Un peu d’organisation
----------

Comme j’en ai assez de me trimballer mes fichiers entre mon PC et le Pi par clé USB, avec parfois des erreurs de manipulation, je décide de mettre en place un serveur Git. Comme ça a l’air un peu casse-burne à faire sur Windows, je décide de le mettre sur le Pi. Le danger, c’est de perdre le dépôt principal en cas de problème sur la machine, mais le risque reste faible et les dégâts potentiels limités. Allons-y, il y a plein de tutoriels sur le net pour installer un serveur Git sur son Pi.

Et c’est là que c’est génial : aucun des tuto ne marche correctement ! Tous envisagent les accès en protocole pseudo-local (user@adresseip:/chemin/depot.git), sauf que ce genre d’accès ne marche pas depuis une machine Windows, impossible de lire le contenu du dépôt.

Après quelques galères, j’ai fini par trouver une méthode qui marche, sous la forme git://adresseip/depot.git. Côté client (msysgit), il faut tout de même lancer la commande suivante afin d’éviter qu’un git push ne se bloque en fin de commande :

git config --global sendpack.sideband false

Côté serveur, il faut lancer le git daemon en n’oubliant pas d’ajouter l’option --enable=receive-pack pour activer les push. J’ai placé un script dans /etc/init.d/ pour lancer le daemon automatiquement au démarrage. Cette page m’a bien aidé à comprendre la marche à suivre, moi qui ne suis pas du tout familier des sysèmes Linux.

J’en profite pour tester mes premières avancées sur la bibliothèque graphique. L’accordeur du programme de test m’indique maintenant la note la plus proche en grand sur l’afficheur LCD. Ça se voit bien de loin malgré la faible taille de l’écran. Le résultat est extrêmement pratique et dépasse quasiment mes espérances en la matière.

D’autre part le nombre de fichiers source commence à gonfler ; les temps de compilation s’allongent d’autant. Je vais devoir passer à un système de make plutôt que de recompiler tous les fichiers d’une traite à chaque fois. Je recopie plus ou moins celui que m’avait écrit jackoneill pour fmtconv, qui utilise les autotools.

Prototype augmenté

(Schémas, photos et peut-être vidéos à venir un peu plus tard.)

Après quelques avancées du côté du logiciel, je n’arrive plus à me retenir et me lance dans la conception d’une deuxième version de l’électronique pour corriger certains défauts. Au programme :

Des LED plus brillantes
----------

Les LED orignales étant un peu faiblarde en plein jour, j’en cherche de puissance nettement plus forte. Peu importe d’ailleurs qu’elles soient trop brillantes, puisqu’on pourra les atténuer par PWM sans toucher au point de fonctionnement électique.

Choix des LED

Je tombe sur des rouges et vertes de puissance équivalente, soit respectivement 180 et 150 mcd. Elles ont pour avantage d’avoir un tube assez peu haut (ce qui réduit mes besoins en longueur de vis) et d’avoir un grand angle de visibilité. Leur point de fonctionnement typique est de 20 mA pour environ 2 V. Leur consommation unitaire me demande d’utiliser une commande à transistor pour les alimenter.

Cette consommation me pose un autre petit problème. La somme de ce qui est branché au 3,3 V du GPIO ne doit pas tirer plus de 50 mA. Or si j’allume les 3 diodes simultanément je suis déjà à 60 mA. Il faut ensuite ajouter la consommation de tous les autres dispositifs électroniques connectés au GPIO.

J’ai donc deux possibilités : alimenter les LED sur le 5 V, la limite se situant alors sur la capacité du transformateur (on est large). L’inconvénient c’est que la distance entre la tension de la LED et celle de l’alimentation est bien plus élevée, ce qui va dissiper plus de puissance dans la résistance de contrôle. L’autre possibilité est de rester sur le 3,3 V et de limiter l’allumage simultané à une seule diode.

Par fainéantise je choisis la deuxième solution. Il m’est tout de même possible d’illuminer plusieurs LED en même temps par multiplexage temporel, ce qui divise aussi la puissance lumineuse de chaque LED. Cette astuce me réclame de changer un peu mon code de PWM, mais la modification se fait toute seule. Au final je vais pouvoir éclairer deux LED simultanément, à la moitié de leur puissance nominale.

Calculs des résistances

Je récupère des transistors NPN de type BC547B et je fais le calcul des résistances nécessaires. En faibles courants, VCESAT < 0,25 V et VBESAT = 0,7 V d’après la fiche technique. Le facteur d’amplification β vaut 200.

La LED rouge donne 180 mcd pour 20 mA à 1,95 V :

RR = (VALIM − VCESAT − VLED) / IC
    = (3,3 − 0,25 − 1,95) / 0,020
    = 55 Ω.

On arrondit à la valeur standardisée de 56 Ω.

La LED verte donne 150 mcd pour 20 mA à 2,1 V. Pour compenser la luminosité on déplace le point de fonctionnement : 24 mA à 2,15 V.

RG = (VALIM − VCESAT − VLED) / IC
    = (3,3 − 0,25 − 2,15) / 0,024
    = 37,5 Ω.

On arrondit à la valeur standardisée de 39 Ω.

En ce qui concerne la résistance entre la commande et la base du transistor :

IBmin = IC / β
        = 0,024 / 200
        = 0,12 mA.
RBmax = (VHI − VBESAT) / IBmin
         = (3,3 − 0,7) / 0,00012
         = 21666 Ω.

Il faut un facteur 2 de sécurité, on choisit donc 10 kΩ.

Essais

Sur la plaque d’essai, tout marche très bien, sauf que… comme les boîtiers des LED sont transparents et non translucides, le point lumineux est à la fois très étroit et très brillant. La lumière est trop agressive à mon goût.

Pas de problème, j’entreprends de dépolir les boîtiers. Pour cela, j’utilise une pierre à aiguiser à grain fin, le papier de verre que j’ai sous la main étant trop grossier. Le résultat n’est pas aussi parfait qu’avec une LED plus classique, mais reste tout à fait satisfaisant. Je considère le nouveau montage comme validé.

Je vais devoir changer intégralement la plaque électronique du module LED pour rajouter tous les nouveaux composants, et ajouter un fil 3,3 V au câble de liaison avec la plaque principale.

Codeurs incrémentaux
----------

En réfléchissant aux interactions que j’allais avoir avec le pédalier, je me suis dit qu’avoir une série de potar pour contrôler les principaux paramètres des effets pouvait être sérieusement pratique lors de la programmation des presets. Il me reste 7 canaux sur l’ADC, ça doit être jouable.

Bon en fait non les potars ce n’est pas terrible pour l’utilisation que je veux en faire. Leur position « absolue » risque de poser problème lors du changement d’assignation d’un paramètre à l’autre. Je me renseigne alors sur les codeurs incrémentaux, qui conviendront mieux.

Globalement il s’agit de doubles interrupteurs, émettant un signal en quadrature de phase quand on tourne le bouton, ce qui permet de savoir à la fois quand le bouton est tourné et dans quelle direction. Beaucoup de codeurs disposent en plus d’un bouton poussoir, ce qui est ma foi aussi pratique que dispensable.

J’opte pour des Bourns PEC11R-4215F-S0024, à 24 positions par tour complet. Je prend un jeu de boutons-capuchons avec. Je vais en installer deux pour le contrôle de l’interface utilisatrice, et cinq pour les paramètres. Je devrais pouvoir faire les deux premiers à côté des autres boutons de l’interface, les autres dans la section un peu vide sur la gauche du pédalier.

Câblage

Pour connecter tout ce petit monde, il va me falloir… un autre extenseur de ports. Je vais donc rajouter un 23017 sur I2C, exclusivement dédié aux codeurs incrémentaux.

Avec ces 16 entrées, je peux brancher 5 codeurs simples pour les paramètres et 2 codeurs avec bouton-poussoir pour le contrôle de l’interface. Les boutons-poussoir viendront doubler le bouton de validation.

Je vais devoir le monter sur une nouvelle carte, que je connecterai à la première avec un lot de dérivations pas très propres. Il va y avoir encore une floppée de résistances de pull-up et de protection à ajouter, que de joie en perspective.

Les codeurs proprement dits sont soudés et fixés ensemble à une plaquette, un groupe de 2 et un groupe de 5. Ces plaquettes supportent sur l’autre face des connecteurs, ce qui facilite la pose des câbles. Petit obstacle : mes plaquettes ne sont cuivrées que d’un côté. Cependant je trouve un moyen de fixer le tout solidement et à peu près proprement.

Je commence quand même à douter de mon idée. Présouder les codeurs va probablement me créer des difficultés quand il va falloir percer les trous dans le châssis. Ceux-ci devront être parfaitement ajustés pour que tous les codeurs rentrent correctement. Ai-je fait les choses dans l’ordre inverse ? On verra bien en temps et en heure.

Test préliminaires

Je câble sur la plaque d’essai un codeur avec son 23017 dédié. Cela fonctionne comme prévu et je peux apporter quelques réponses à mes interrogations :

Les résultats étant satisfaisants, je retiens cette idée et je l’implémenterai définitivement un peu plus tard.

Plus de pédales d’expression
----------

Je décide d’ajouter des emplacements permettant d’ajouter des pédales d’expression, quitte à n’en avoir qu’une initalement.

La première difficulté est liée aux parasites. Actuellement, toutes mes entrées inutilisées sont reliées à la masse, et sont par conséquent inutilisables. D’autre part la pédale d’expression existante est censée rester connectée quand on a besoin d’elle. Je n’ai donc pas de cas où j’aurais une entrée dans le vide pendant qu’une autre est échantillonnée ; cependant ce cas va se poser si je rajoute des entrées.

J’ai donc pensé rajouter des résistances de pull-down assez importantes, de l’ordre de 1 MΩ. De cette manière je garde l’entrée connectée à la masse même en absence de connexion. Quand une pédale est insérée, la résistance de pull-down devient négligeablement grande devant le potar (50 kΩ). Les positions extrêmes arrivent toujours à la masse et à VREF, seule la courbe de progression est influencée par cette résistance. J’ai établi sa formule et il s’avère que même avec un potar de 250 kΩ, l’influence du pull-down reste suffisamment faible pour ne pas trop altérer la linéarité de la courbe.

La deuxième difficulté est liée à la carte actuelle. Je n’ai pas les moyens d’ajouter proprement ces nouvelles résistances et connecteurs. Je vais donc devoir concevoir une nouvelle carte, ce qui me donne l’occasion de remettre un peu à plat l’ensemble du montage.

Nouvelles cartes
----------

Après réflexion, je décide d’une approche modulaire. Je vais créer plusieurs cartes : une carte centrale dispatchant les signaux du Pi et plusieurs cartes secondaires se répartissant différentes fonctions.

Cette modularité permet de personnaliser plus facilement le pédalier. Par exemple les codeurs incrémentaux sont tous sur une carte. Si on veut tourner à l’économie et ne pas mettre de codeur incrémentaux, on peut aussi faire l’impasse sur la carte correspondante.

J’ai donc répertorié les cartes suivantes :

J’ai décidé de passer toutes les résistances de protection à 10 kΩ au lieu de 1 kΩ, puisque dans le montage que j’utilise, aucune logique de pont diviseur n’intervient pour contraindre ces valeurs.

D’autre part j’ai ajouté un condensateur de filtrage de 100 nF à tous les interrupteurs (boutons, pédales et codeurs incrémentaux). Ça me semblait plus judicieux, surtout pour les codeurs incrémentaux où la cadence d’échantillonnage est plus rapide et rend plus difficile le filtrage des rebonds côté logiciel.

J’ai également trouvé une forme plus compacte pour disposer une grande série de résistances et de condensateurs liés à des interrupteurs.

Quant aux fils de connexions enjambant les pistes et l’enfer de leur soudure, j’ai retenu la leçon et je les ai placés côté composants. J’ai également prévu les emplacements nécessaires de façon à éviter de les faire cohabiter avec une patte de composant dans le même trou.

Je caresse aussi l’idée de (faire) graver un PCB pour le pédalier, cette fois-ci tout-en-un. Cependant ce sera CMS obligatoires, ce qui va amener un nouveau lot de difficultés et un prix final pas forcément moins cher que la conception actuelle. Je garde l’idée sous le coude pour l’instant afin de me consacrer à ce qui existe déjà. J’étudierai la question plus tard.

Un afficheur plus grand
----------

Choix de l’écran

J’ai commencé à faire des esquisses pour l’interface utilisatrice, et je commmence à trouver l’écran Nokia un peu étroit. Il ne manque pas grand-chose, pourtant. Je fais une petite recherche. Je suis très tenté par l’écran TFT 3,5” de chez Adafruit, qui fait 480 × 320, en couleurs 18 bits et tactile de surcroît. Cependant il est un peu cher (plus de 50 € en import) et en rupture d’approvisionnement au moment de mes recherches. Je me pose aussi la question du débit d’envoi des données. Celui-ci devient considérablement plus important avec toute cette surface et un facteur × 18 sur le bit/pixel. Une interface parallèle deviendrait nécessaire pour obtenir des taux de rafraîchissement acceptables.

Je finis par me rabattre vers un afficheur monochrome 128 × 64 de dimension équivalente. Il s’agit du modèle 12864ZW de chez… euh… je ne sais pas trop. Il est commercialisé par DFRobot et importé par Gotronic pour une vingtaine d’euros, ce qui me semble déjà plus raisonnable. Il est doté d’interfaces parallèle et série, ainsi que d’un rétro-éclairage. Il semble y avoir une documentation technique suffisante.

La notice du contrôleur (Sitronix ST7920) m’informe qu’il peut fonctionner en 3,3 ou 5 V. En principe je devrais pouvoir préserver la compatibilité du montage avec l’afficheur Nokia, mais il va tout de même falloir que j’achemine des alim et des masses en plus. En tout cas, ça a l’air jouable.

Essais et galères

L’écran reçu, je le branche sur la plaque d’essai et je code un embryon de driver. Comme pour le Nokia, j’utilise l’interface SPI pour le signal utile et son horloge, ainsi qu’une broche séparée pour l’activation de la puce. Malheureusement rien ne s’affiche, ou plutôt une série de caractères chinois avec un contraste extrêmement faible. Bref, je n’arrive pas à accéder au mode graphique et il y a un sérieux problème matériel d’affichage. Je me demande si mon exemplaire n’est pas défectueux. En cas de défaillance, toujours commencer par accuser les autres.

Au cours de mes tatonnements je tente d’alimenter l’écran en 5 V. Là tout s’éclaire ! Le contraste revient et le rétro-éclairage s’affirme vraiment. Je suis donc allé trop vite en considérant que si le contrôleur acceptait le 3,3 V, il en serait de même pour l’écran que j’ai acquis.

L’obstacle n’est pas insurmontable et je décide donc de passer en 5 V. En principe je devrais avoir les signaux de contrôle au même niveau. Mais après quelques tests avec un adaptateur de tension fourni avec le Nokia (NXP HEF4050B), il semble que l’écran réponde aussi bien au 3,3 V. Ce sera toujours ça de gagné.

Cependant mon driver ne marche pas correctement, malgré un suivi minutieux de la fiche technique. Je passe beaucoup de temps à le débugguer et parviens finalement à corriger la plupart des problèmes.

Pour le montage, je modifie le schéma existant afin de rajouter des broches tout en préservant le fonctionnement existant pour le Nokia. En effet je préfère être prudent et je veux pouvoir revenir en arrière en cas de problème inattendu et insoluble. Je place donc mes nouvelles broches de façon à pouvoir brancher au choix le connecteur 2 × 4 broches du Nokia, ou alors un connecteur 2 × 8 broches pour le 12864ZW faisant un pont sur les nouvelles broches. J’ai de la chance, la modification ne nécessite que très peu de recâblage. D’autre part les connecteurs HE-14 sont dépourvus de guides et me permettent de faire cette adaptation un peu bâtarde sans être gêné.

Tout semble s’arranger, je vais pouvoir faire le montage et faire des essais dans l’environnement matériel et logiciel complet.

Nouveaux essais, nouvelles galères

Après un certain temps de mise en place et de débuggage, j’obtiens mes premiers résultats. Cependant mon affichage est invariablement corrompu, de manière aléatoire. Je passe beaucoup de temps à essayer de déterminer un motif reproductible, des circonstances plus précises…

Assez rapidement je sens que le problème vient de la broche de sélection de la puce, qu’il y a des interférences avec les signaux venant de la pédale d’expression, mais je n’ai aucune idée précise de ce qui ne va pas. Est-ce que je ne respecte pas certains timings ? Un problème dans les séquences des basculements ? La notice technique n’est pas très éclairante et certains points restent un peu obscurs.

Je pense à un problème de threading comme celui que j’avais rencontré précédemment sur le SPI. Je change alors de manière radicale une bonne partie du code concerné pour me protéger au mieux de ce genre de problème, mais rien n’y fait.

J’essaie de changer dans la mesure du possible les signaux transmis par l’ADC de la pédale. L’ADC étant au bit près et non à l’octet, je peux déplacer les messages d’un ou plusieurs bits de façon à tomber sur des « creux » de perturbation côté ST7920. Après quelques tatonnements, je trouve une position qui améliore bien la situation mais qui ne la résout pas totalement.

Je passe alors du temps sur le net à la recherche de messages de personnes qui auraient eu le même problème que moi, mais ne trouve rien de probant. Cependant je trouve plus d’informations sur cet écran un peu mystérieux.

Tout d’abord, il existe sous différentes déclinaisons, certaines nécessitant le changement de composants CMS pour activer le mode série. J’ai de la chance, la mienne est correcte.

Ensuite, certaines versions, en particulier le 12864ZW, disposent de ponts sur le PCB permettant d’activer certaines fonctions quand on dépose un point de soudure dessus, ou qu’on y colle certains composants CMS (résistances, potar…) En particulier l’activation du rétro-éclairage ou le choix parallèle-série. J’aurais apprécié savoir ça avant, ça m’aurait évité de rajouter autant de câbles pour la liaison avec la carte !

Mais surtout je tombe sur une notice « alternative » du contrôleur. Difficile de dire si elle est plus récente ou plus ancienne. Ent tout cas le nom Digole remplace celui de Sitronix, et plus important, le nom de l’écran 12864ZW y est mentionné explicitement. Je me mets alors en quête des différences entre les deux documents, au cas où j’y trouverais quelqu’indice.

Et là, surprise ! Je constate que la description de la broche d’activation diffère significativement. La documentation initiale précisait que l’état bas réinitialisait la communication. Ici ce n’est point le cas, et en plus il est indiqué qu’il ne faut effectuer aucune transition sur les broches d’horloge et de donnée pendant toute la durée de cet état bas. Bref, la broche de sélection ne fait pas son travail et cette documentation admet à demi-mot que la fonction est bugguée…

Je vais donc encore devoir faire un patch hardware à l’aide d’une double porte logique ET (TI SN74HC08) s’intercalant entre la carte et l’écran, de façon à réduire au silence l’horloge et les données quand CS est bas. Cette porte me permettra du même coup de faire l’adaptation 3,3 vers 5 V, pas nécessaire mais tout de même plus prudente. Comme en l’état il n’y a plus de place sur la carte principale, je vais en faire un circuit à part localisé à côté de l’écran.

Bidouille dégueu : j’ai intercalé une diode passante entre le 5 V et le VCC de la puce pour faire légèrement chuter la tension d’alim. Cela me permet de faire rentrer les niveaux hauts en entrée dans les specifications requises, c’est-à-dire de les avoir supérieurs à 0,7 × VCC. Le fait que la chute de tension varie en fonction du courant débité n’est pas gênant dans notre cas.

Encore du carton, toujours du carton
----------

Pour des raisons pratiques, je vais avoir besoin de garder mon prototype à côté de moi sur la table, pendant encore longtemps pendant la conception logicielle. Je ne veux donc pas intégrer les éléments dans le boîtier actuel.

Cependant toutes ces plaques et fils qui courent partout n’est pas non plus très pratique. Je décide donc de placer l’ensemble du bazar dans une autre boîte en carton, une boîte à chaussure cette fois-ci, d’encombrement limité.

Je plaque les cartes sur le fond. Je loge le Pi sous le couvercle dans un coin, ce qui me donne un accès aux connecteurs depuis l’extérieur. L’écran est fixé sur la façade, ainsi que la plaque LED, les codeurs incrémentaux et la prise jack de la pédale d’expression.

Je perce une trappe pour faire passer les câbles des boutons et pédales. L’interface audio reste à l’extérieur, je pose dessus la plaque d’expérimentation avec tous les boutons et futures pédales. Voilà ! On y voit désormais un peu plus clair.

Petite frayeur tout de même : quand j’enfonce certains boutons-pédales, le logiciel en détecte d’autres en plus, et de manière curieusement localisée géométriquement. Je pense à un court-circuit dans mon montage, mais après quelques essais je finis par trouver le coupable : les boutons sont collés entre eux, et contrairement aux apparence, leur boîtier n’est pas parfaitement isolant sur un des côté. J’insère donc une fine bande de carton entre les deux rangées d’interrupteurs et l’affaire est réglée.

Ci-dessus, vue de la façade. Le Pi est sous le couvercle en haut à gauche, les LED de l’accordeur à droite de l’afficheur. Les boutons rotatifs sont les codeurs incrémentaux, tous fonctionnels. On ne la voit pas bien, mais la plaque posée sur l’Audiobox contient les 12 boutons-pédales sur la gauche, et les 6 boutons d’interface utilisatrice sur la droite. Planqué derrière à droite, un mini-ampli Marshall qui me sert pour les essais. Il passe surtout son temps à amplifier les parasites s’écoulant du téléphone sans fil posé un peu plus loin.

La boîte s’ouvre et exhibe ses entrailles. On y voit essentiellement un gros paquet de fils.

Les entrailles vues de dessus. Posée sur le fond à gauche, la carte principale. Au milieu, la carte des pédales et des boutons d’interface. À droite, la carte des codeurs incrémentaux. L’afficheur n’a pas encore eu droit à son « patch ».

Côté logiciel
----------

Les avancées sont bonnes et vont dans plusieurs directions.

Il me reste tout de même beaucoup de choses à faire, mais le seuil d’utilisabilité concrète se rapproche à grands pas.

Ci-dessus, un capture d’écran de l’émulation sous Windows. Il s’agit de l’écran principal, indiquant le programme et la banque courantes. La zone du milieu indique le dernier paramètre changé et l’effet concerné. Ici il s’agit du tempo que l’on peut régler en tapant en rythme sur une pédale dédiée. Les paramètres qu’on a choisi d’asservir au tempo (type LFO) se mettent alors automatiquement en cadence. En bas figure l’adresse IP de la machine, afin de faciliter une éventuelle connexion de service par prise réseau.

La partie grise en dessous représente les LED. En fonctionnement normal, celle de gauche indique une saturation sur la sortie et celle de droite une surcharge CPU (pouvant provoquer des grésillements). La verte du milieu n’est pas utilisée pour l’instant.

Persistance des presets
----------

Pour l’instant, toutes les modifications faites aux sons du pédalier sont oubliées dès que le programme s’arrête. Je vais donc rajouter une fonctionnalité de sauvegarde.

J’ai élaboré rapidement un format de fichier à la fois relativement léger et éditable manuellement avec un simple éditeur de texte. Cette caractéristique est importante car il peut parfois être nécessaire de corriger un fichier corrompu lors d’un test, ou simplement pour utiliser des fonctionnalités qui ne sont pas encore disponibles dans l’interface utilisatrice.

Le fichier de réglages a pour chemin /opt/pedalevite/etc/config/current. Il est lu au démarrage du programme, et sauvegardé à chaque fois qu’on stocke un preset dans une banque.

Mode autonome
----------

Jusqu’ici, j’avais besoin de lancer manuellement le programme pour faire tourner le pédalier, que ce soit à distance par une console SSH ou depuis l’écran et le clavier connecté au Pi. Ce n’est évidemment pas mode de fonctionnement final. Je vais à présent essayer de m’en rapprocher en lançant automatiquement le programme, sans qu’il soit nécessaire d’avoir le montage connecté à un équipement informatique quelconque (réseau ou clavier/écran).

En premier lieu je mets en place dans le menu de Pédale Vite des options pour redémarrer le programme, relancer la machine ou tout arrêter. En effet, une fois coupé de tout, je dois pouvoir assurer un minimum de maintenance, en particulier arrêter le Pi en toute sécurité.

Ces opérations ont lieu sans problème, avec tout de même une petite difficulté liée au fait que je dois afficher un message avant le redémarrage ou l’arrêt. Ce message doit arriver en entier jusqu’à l’afficheur avant que l’action en question ne coupe tout, et demande donc une petite temporisation.

J’en profite au passage pour rajouter un mode de sortie d’urgence. Si à son lancement, le programme détecte que le bouton Annuler est maintenu enfoncé, il ne va pas plus loin et s’arrête. En effet j’ai peur qu’un problème logiciel quelconque n’empêche un démarrage correct du Pi et ne bloque son accès.

Une fois ceci fait j’établis un plan d’installation. Tout ce qui concerne le pédalier ira dans /opt/pedalevite. Je crée un sous-répertoire bin qui accueillera le programme proprement dit. Je ne copie celui-ci depuis le répertoire de compilation que s’il a été préalablement testé avec succès. Je crée aussi un sous répertoire etc/config pour stocker les presets et autres fichiers de configuration.

Plantages

Je rajoute donc un script dans /etc/init.d/, avec pour seule dépendance $local_fs. De cette manière, le logiciel démarra aussi tôt que possible. Je redémarre, et là… le programme démarre puis plante le système au bout de quelques secondes. Je ne peux plus accéder à rien, SSH est muet, l’écran est noir et rien ne répond au clavier. Je redémarre de force et fais quelques nouvelles tentatives. Parfois, le démarrage va jusqu’au bout mais le cas général, c’est le plantage. Je n’y comprends rien.

Je me rends compte aussi que mes affichages sur console (essentiellement un rapport temps réel de l’occupation CPU) pourrissent bien les logs. Je les désactive donc.

Je dépose des messages sur des forums à propos de mon plantage mais les réponse sont rarement éclairantes. On me conseille d’insérer une pause significative avant le lancement, ce qui effectivement supprime le plantage mais ne m’en indique pas la raison. Je refais d’autres essais en changeant les dépendances ou les méthode de lancement. À un moment donné, le plantage devient systématique. Le pire, c’est que mon mécanisme d’arrêt d’urgence est inoppérant. Mon Pi est définitivement bloqué et inaccessible.

Je tente d’utiliser un driver Ext4 pour accéder à la carte SD du Pi depuis mon Windows et retirer le programme maléfique. Malheureusement la partition système n’est pas reconnue. C’est une spécificité Windows, il ne lit qu’une seule partitions sur les médias amovibles. Or la SD comporte plusieurs partitions, celle de NOOBS et la « vraie » partition système.

Pas de panique, je vais essayer de démarrer sous Linux avec un Live CD Ubuntu et monter ma carte SD. Problème : on est passé au DVD depuis un moment, et je n’ai sous la main que des CD comme supports vierges. Je trouve d’anciennes versions qui tiennent sur CD. Je grave la plus récente mais là, déception encore, mon matériel est trop récent et le démarrage s’arrête.

Finalement je finis par emprunter le portable d’un de mes coloc qui tourne nativement sous Linux et qui dispose d’un adaptateur USB-SD. J’effectue enfin la manip qui sauve ma machine.

Entre temps je me suis plus documenté et j’ai une vague hypothèse de ce qui a pu se passer : j’ai utilisé le DMA pour faire la PWM des LED sans trop me poser de questions. Or, le système utilise plusieurs canaux DMA à ses fins, dont celui occupé par mes LED (le numéro 0). J’ai donc probablement créé un conflit amenant au plantage. Quelques essais viennent confirmer mon hypothèse et je corrige le problème en passant sur le numéro 4, qui est disponible.

Échaudé par le précédent, je renforce et simplifie mon dispositif d’arrêt d’urgence. En effet, si celui-ci n’était pas fonctionnel, c’est parce que le test avait lieu après l’initialisation de l’ensemble du matériel.

Le programme démarre maintenant correctement sans aucune intervention manuelle. Je peux désormais débrancher clavier, souris et écran sans souci. Je ne laisse que la prise réseau pour l’accès console.

Raccourcir le temps de démarrage
----------

Le démarrage est long. Il faut environ 40 secondes avant que le programme ne soit opérationnel. Le système charge plein de services inutiles ou dispensables.

NOOBS

La première chose à faire est de se débarrasser de NOOBS, qui met beaucoup de temps à enchaîner sur le « vrai » système. Pour cela :

sudo fdisk -l

Repérer le numéro de la partition de NOOBS. C’est habituellement la nº 1, pesant 1 Go en FAT16. Repérer le numéro de l’autre partition de boot, en FAT32. C’est habituellement la nº 6, précédant la grosse partition Linux qui couvre le reste du disque. Puis monter la partition NOOBS :

sudo mkdir /mnt/noobs
sudo mount /dev/mmcblk0p1 /mnt/noobs

Ajouter le fichier autoboot.txt :

nano /mnt/noobs/autoboot.txt

Y écrire la ligne suivante, en remplaçant éventuellement 6 par le numéro de la partition voulue :

boot_partition=6

Redémarrer la machine et constater la différence…

Wi-Fi et Bluetooth

Tout d’abord, on peut se passer du Wi-Fi et du Bluetooth. On ne gardera que la connexion filaire, ce qui est d’ailleurs un peu plus sûr dans le cadre de l’utilisation prévue. La procédure est simple :

sudo nano /etc/modprobe.d/raspi-blacklist.conf

Ajouter les lignes :

# Wi-Fi
blacklist brcmfmac
blacklist brcmutil
# Bluetooth
blacklist btbcm
blacklist hci_uart

Services inappropriés au mode lecture seule

J’ai également sous la main une autre liste de services à retirer ou remplacer, pas directement liée à l’accélération du démarrage, mais plutôt au passage du système de fichier en lecture seule, pour permettre une extinction à chaud. Je ne garde ici que les premières étapes, qui n’ont pas de conséquences significative sur l’utilisation générale du Pi, à part le retrait pur et simple de l’interface graphique.

Retirer les choses qui ne sont pas nécessaires, ou qui sont inappropriées pour les opérations en lecture seule :

sudo apt-get remove --purge wolfram-engine triggerhappy pi-bluetooth
sudo apt-get remove --purge cron anacron logrotate dbus dphys-swapfile

Retirer ce qui à trait à X-Server :

sudo apt-get remove --purge xserver-common lightdm
sudo insserv -r x11-common

Retirer les bibliothèques liées à X11 :

sudo apt-get autoremove --purge

Installer busybox syslog à la place de rsyslog :

sudo apt-get install busybox-syslogd
sudo dpkg --purge rsyslog

Autres programmes et services dispensables

À ce niveau de purge, le résultat est déjà très concluant : le programme est opérationnel 9 secondes après l’allumage à froid, temps qui est à présent tout à fait supportable.

Si on veut continuer, il y a une méthode simple pour connaître ce qui prend du temps lors du démarrage. Sur un terminal :

systemd-analyze blame
systemd-analyze critical-chain

La première commande liste les programme qui prennent le plus de temps, avec leur temps d’exécution respectif. La deuxième liste les éléments du chemin critique, qui sont donc à optimiser en priorité.

Système de fichiers en lecture seule
----------

Je passe maintenant à une étape important qui permettra d’éteindre le pédalier à chaud sans préavis et sans risquer d’endommager la mémoire de masse.

La solution est dans ce cas de passer le système de fichiers en lecture seule. En effet, les problèmes de corruptions interviennent quand on écrit sur la carte et qu’on coupe le courant à ce moment-là. Comme il n’y a plus d’écriture sur la carte SD, les risque des corruption disparaissent.

Mais alors, comment sauvegarder les modifications de réglages du pédalier ? Simplement en remontant temporairement le système en lecture-écriture, tout juste le temps de faire la sauvegarde. Cela minimise les risques.

Côté système

Je me sers de l’article cité précédemment, ainsi que de celui-ci. Les premières étapes ont déjà été faite dans la partie accélération du démarrage ; voici les suivantes :

Il y a quelques liens sur /tmp à faire, entre autre pour le stockage des baux DHCP

sudo rm -rf /var/lib/dhcp/
sudo ln -s /tmp /var/lib/dhcp

Également :

sudo rm -rf /var/run /var/spool /var/lock
sudo ln -s /tmp /var/run
sudo ln -s /tmp /var/spool
sudo ln -s /tmp /var/lock

Ensuite :

sudo nano /etc/init.d/checkroot.sh

Commenter le do_start() à la fin.

sudo nano /etc/init.d/checkfs.sh

Commenter le do_start() à la fin.

sudo nano /etc/init.d/checkroot-bootclean.sh

Commenter le rm et le clean_all dans le case start.

sudo nano /etc/init.d/mountall.sh

Commenter le swaponagain 'swapfile'.

sudo insserv -r bootlogs
sudo insserv -r alsa-utils
sudo insserv -r console-setup
sudo insserv -r fake-hwclock
sudo nano /etc/fstab

Ajouter ,ro après les defaults pour les partitions du disque, ce qui donne :

proc            /proc           proc    defaults             0       0
/dev/mmcblk0p6  /boot           vfat    defaults,ro          0       2
/dev/mmcblk0p7  /               ext4    defaults,ro,noatime  0       1

Y ajouter la ligne :

tmpfs           /tmp            tmpfs   defaults             0       0

Ensuite :

sudo nano /boot/cmdline.txt

Ajouter ro à la fin :

dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=/dev/mmcblk0p7
	rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait ro

Il suffit de redémarrer la machine et le tour est joué. Cependant ce mode lecture seule ne convient pas pour le développement. Il est alors nécessaire de remonter manuellement le système de fichiers en lecture et écriture :

mount -o remount,rw /

Cette commande n’est pas persistante et nécessite d’être relancée après le démarrage de la machine. On peut à nouveau passer le système en lecture seule en changeant le rw en ro.

Côté code

Mon système de sauvegarde a été légèrement révisé. Le programme ne sauve plus le fichier de configuration directement à l’endroit spécifié, mais d’abord dans /tmp qui est un disque RAM. Une fois le fichier sauvé, un script est appelé. Celui-ci monte le système de fichiers en lecture et écriture, déplace le fichier de /tmp vers sa destination finale, et remonte aussitôt le système en mode lecture seule. Si le système de fichier était déjà en lecture et écriture, seul le déplacement est fait. Pendant tout ce temps, la LED verte est maintenue alumée pour indiquer qu’il y a une opération disque en cours.

#!/bin/sh

# Makes sure we run as root
if [ $(id -u) != 0 ]; then
  exec sudo "$0" "$@"
fi

fsro=`mount | grep " / " | grep -c "(ro[),]"`
if [ $fsro != "0" ]; then mount -o remount,rw / ; fi
mv "$@"
if [ $fsro != "0" ]; then mount -o remount,ro / ; fi

Une amélioration à envisager serait d’intégrer un système de backup automatique, qui garderait et numéroterait les configurations précédentes tout en élcaircissant les sauvegardes les plus vieilles.

Le point sur les effets et le logiciel

Je vais énumérer les principales fonctionnalités disponibles sur le pédalier à l’heure où j’écris ces lignes, c’est-à-dire début septembre 2016. Ci-dessous, Pédale Vite (v1) dans son boîtier :

Effets
----------

Tous les effets fonctionnent en mono ou en stéréo, certains pouvant ajouter une dimension stéréo à un signal mono. Ils sont également tous dotés de trois paramètres : un bypass, un réglage de mix entre wet et dry (signal traité et non traité) et un volume sur le signal traité.

J’ai ajouté quelques sons d’exemples pour montrer un peu de quoi on parle. Alors attention, ce ne sont pas DU TOUT des exemples « vendeurs ». Je n’ai absolument rien préparé, j’ai simplement fait défiler les effets les uns après les autres et changeant un paramètre ici et là, pour montrer que ça bouge, tout en gratouillant quelques cordes des autres mains. Ça prend déjà beaucoup de temps de brancher le dispositif, d’enregistrer des choses à la volée, de couper les prises et de mettre le résultat en ligne. Et par dessus le marché, mon ampli ne marche que capricieusement. Si vous cherchez des sons de démo sexy et in your face avec des riffs cool ou des mélodies intéressantes, inutile de cliquer dessus.

Techniquement, j’ai branché Pédale Vite sur un Marsnall 8080V (oui, le haut du h s’est cassé, c’est devenu un Marsnall) à volume assez modéré. Le son est capturé par un SM 57 placé à une trentaine de centimère de l’ampli. Le tout est numérisé sur une Fireface UCX en 24 bits, 44.1 kHz. J’ai laissé pas mal de marge en terme de niveau (environ 15 dB), donc le son peut paraître un peu faiblard. C’est du mono, donc pas de démonstration d’effets stéréo. Ah oui, la guitare est une Washburn Mercury II, les cordes sont usées… jusqu’à la corde et les câbles des daubes premier prix (sauf pour le micro) qu’il faut que je m’empresse de changer.

Input Impedance Fix

Cet effet permet de corriger en quelque sorte l’impédance d’entrée de la carte son, qui peut être un poil juste, résultant en une légère atténuation des aigus. Il s’agit d’un simple filtre linéaire de premier ordre de type high-shelf.

On peut choisir le niveau d’amplification des aigus et la fréquence de seuil. Il faut calibrer l’effet en utilisant un ampli avec un réglage aussi transparent que possible (son clair, pas d’égalisation). On compare alors le son avec la guitare branchée directement avec celui du pédalier placé en intermédiaire avec cet unique effet.

Idéalement il faudrait que je sorte cette effet des programmes et que le logiciel le rajoute implicitement en début de chaîne, si nécessaire. Le réglage se ferait séparément une bonne fois pour toute.

Exemple

Simple distortion

C’est la distorsion que j’ai utilisé dans mes premiers tests et qui n’a pas beaucoup évolué. Il s’agit d’une saturation asymétrique toute bête, avec un filtre passe-haut en entrée afin de virer une éventuelle composante continue et de nettoyer un peu les graves. Il est possible de choisir le gain de la distortion (jusqu’à +60 dB) et la fréquence de coupure du filtre.

La disto est tout à fait utilisable mais a un son parfois un peu dur. Un de mes prochains travaux concernant les effets sera de doter le pédalier d’une distorsion obtenue par modélisation de circuits analogiques.

Exemple

Distortion Tone Stage

C’est un peu le complément indispensable de l’étage de distorsion pur. Il s’agit d’un réglage de tonalité modelé d’après un circuit qu’on trouve dans de nombreuses pédales, type DS-1 ou Big Muff Pi. Malheureusement ce genre de filtre fait apparaître systématiquement un creux dans les médiums. L’effet a donc été modifié de façon à proposer un réglage des médiums. Le filtre à toutefois été modifié de façon à ajouter un réglage des médiums. Il est également possible de choisir la fréquence centrale du filtre, ce qui permet de calquer facilement l’étage de tonalité de la plupart des pédales utilisant ce système.

Exemple

CompEx

Un compresseur/expanseur relativement simple. On commence par définir le niveau de seuil (knee). On choisit ensuite le ratio au-dessus et en dessous de ce seuil, ce qui permet de comprimer ou d’étendre la dynamique du son. Il est possible d’ajuster les temps de réponse attack et release. Le gain général est corrigé automatiquement en fonction des réglages, cependant un paramètre supplémentaire permet de l’ajuster manuellement.

Une amélioration possible consisterait à montrer la courbe et à y indiquer en temps réel le point de fonctionnement.

Exemple

FlanCho

C’est un chorus/flanger relativement classique. Il peut générer un signal stéréo à partir d’une entrée mono. On peut régler le nombre de voix, de 1 à 4, pour obtenir plus ou moins d’épaisseur.

La fréquence des oscillations est réglable, ainsi que la forme d’onde (sinus, triangle, dents de scie montantes et descendantes, sinus avec glissements aléatoires). Il y a en plus un paramètre qui permet de déformer l’onde de contrôle et de la saturer par le bas ou par le haut. Un autre paramètre permet de fixer manuellement la phase, ce qui peut être utile pour placer l’oscillation à un endroit précis quand on change de programme par exemple, ou à tout moment si on associe une pédale à ce paramètre.

On peut ajuster la profondeur des oscillations ainsi que le retard global entre la voix principale et les voies oscillantes. Ces deux paramètres altèrent la tonalité de l’ensemble.

Le côté flanger est déclanché par un feedback qui peut être réglé positivement ou négativement. On peut aussi désactiver complètement la voix principale pour transformer le chorus en simple vibrato.

Exemple

Phaser

Un phaser au son très typé. Il peut générer un signal stéréo à partir d’une entrée mono.

On peut choisir la vitesse et la profondeur des oscillations. Comme pour FlanCho, un paramètre permet de fixer la phase manuellement. Il est également possible de stopper les oscillatons. Un autre paramètre permet de déplacer la phase par rapport à son point courant, ce qui peut être intéressant pour obtenir des oscillations supplémentaires en branchant la pédale d’expression dessus.

Il y a une réinjection (feedback) qu’on peut régler en intensité et en couleur. Ce feedback est saturé, il peut donc être intéressant de pousser un peu le niveau du signal d’entrée pour enrichir le résultat.

Un filtre passe-bande désactivable permet de choisir une plage de fréquences à conserver sur le son phasé. Cela permet essentiellement de limiter les basses fréquences sur les réglages un peu francs.

Enfin on peut régler la proportion entre le signal phasé et le signal original, l’effet le plus fort étant obtenu avec un mélange égal. Quand on ne garde que le signal phasé en stéréo, on obtient un effet de spatialisation peu ou pas colorant.

Exemple

Wha-wha

Il s’agit d’une wha-wha plus ou moins calquée sur la Cry Baby. On peut régler la fréquence du filtre, qui est affectée par défaut à la pédale d’expression. La plage a été étendue, ce qui permet d’obtenir un son ravageur dans les basses fréquences. On peut également régler le niveau de résonance.

Exemple

Parametric Equalizer

Un égaliseur paramétrique 4 bandes très classique. Chaque bande est constitué d’un filtre d’ordre 2. Pour chaque bande on peut régler sa fréquence, le facteur de qualité (largeur de bande), la forme du filtre (pic, plateau haut et bas, passe-haut et bas) et son gain. Chaque bande est également activable individuellement.

Pas d’exemple pour cet effet.

Filter Squeezer

C’est un filtre très particulier. Il est basé sur le fameux filtre Moog passe-bas 4 pôles, sérieusement modifié pour ne pas dire vilainement charcuté.

Il donne un son qui va d’une douce chaleur un peu vintage à une fuzz rugissante en passant par une radio défectueuse ou le larsen parasité. Il y a des sons qui sont comparables à ceux obtenus par la Fuzz Factory.

En terme de réglages, on peut régler la fréquence de coupure. Celle-ci est automatiquement assignée à la pédale d’expression. On peut régler la résonance, les valeurs les plus élevlées mettant le filtre en auto-oscillation. On peut également régler la coloration, qui influe sur l’aspect destructif et fuzz du filtre. Enfin, il est possible d’ajuster le niveau d’entrée, le filtre étant très sensible au volume de ce qui lui rentre dedans. Il est d’ailleurs de bon ton de placer devant un compresseur aux réglages musclés si on veut obtenir quelque chose d’un tant soit peu prévisible et reproductible.

Ça fait un moment que j’ai conçu ce filtre, il figure d’ailleurs dans la panoplie des plug-ins intégrés à Ohm Studio. Je ne l’avais jamais essayé sur une guitare auparavant et je dois dire que le résultat m’enchante infiniment.

Exemple

Frequency Shifter

C’est un effet assez simple qui décale toutes les fréquences du son. Comme les fréquences sont additionnées et non multipliées, les rapports harmoniques se perdent et le son devient atonal ou inharmonique, se rapprochant d’un son de cloche. Cependant quand la fréquence de décalage tombe sur une note spécifique, certaines notes en liaison (octave, quinte, quarte…) se mettent à sonner de nouveau juste et prennent une coloration très spéciale.

C’est un effet qui ressemble au ring modulator, mais qui ne réfléchit pas l’image spectrale comme c’est le cas pour ce dernier.

Seule la fréquence de décalage est réglable, elle peut être positive ou négative.

Exemple

Delay

Effet d’écho relativement classique. Il peut générer un signal stéréo à partir d’une entrée mono.

Il y a en fait deux lignes à retard indépendante, une pour chaque canal. Pour chaque ligne on peut régler la durée du retard, son niveau de sortie, le taux de réinjection et le filtrage (passe-haut ou passe-bas) de cette réinjection.

Il est également possible de croiser les réinjection des lignes.

Exemple

Freeverb

Il s’agit d’une réverbération basée sur un algorithme de type Schroeder. Les réglages ont été mis au point par Jezar de Dreampoint et diffusés dans le domaine public. Elle peut générer un signal stéréo à partir d’une entrée mono.

La qualité de cette réverbération est très correcte, sans être non plus transcendante. Elle permet de créer un peu matière autour du son.

Les réglages de la réverb originale de Jezar ont été conservés : taille de la pièce, atténuation, niveaux wet et dry, largeur et possibilité de « figer » le son de sortie. J’ai rajouté en plus des filtres passe-haut et passe-bas pour nettoyer le son.

Exemple

Tremolo

L’effet de trémolo est une sorte de volume oscillant.

On peut régler la vitesse des oscillations et la forme d’onde (sinus, carré, triangle, dents de scie montantes et descendantes). Un paramètre fixe leur amplitude. Deux autres paramètres règlent la courbure à applique à la commande de volume, pour se rapprocher des trémolos analogiques classiques.

Exemple

Autres exemple, quelques combinaisons d’effets

Accordeur

Ce n’est pas un effet à proprement parler mais je vais quand même le décrire ici. Il s’active par une pédale et coupe le son de sortie quand il est actif. Il est possible de choisir les accordages standards pour guitares 6 cordes et basses 4 cordes. Un mode chromatique permet d’accorder sur n’importe quelle note de la gamme.

La note détectée (ou plutôt la plus proche dans le réglage choisi) est affichée en grand sur l’écran. Les LED indiquent si le son est trop haut ou trop bas par rapport à ladite note.

Manques notables

Une bonne distorsion basée sur un modèle analogique, un noise gate et un moteur de convolution (simulateur d’ampli, réverb)

Possibilités
----------

Voici les possibilités offertes par le pédalier. Elles ne sont pas encore toutes disponibles dans l’interface utilisateur. En revanche, on peut y accéder en modifiant à la main le fichier de configuration.

Assignation des pédales

Les 12 pédales peuvent être configurées à la fois globalement, par banque et par programme. Sur chaque pédale, on peut assigner des événements à la pression, au relâchement et au maintien enfoncé (2 secondes). Les événements liés à la pression sont organisés en cycle, c’est-à-dire qu’en pressant plusieurs fois, on peut déclancher différents événements à chaque fois. Chaque événement est composé d’une liste d’actions.

Une action peut incarner différentes choses : changer de programme, changer de banque, modifier un paramètre, taper le tempo, activer l’accordeur… Grâce au système de liste d’actions et de cycles, on peut obtenir des comportements riches et complexes.

Paramètres et contrôleurs

Dans un programme, on peut assigner n’importe quel paramètre à un ou plusieurs contrôleurs (pédales d’expression et codeurs incrémentaux). Un contrôleur au plus peut modifier le paramètre de manière directe, les autres peuvent être assignés en modulation relativement à cette valeur. D’autre part l’effet peut déclarer des paramètres comme étant assignés par défaut à une pédale d’expression (par exemple la wha-wha).

Chaque assignation se définit par une plage de valeurs et une courbure. Il est également possible de définir une liste de crantage.

Les paramètres temporels peuvent être réglés en temps absolu (ms) ou en unité musicale, relative au tempo courant.

Sources de modulation

Ce point continue celui sur les contrôleurs. Les sources de modulation sont des effets qui permettent de générer des informations de contrôle. Bref, ce sont des contrôleurs internes, pilotés par des algorithmes. Actuellement nous avons les LFO (Low Frequency Oscillator), qui synthétisent des oscillations basse fréquence. Il y a également les suiveurs d’enveloppe qui permettent de détecter le volume du son à n’importe quel point de la chaîne et de le transformer en signal de modulation.

Les LFO permettent d’obtenir une palette de formes d’onde variées. De base, on peut contrôler leur vitesse et leur amplitude. Petit panorama ci-dessous.

Sinus. C’est la forme d’onde de base :

Parabole :

Carré :

Triangle :

Dents de scie :

Bruit rouge :

Varislope. Il s’agit d’une onde qui peut incarner différentes formes situées entre le carré, le triangle et la dent de scie. On peut contrôler la forme précise à l’aide de deux paramètres auxiliaires. Le premier, le temps, détermine la position temporelle du premier extremum de la courbe par rapport à la période complète. Le deuxième, la forme, donne la forme de la transition entre les deux extrema.

Temps = 25 %, forme = 0 % :

Temps = 25 %, forme = 50 % :

Temps = 25 %, forme variant entre 0 et 100 % :

N-Phase. Là aussi, cette forme est contrôlée par deux paramètres supplémentaires. Elle est constituée de plusieurs sinus déphasés. Le LFO passe régulièrement d’une phase à l’autre. Le premier paramètre contrôle le temps de découpage, et le deuxième le nombre de phases.

28 découpages, 2 phases :

16 découpages, 3 phases :

Biphase. Ce mode ressemble au N-Phase, mais le nombre de phases est fixé à 2. En revanche, il est possible d’ajuster la différence entre les phases.

16 découpages, quadrature de phase :

32 découpages, déphasage léger :

Enfin, plusieurs paramètres s’appliquent à la plupart des formes d’onde et permettent de les transformer de manière similaire.

Une première série de paramètres agit sur la phase de l’oscillateur, tandis que l’autre joue sur la forme générée.

Distorsion de phase. Ce paramètre permet de déplacer la position temporelle du milieu de la forme d’onde. Il correspond à un réglage de pulse width. Ici sur un sinus :

Mais le point qu’on déplace n’est pas forcément celui du milieu. Un autre paramètre permet de sélectionner ce point. Ci-dessous, la même déformation en déplaçant le point situé aux trois quarts :

Il est possible d’introduire un élément chaotique. Ce paramètre accélère ou ralentit aléatoirement l’oscillateur en veillant à ce qu’il retombe toujours sur ses pieds afin que le rythme global soit conservé. C’est une manière très simple de rajouter un peu de vie dans une oscillation. Ci-dessous la même déformation de phase appliquée à deux formes d’onde :

Maintenant, les paramètres agissant sur le signal généré.

Inversion de signe. Elle sert par exemple à transformer une dent de scie montante en descendante :

Passage en unipolaire. Ce paramètre remonte et compresse la courbe afin que le bas soit à zéro. Ce mode peut simplifier les réglages de taux de modulation car le minimum du LFO correspond à la valeur de base du paramètre modulé.

Sample & Hold. Ce paramètre permet de créneler la courbe du LFO en bloquant régulièrement sa valeur pendant une courte période :

Smooth. On peut adoucir les transitions brutales à l’aide de ce paramètre :

Il est également possibe de fixer la phase du LFO à tout moment. On peut ainsi facilement synchroniser le LFO à un changement de programme.

Signalons aussi que les paramètres propres aux sources de modulations sont eux-mêmes modulables par n’importe quel contrôleur ou autre source, y compris sous forme de rebouclage. D’autre part il n’y a virtuellement pas de limite au nombre de sources qu’on peut inclure dans un programme…

Suiveurs d’enveloppe

Cette autre source de modulation prend en entrée un signal audio, en détecte le volume instantané et le restitue sous forme de modulation. On peut insérer des suiveurs d’enveloppe n’importe où dans la chaîne des effets.

Le suiveur est configuré par trois paramètres temporels : le temps d’attaque, le temps de maintien et le temps de relâchement. Le premier détermine la vitesse à laquelle le suiveur répond à une montée de volume. Le dernier est identique mais pour une descente de volume. Enfin le temps de maintien indique pendant combien de temps le suiveur s’immobilise sur la valeur d’un pic avant de redescendre.

Un paramètre de gain permet d’ajuster la sensibilité générale. Le paramètre de seuil permet de fixer un minimum en-dessous duquel le suiveur ne redescend pas. C’est utile pour recueillir uniquement les pics de volume les plus forts. D’autre part, le suiveur fonctionne en deux modes, linéaire et logarithmique. Dans le deuxième cas, la modulation est proportionnelle à un volume en dB. Enfin il est possible de choisir si la modulation est limitée par le haut, ce qui correspond à un écrêtage des pics les plus forts.

Nouvelles améliorations

Alimentation séparée pour la carte audio
----------

Premier essai

Quand on a un gros gain sur la distorsion, le bruit de fond remonte. Ce bruit de fond a des orgines diverses. Ici en particulier, ces sont les parasites liés à l’activité du CPU qu’on entend le plus. On les reconnaît clairement car la tonalité du bruit varie en fonction de la taille des buffers de traitement et de la charge de calcul.

Ces parasites sont transmis à la carte audio par l’alimentation qui provient directement du Pi via l’USB. C’est un problème qui a d’ailleur été rencontré par d’autres personnes. Une solution efficace consiste à donner à la carte une alimentation séparée. Par exemple, on peut utiliser un hub USB alimenté. Cependant un hub c’est un peu encombrant et surdimensionné. Du coup j’ai récupéré un petit chargeur de téléphone portable 5 V 450 mA et j’ai fabriqué un bout de câble à trois branches.

La première, c’est le chargeur dont la prise a été coupée afin de mettre les fils à nu.

La seconde, l’entrée, est constituée d’un connecteur femelle USB-B. Comme je n’ai trouvé que des embase, je l’ai soudée sur un tout petit carré de plaque de prototypage (4 × 4 trous). Au paravant, j’ai passé trois fils dans ce carré. Un noir pour la masse, et un blanc et un vert pour les données. Voir le plan de connexion. Les fils sont placés à côté des broches et ressortent par le côté. Ils sont ainsi coincés entre la fiche et le carré quand on soude les deux ensemble. Une fois repliées, les pattes de fixation de l’embase permettent de maintenir l’assemblage compressé pendant la soudure.

La troisième est une prise USB-B mâle. J’ai eu du mal à la trouver (un modèle chez Mouser) ; manifestement personne ne confectionne de câble USB. J’y ai accroché les deux fils de données ainsi que le fil rouge du chargeur (positif) au +5 V. La masse récupère un assemblage du fil noir du chargeur (négatif) et du fil noir issu de l’embase femelle.

Le tout est enveloppé de ruban adhésif d’électricien. Le montage s’intercale entre le câble de liaison USB et la carte audio. J’ai également bricolé une dérivation sur la prise 220 V femelle dans le pédalier afin d’en rajouter une seconde. J’ai accroché le chargeur au transfo du Pi avec un simple ruban adhésif.

Ronflette

Le résultat est plutôt concluant. Une grosse partie des parasites est partie, sans toutefois avoir complètement disparue. Par contre je récupère une ronflette accordée en sol (100 Hz) qui n’était pas là auparavant, ou beaucoup moins forte. Il s’agit très probablement d’un mauvais filtrage du chargeur bas de gamme après redressement de l’alternatif. Du coup j’ai intercallé un petit filtre entre le chargeur et le montage précédent. Il s’agit d’un simple passe-bas RC constitué d’une résistance 2,2 Ω en 2 W (1 W suffirait) et d’un condensateur 4700 µF (16 V), soit une coupure à 16 Hz. Le condensateur électrolytique est doublé en parallèle d’un condensateur film 100 nF pour bloquer les parasites HF.

Le montage est fixé au socle du pédalier avec vis et entretoises, non représentées ici. Malheureusement je n’ai pas eu l’occasion de faire de photo pour cette partie.

Le résultat est encore imparfait, il reste des parasites de toute sorte. Cependant l’ensemble est tout de même moins bruyant qu’avec l’alimentation venant du Pi, ça valait donc le coup de le faire.

Interrupteurs au pied sans clic
----------

Les interrupteurs choisis initialement étaient bruyants, en plus de nécessiter une pression importante pour basculer. Je les ai donc changés contre des interrupteurs à touché soft, sans clic. Ça doit être des Toowei T601A21 bien que je ne sois pas absolument sûr du modèle. Les prix sont grosso-modo similaires. Non seulement le touché est effectivement nettement plus sensible et agréable, mais en plus ces interrupteurs sont beaucoup plus faciles à souder, en plus d’avoir un encombrement vertical réduit.

Le seul inconvénient, c’est que les rondelles livrées avec sont un peu étroites et sont parfois un peu limites avec mes trous un peu trop larges. Je les ai donc remplacées par celles des anciens interrupteurs qui convenaient parfaitement.

Essai de PCB
----------

Je me suis mis à KiCAD et j’ai tracé un PCB double face 65 × 145 mm² pour l’ensemble des circuits de Pédale Vite.

J’ai repris toute l’électronique telle quelle. Les connecteurs sont identiques à ceux utilisés avec les plaques de prototypage, à part deux d’entre eux.

Je n’ai pas fait imprimer ce PCB puisque j’ai déjà un montage fonctionnel, cependant je pense que pour un nouveau montage, ça peut être un gain de temps et de budget. La plaque doit pouvoir se fixer au milieu, à la place de la carte des interrupteurs, dans le sens de la hauteur. Elle tient tout juste sous l’écran. Tous les fichiers nécessaires (sources KiCAD et exports Gerber) sont dans le dépôt Git.

Le développement se poursuit

Réducteur de bruit
----------

J’ai ajouté un réducteur de bruit. Ça faisait longtemps que je voulais incorporer un noise gate, voilà qui est fait. J’en ai même fait deux différents.

Sauf que ce ne sont pas des noise gate classiques, fonctionnant en coupant le signal en-dessous d’un certain seuil. Il s’agit plutôt de traitement dynamique multibande, à la croisée entre le noise gate et la réduction de bruit dans le domaine spectral par transformée de Fourrier et prise d’empreinte.

Ainsi Noise Bleach découpe le signal en 8 bandes différentes. Un certain seuil est soustrait au volume de chaque bande, ce qui fait que sous ce seuil, les bandes sont muettes.

Le découpage est effectué à l’aide de filtres crossover Thiele d’ordre 4. Le chaînage des filtres est effectué selon un diagramme proposé par Christofer Bustad sur la liste music-dsp. Cela faisait longtemps que j’avais ce schéma en tête et que je voulais le tester. Son énorme intérêt est de faire passer chacune des bandes par tous les filtres, soit en passe-bas, soit en passe-haut, en fonction de la position de la bande par rapport à la fréquence de coupure concernée. Ces acrobaties servent à conserver l’équilibre des phases et à pouvoir sommer toutes les bandes sans atténuer ou amplifier de fréquence. Chaque filtre contribue donc à isoler la bande avec son atténuation propre, ce qui donne un taux de réjection extrêment fort dès qu’on s’éloigne un peu des frontières de la bande. L’association de ce routage avec des filtres elliptiques (comme ceux de Thiele) est très puissante, puisque la faiblesse asymptotique de ces derniers est compensée par leur chaînage. On a donc le meilleur des deux mondes : une pente très forte à la fréquence de coupure (qu’on peut pousser jusqu’à l’exagération), et une réjection très élevée quand on va plus loin.

L’inconvénient principal vient de la topographie sérielle de la séparation des bandes. L’algorithme se parallélise donc très mal.

L’effet fonctionne remarquablement bien, il est possible de cibler certaines plages de fréquences plus que d’autre. On réduit ainsi très fortement le bruit en laissant le signal de la guitare sonner beaucoup plus longtemps qu’avec un noise gate conventionnel. Cependant l’effet occupe un temps CPU significatif, de l’ordre de 14 % d’un cœur.

J’ai donc conçu un autre réducteur, Noise Chlorine, fonctionnant sur un principe similaire. Au lieu de découper le signal en bandes contiguës, on lui prélève certaines fréquences (filtrage passe-bande d’ordre 2) pour les atténuer selon le même principe que Noise Bleach. En raison de la forme de la sélectivité des filtres, l’effet s’adresse principalement aux ronflettes qu’on pourra cibler précisément. Cependant on peut faire du filtrage à bande large en descendant la sélectivité. Le résultat est un peu moins probant mais reste très efficace et surtout consomme beaucoup moins de ressources CPU.

Optimisation de Noise Bleach
----------

Ce passage a été écrit bien plus tard (2021), mais inséré à cet endroit du texte par pertinence.

J’ai nettement amélioré le procédé de séparation des bandes. L’approche de Christofer Bustad était conceptuellement intéressante, mais pas si performante que ça. J’ai utilisé un algorithme beaucoup plus traditionnel de séparation par bandes sous forme d’arbre binaire aux caractéristiques suivantes :

Le résultat est tout à fait satisfaisant, aussi bien en termes de son (bonne séparation, bruit de calcul correct, mélange parfait moyennant un déphasage global) que de rapidité d’exécution. Je n’ai pas couché par écrit les gains de performance, mais de mémoire ils étaient très significatifs.

À noter, l’algorithme de Noise Bleach a été repris et détourné par Nicolas Lacoumette de FKFX pour en faire un effet à part entière, tout à fait intéressant et particulièrement pertinent dans le traitement des percussions (effet d’assèchement).

Du bug, du gros et du lourd
----------

J’ai passé plusieurs jours à pourchasser un bug qui m’a donné bien du fil à retordre. Quand je changeais de programme, j’avais parfois de gros craquements, en particulier sur un programme utilisant un LFO sur l’equalisation. Et parfois le son se coupait, à moins que j’enchaîne les programmes dans un autre ordre.

J’ai passé un certain temps à comprendre où était localisé le problème. En effet, passer du debugger de Visual Studio à gdb, ça fait un choc. D’autant plus que mon problème n’arrivait qu’en mode optimisé, et uniquement sur le pédalier (en ARM donc, pas sur l’émulateur Windows). Et dans ce mode, il est difficile de faire confiance au débugger : les breakpoints se déplacent, le contenu des variable est souvent indisponible et quand il l’est, il n’est absolument pas fiable… En tout cas j’ai suspecté — à tort — une variable non initialisée.

Après avoir passé un certain temps à dompter la bête et analyser le problème plus en détail, j’ai fini par me rendre compte que les craquements se produisaient dans l’équaliseur, lors d’un changement dynamique de paramètre (mais à un instant précis, le reste du temps ça marchait).

Dans cette situation, les coefficients des filtres sont mis à jour à chaque échantillon, de façon à opérer une transition aussi fluide que possible, et justement éviter les craquements ou résonances parasites. J’ai vérifié le côté théorique (correct mais sans plus) : le manque de perfection de la méthode utilisé n’était manifestement pas la cause du problème.

Après quelques tests, j’ai fini par comprendre que la valeur d’incrément pour la transition d’un des coefficient contenait une valeur abérante. Pourquoi ? C’est là que j’ai bien galéré. Au final, j’ai trouvé que le programme ne stockait pas la valeur de cet incrément après son calcul, alors que le code source le spécifiait explicitement. La valeur n’était pas stockée, sauf si j’allais la lire explicitement pour l’afficher à l’écran.

La raison est à la fois simple et pernicieuse. Il s’agit de pointer aliasing. Quand les modes d’optimisation les plus élevés sont activés, le compilateur fait des suppositions hardies sur les pointeurs afin de s’autoriser les optimisations les plus agressives et les plus efficaces possibles. En l’occurence, il suppose que deux pointeurs de types différents pointent sur des objets différents, même si les adresses sont identiques. Il peut ainsi permuter des opérations ou les supprimer selon ses besoins.

Et là, c’est ce qui se passait. J’avais un tableau de float que j’accédais tantôt directement, tantôt en passant par les vecteurs NEON ou SSE. Or mes routines de chargement et de stockage de vecteurs NEON alignés ne passait pas explicitement par les intrinsics vld1q_f32 ou vst1q_f32. Je les ai rajoutés afin d’être sûr. D’autre part les prototypes des fonctions d’emballage (portables NEON/SSE) utilisaient des void *. J’ai donc remplacé ces pointeurs sans type par des template et repoussé le reinterpret_cast de pointeur juste au niveau de l’intrinsic. Je ne sais pas laquelle de ces deux modifications a été réellement efficace, en tout cas le problème a été résolu ainsi. Donc prudence avec les vecteurs.

Projet de remplacement de la carte son

Dans la lignée des projets fous, cette fois-ci je m’attaque à du sérieux : faire moi-même la carte son du pédalier. Voici ce que j’espère en tirer :

Partant sans aucune expérience dans le domaine de la conception d’interface audio, je ne m’attend ni à un succès ni même à atteindre la qualité de l’existant. Mais au moins j’aurai essayé, et peut-être qu’après quelques itérations j’aurai quelque chose de tout à fait correct.

Premiers pas
----------

À l’heure actuelle, ce sous-projet est déjà relativement bien avancé. Il y aurait eu matière à blogguer, mais là c’est fait et je ne vais pas m’étendre sur sa genèse. La carte sera constituée ainsi :

Prototype

Après avoir dessiné un schéma, j’ai conçu un PCB pour une petite carte d’adaptation permettant de placer le CS4272 et le MK2703B sur une breadboard, pour les tout premiers essais. En effet, ces circuits intégrés ne sont pas disponible en boîtiers à pattes traversantes, mais en TSSOP (0,65 mm) pour le premier et SOIC (1,27 mm) pour le second. J’en ai également profité pour placer sur la carte les condensateurs de découplages nécessaires, puisqu’ils doivent constituer des boucles aussi courtes que possible avec les circuits auxquels ils sont rattachés. Et comme il me restait de la place, j’ai conçu également un PCB pour le redressement et la régulation de l’alimentation.

Le PCB a été envoyé à une fabrique pour impression. De manière générale, fabriquer des PCB en très petite quantité revient cher à l’unité. Je suis passé par Seeedstudio, qui dispose des prix les plus avantageux pour ce genre de commande (10 USD hors transport pour une surface inférieure à 100 × 100 mm²). Il faut bien compter plus de trois semaines, puisque le fabriquant est chinois et que je n’ai aucune envie de payer du transport au prix fort pour une livraison expresse. Si on est pressé, autant se tourner vers des fournisseurs européens, bien plus chers à la manufacture mais plus économiques au transport.

Une fois la carte et les composants reçus, j’ai commencé à monter les différents étages sur breadboard. Je les ai testés un par un, et fait quelques rectifications au passage.

La photo montre les différents étages, surlignés par des pavés colorés. Un seul canal a été réalisé pour l’entrée et pour la sortie, les autres devraient se comporter de manière similaire.

Pour l’instant la carte se comporte correctement, j’obtiens les bons niveaux aux endroits testés. La partie numérique marche, bien qu’elle n’ait été testée que de manière très sommaire. Au final, j’ai pu tester la chaîne d’un bout à l’autre, depuis le préampli micro jusqu’à la sortie en passant par les conversions ADC et DAC.

Il est difficile de tester la qualité sonore sur breadboard, puisque le circuit est très désoptimisé concernant l’élimination des parasites. J’ai donc mis au point une première version du PCB de la carte complète et je l’ai envoyé à imprimer.

Concrétisation
----------

Le circuit imprimé reçu, j’ ai pu commencer l’assemblage.

Le soudage du CS4272, puce en boîtier TSSOP, n’a pas été simple. Cela avait été aussi le cas pour l’adaptateur du prototype. En fin de compte, j’ai compris pourquoi : j’avais utilisé une empreinte standard de TSSOP pour le PCB. Ce type de composant est censé être placé par une machine et soudé au four. Les pastilles sont donc réduites à leur surface minimale. Pour une soudure manuelle, il faut étendre les pastilles, de façon à ce que la soudure excédentaire coule à l’extérieur des pattes plutôt que sous le boîtier. J’ai corrigé le schéma au cas où je devrais refaire un tirage pour une révision.

J’ai effectué les mêmes tests que pour le prototype, et tout marche comme prévu.

Pilotes

La suite m’a demandé beaucoup plus de temps et m’a fait perdre quelques cheveux. Il s’agissait de concevoir un driver (pilote) pour la carte, afin de la relier au Pi et pouvoir la contrôler au sein de mon programme.

Globalement, la carte s’interface en I2S avec son hôte. C’est elle qui est maîtresse pour les deux horloges (bits et mots). La configuration de la puce se fait par I²C. Deux signaux sont ajoutés, l’un pour réinitialiser la carte, l’autre pour choisir la fréquence d’échantillonnage, 44,1 kHz ou 48 kHz.

J’ai commencé par me lancer dans la réalisation d’un pilote Alsa. En effet, il existe un projet nommé ASoC (Alsa System on Chip), qui implémente des composantes de pilotes pour de nombreuses puces, protocoles et SoC. En principe, il n’y a plus qu’à faire l’assemblage et le paramétrage, et tout roule. Je dis bien en principe, parce que concrètement il n’existe quasiment pas de documentation, il est difficile d’apprendre par l’exemple et l’ensemble est très hermétique. Il faut aussi bien connaître le Device Tree de Linux, ce qui était complètement nouveau pour moi.

Au final, loin de tout comprendre, j’ai bricolé un overlay qui n’était pas complet mais me permettait de faire les tests nécessaires. Et là, déception : la latence n’était pas bien meilleure qu’avec la carte USB et la charge CPU s’était accrue.

J’ai donc décidé de me passer d’Alsa et de dialoguer avec la carte directement à partir du programme. Ma première tentative échoue. Elle consistait à implémenter le transfert I²S en lisant et écrivant les broches du GPIO à la main. Ça marchouillait, mais sans plus. Dans le principe ça fonctionne, mais j’avais régulièrement des craquements. En effet le thread qui s’adresse au GPIO a un timing très serré, je ne devais pas louper une seul front d’horloge, toutes les 177 ns. Mais évidemment le noyau interrompt régulièrement les threads et cela suffisait à me faire perdre la synchro, ne serait-ce que pour un échantillon. La solution aurait pu marcher en « bare metal » (sans sytème), cependant ce n’était pas la direction que j’avais choisie. Il y a peut-être des outils pour améliorer ça dans la branche Prempt-RT de Linux, mais j’avais encore des cordes à mon arc avant de chercher de ce côté.

Ma deuxième tentative s’est révélée nettement plus fructueuse : j’ai utilisé le contrôleur hardware PCM/I²S du SoC, encore une fois de manière directe, sans passer par une brique système. Par simplicité, j’ai conçu le pilote en implémentant les transferts en polling plutôt qu’en DMA.

Résultat : une latence de 3,5 à 3,8 ms avec des buffers de 64 samples, bien mieux que ce que j’avais avant. De plus, le taux d’utilisation CPU était plus stable et un peu plus de temps était disponible pour le traitement. Par curiosité, je suis descendu à 16 samples pour une latence de 1,7 ms. La consommation CPU était plus élevée mais pas encore insensée, et le système est resté stable.

Il me reste des détails à régler et à faire des tests plus intensifs avec de la charge du côté des I/O, mais pour l’instant c’est en très bonne voie. Si j’ai le courage, j’implémenterai par la suite des transferts DMA.

Concrétisation de la version 2

Avec cette nouvelle carte audio, je pense pouvoir éliminer le principal défaut de Pédale Vite : son épaisseur. En effet la carte USB était assez épaisse et ne pouvait pas tenir entre deux commutateurs au pied, d’où une place de perdue significative. D’autre part j’ai pu gagner beaucoup de surface en terme de circuits imprimés avec la condensation de toutes les cartes auxiliaires en une seule plaque.

Ajoutons aussi que je n’étais pas satisfait de l’écran précédent. J’ai cherché différentes options, différents modèles, et j’ai fini par opter pour un petit écran en HDMI. Celui-ci est en plus tactile, ce qui ne m’intéresse que moyennement, mais qui peut être toujours bon à prendre. J’ai rapidement fait quelques tests qui se sont avérés très encourageants. Son prix est certes plus élevé que son prédécesseur, mais je pense qu’on y gagne sur de nombreux plans. En particulier, la résolution est nettement plus élevée (800 × 480) et me permettra de donner à Pédale Vite une interface réellement « grapique ».

Je me suis demandé également si je ne pouvais pas remplacer le Raspberry Pi 3 par une machine plus puissante. J’ai pensé à un Odroid N2, qui a l’air vraiment bien. Sauf qu’il lui manque l’entrée audio en I2S (il n’a que la sortie à ce format). J’ai fouillé un peu les docs, le SoC implémente bien les transferts I2S dans les deux directions, mais les broches ne sont pas câblées sur le N2. Toutefois je pense qu’il doit être possible de faire passer l’entrée par la broche de contrôle du ventilateur (!) en réassignant sa fonction. À voir et à tester. La doc du SoC S922X est très superficielle voire lacunaire, ça sent la galère. Entre temps le Raspberry Pi 4 est sorti, il est d’une puissance comparable (mais moindre) à celle du N2, plus petit, dispose d’une excellente compatibilité avec le Pi 3 pour un prix très abordable. Ce sera finalement mon choix.

J’avais alors assez de nouveaux éléments pour me lancer dans une version 2 de Pédale Vite. J’ai changé au passage quelques détails comme le positionnement des connecteurs ou les boutons de navigation. Le boîtier n’est plus fait d’une seule tôle pliée mais de plusieurs panneaux. La façade principale et le panneau arrière des connecteurs sont en acier, la face avant et le capot du dessous en aluminium. Ce sont des chutes de précédents montages, tout comme le bois des montants. Des cornières en aluminium font la jonction aux angles.

Le boîtier étant réalisé, la partie logicielle a pu être intégrée quasiment telle quelle, et le pédalier semble marcher correctement. J’ai modifié les configurations des projets de façon à faire cohabiter les deux versions de Pédale Vite au sein du même dépôt Git, et que dans la mesure du possible, les mises à jour de l’un profitent automatiquement à l’autre.

En rédigeant la nouvelle documentation et en mettant au propre les schémas et PCB, j’ai détecté une petite erreur sur l’implantation des composants sur la carte son. J’ai dû déssouder et remplacer quelques résistances.

Flight case
----------

On reprend plusieurs années après… Le pédalier me suit maintenant régulièrement de répétitions en concerts. Pour le transporter, j’avais opté pour un sac à dos dont je ne me servais plus. Cependant le sac offrait une protection très mince au pédalier qui était parfois malmené. J’ai donc décidé de lui offrir un étui solide adapté au transport régulier et mouvementé, bref un flight case.

J’ai ainsi commandé les matériaux nécessaires dans une boutique spécialisée : panneaux de bois plastifiés, cornières, fermetures papillons, poignée, rivets… Le montage de la caisse a été plutôt simple, bien que la pince à rivets que j’avais empruntée m’ait claquée dans les mains. Si vous vous lancez dans ce type de projet, prenez une bonne pince, de préférence à longs manches, tenus à deux mains. Il y a bien une centaine de rivets à fixer et les pinces premier prix ne tiennent pas du tout la distance, elles sont tout juste bonnes à fixer une plaque d’immatriculation et pas vraiment plus. Sans compter qu’elles demandent plus de force et mettent les mains à rude épreuve.

L’étui est censé contenir au moins trois choses : le pédalier, la pédale d’expression et les câbles (audio et alimentation secteur). J’ai donc choisi de placer les câbles sous le pédalier, et de mettre la pédale d’expression sur la tranche pour gagner de la place. L’étui est transportable à l’aide d’une poignée, comme une valise. Par simplicité j’ai opté pour un couvercle détachable plutôt qu’attaché avec des charnières. J’ai pensé que c’était plus facile à réaliser et plus solide.

L’aménagement intérieur n’a pas été simple. Il me fallait caler les différents éléments avec de la mousse de façon à amortir les chocs d’une part, et les bloquer dans toutes les directions d’autre part. J’ai pris une plaque de mousse dense en plastazote 45 kg/m³, qui n’est rien d’autre que du polyéthylène (PE).

Le problème du PE, c’est que ça se colle très mal. La plupart des colles du commerce indiquent qu’elles sont inadaptées à ce type de plastique. J’ai utilisé une bombe de colle de type néoprène. J’ai dû faire quelques essais, et finalement la meilleure façon de s’y prendre, c’est de badigeonner les deux surfaces, attendre une dizaine de minutes que ça prenne, et assembler les deux parties. L’assemblage tient alors immédiatement, il ne faut pas se tromper en positionnant les deux pièces.

Le plastazote se coupe facilement — et surtout proprement — aux ciseaux. Éviter d’utiliser un cutter, ça fait des peluches assez dégueu. Cependant il est difficile de tracer le contour des pièces sur de la mousse noire. J’ai commencé par faire une légère entaille à la règle et au cutter, en positionnant la lame du cutter le plus à plat possible. La raignure permet alors de guider la découpe finale aux ciseaux.

Pour coller deux pièces de mousse entre elles, par exemple pour faire une épaisseur renforcée, on peut les chauffer plutôt que d’utiliser de la colle. Il faut y aller progressivement avec un pistolet à air chaud. À environ 200 °C, ça ramollit instantanément. On chauffe une petite surface des deux parties et on les plaque ensemble. Au bout de 2–3 secondes, la soudure est effective. On continue de cette manière sur toute la longueur de la pièce.

Je ne suis pas très doué avec la colle, j’ai laissé des bavures partout !

J’ai pris des chutes de liteaux pour surélever Pédale Vite et laisser de la place pour les câbles. Ils ont été rivetés au fond de la caisse. J’ai tapissé le reste du fond avec de la mousse verte fine qui servait d’emballage à mes fournitures (manifestement du plastazote léger). On réutilise tout ! Ça évite aux jacks de faire du bruit lors des déplacements.

Ça n’apparaît pas sur les photos, mais j’ai aussi confectionné avec de la mousse une cale amovible permettant de bloquer la partie avant (la plus fine) du pédalier. Il me reste encore un peu de place au-dessus du pédalier si je veux y stocker d’autres câbles ou une multi-prise par exemple.

Au final l’étui convient très bien. Placer ou extraire la partie gauche du pédalier est un peu difficile (pas assez de place pour glisser les doigts), mais c’est un inconvénient vraiment mineur. L’ensemble est un peu lourd, l’étui seul fait dans les 5 kg, mais c’est le prix tout à fait normal de la robustesse.

Migration sur Raspberry Pi 5

Fin 2023 sort la version 5 du Raspberry Pi. Celle-ci est nettement plus rapide que la 4e itération et semble constituer une mise à jour tout à fait pertinente pour Pédale Vite.

Je pensais dans un premier temps pouvoir substituer la version 5 à la 4 quasiment sans rien faire comme ça avait été le cas pour passer de la 3 à la 4. Oui mais voilà : le hardware a beaucoup changé et s’accompagne d’une évolution significative du système. Plus rien ne marche.

J’ai pu cerner assez rapidement les problèmes :

L’écran

Finalement c’était la partie la plus simple. L’écran SPI ne fonctionnait pas tel que configuré selon la documentation publiée par Waveshare. Le driver précédemment utilisé est devenu obsolète, et il a fallu passer par une méthode plus moderne, le driver VC4. Le faire marcher pour afficher la console a demandé quelques recherches et échanges avec Waveshare, mais rien d’insurmontable.

La grosse différence, c’est que ce driver n’expose qu’une version brute de l’écran. Nativement, il est en mode portrait en RGB 16 bits. Le framebuffer est lui aussi à ce format, il a donc fallu changer le code d’affichage de Pédale Vite pour sortir en RGB16 tout en effectuant une rotation du contenu affiché.

Les GPIO

La documentation du RP1 est suffisamment étoffée pour pouvoir adresser les GPIO directement. Cependant n’ayant pas besoin de performances fulgurantes pour lire les boutons ou commander quelques signaux, j’ai décidé d’utiliser l’interface officielle de Linux pour manipuler les GPIO via de simples appels ioctl. Évidemment on perd l’accès à toutes les fonctionnalités spéciales proposées par le RP1, mais je n’en ai pas besoin ici et je préfère dans ce cas privilégier les fonctions système officiellement supportées.

Le PWM

Les LED de Pédale Vite sont commandées par des GPIO modulés par PWM afin d’en faire varier la luminosité. Le Pi a deux GPIO permettant de faire directement du PWM en hardware, mais ceux-ci sont en nombre insuffisant et surtout ne sont pas reliés aux broches physiques connectées aux LED.

Sur les modèles précédents du Pi, cette modulation PWM était générée artificiellement par un pilotage du GPIO par le DMA. Celui-ci lisait en mémoire une forme d’onde donnant la largeur d’impulsion commandée.

En l’absence de fiche technique officielle pour le DMA du RP1, j’ai dû me résoudre à générer le PWM en software. J’ai donc un thread qui tourne exclusivement pour piloter les broches soumises à PWM. J’ai créé une petite bibliothèque permettant de gérer facilement plusieurs canaux PWM et de se synchroniser aussi précisément que possible pour basculer les états aux bons moments. Une modulation delta-sigma permet de corriger en direct les inévitables décalages temporels liés au scheduler système et d’obtenir une luminosité aussi constante et précise que possible.

Cette solution software reste cependant un substitut de première nécessité plutôt qu’une implémentation économe en ressources et définitive.

La carte son

J’avais plusieurs solutions pour piloter ma carte son maison. La plus simple, que j’avais déjà testée jadis, c’est de réutiliser et adapter un driver ASoC existant en créant un nouvel overlay. Cela marche bien, avec l’inconvénient d’une latence importante. En effet, ALSA est construit de façon à pouvoir ouvrir un flux audio en entrée ou en sortie à n’importe quel moment et les gérer indépendamment. Le full duplex n’est qu’un cas parmi d’autres qui n’est pas géré dans sa spécificité.

A contrario, le driver que j’avais écrit à l’origine utilisait le fait que les flux d’entrée et de sortie sont ouverts et fermés simultanément, et qu’ils restent parfaitement synchronisés. Cela m’avait permis de réduire la latence entre l’entrée et la sortie au strict minimum, ce qui est important pour un effet audio temps-réel. J’ai donc écarté une nouvelle fois cette solution pour écrire un driver à part entière, la gardant quand même sous le coude en cas d’échec.

La difficulté vient du fait que ni l’interface I2S, ni le DMA ne sont documentés. J’ai donc rétro-ingénieuré l’interface I2S à partir des drivers Linux. Pour faire mes tests, j’ai mis en œuvre un simulateur de codec I2S utilisant des broches libres du GPIO. Ainsi j’ai pu tester les communication entre l’interface I2S du RP1 et mon simulateur tout en maîtrisant l’horloge qui les cadence. À la fin, j’ai consigné mes trouvailles dans ce document.

Le DMA est d’un autre tonneau, beaucoup plus complexe. J’ai donc remis son analyse à plus tard. Le driver que j’ai développé fonctionne ainsi en polling, un thread spécifique haute priorité étant dédié à l’approvisionnement et à la récupération des données audio à travers la FIFO de l’interface I2S. Pour tester la qualité du driver sans tout brancher dans le boîtier de Pédale Vite, j’ai ressorti un vieux circuit que j’avais employé lors de la conception de la version 2 de Pédale Vite, il s’agit d’un codec CS4272 avec son horloge.

La solution est loin d’être idéale et probablement sensible aux caprices du scheduler, mais elle fonctionne de manière stable et on pourra y intégrer le DMA plus tard.

Reste à faire

Pédale Vite sous Pi 5 est dorénavant tout à fait fonctionnel. Cependant, il faudrait pouvoir accéder à la documentation du DMA du RP1 pour achever l’implémentation. Je me chargerai probablement d’en faire la rétro-ingénieurie dans les mois qui viennent, sachant que la tâche s’annonce difficile et que ma motivation n’est peut-être pas au niveau. On verra bien…

En tout cas la partie logicielle est toujours 100 % compatible avec la toute première version de Pédale Vite (Pi 3, carte audio USB, écran SPI 128×64 × 1 bit…), qui me sert de backup.

 

 
[Home] [Productions] [Misc] Website by Laurent de Soras, 2003–2024