🛠 Contrôleur MIDI complet : encodeurs, multiplexage 74HC4051 et MIDIx16
Objectifs
Passer des 3 boutons du tutoriel débutant à un vrai contrôleur MIDI DIY — la spécialité historique de la Teensy 3.2 : boutons, encodeurs rotatifs et rangées de potentiomètrès, multiplexés pour économiser les broches, publiés sur les 16 câbles MIDI virtuels (MIDIx16). Vous utiliserez la bibliothèque MIDIcontroller (Josh Nishikawa), publiée pour ce cas d'usage, et vous traiterez les deux pièges documentés : le crosstalk des potentiomètrès multiplexés et le bourrage des buffers USB.
Matériel
- 1 Teensy 3.2
- 8 encodeurs rotatifs avec bouton poussoir (quadrature + switch)
- 16 potentiomètrès 10 kΩ multiplexés par 2 puces 74HC4051 (8 entrées analogiques chacune → 3 broches d'adresse par puce)
- 16 boutons poussoirs (matrice ou directes selon les broches restantes)
- Câble USB ; DAW ou moniteur MIDI pour valider
Architecture
- USB Type : MIDIx16 (Outils > USB Type) : 16 câbles MIDI virtuels, jusqu'à 16 messages par paquet USB — chaque section du contrôleur peut vivre sur son câble.
- Bibliothèque MIDIcontroller (<https://github.com/joshnishikawa/MIDIcontroller>) : gère boutons, encodeurs, aftertouch, et le routage canal/câble ; Yann Seznec a publié son code de contrôleur MIDI open source sur le forum PJRC — une référence de structure (scan des boutons, lecture des encodeurs, envois CC).
- Règle du drain : même en émission pure, appelez
while (usbMIDI.read) { }à chaque tour de loop — sinon les buffers USB se remplissent et le contrôleur se fige (Problème n°10 de la page USB MIDI).
Le piège du 74HC4051 : laisser le signal se stabiliser
Quand on change le canal sélectionné d'un multiplexeur 74HC4051, l'entrée analogique a besoin d'un délai d'établissement (settling) d'au moins 50 µs — davantage si des condensateurs sont présents — sinon le canal précédent continue d'influencer la lecture : les potentiomètrès « se lisent entre eux » (thread forum PJRC « Potentiometers affecting each others when connected to 74HC4051 »).
// Squelette de lecture multiplexee avec settling time.
const int ADDR[] = {A0, A1, A2}; // adresses du 4051
void selectCanal(uint8_t n) {
for (int i = 0; i < 3; i++) digitalWrite(ADDR[i], (n >> i) & 1);
delayMicroseconds(60); // >= 50 us de stabilisation (forum PJRC)
}
uint16_t lirePot(uint8_t canal) {
selectCanal(canal);
return analogRead(A3); // sortie commune du 4051 -> A3
}
Envoi des messages
#include <MIDIcontroller.h>
// Exemple de declaration (voir README de la biblio pour la signature exacte) :
// MIDIcontroller ctl = MIDIcontroller(NUM_BUTTONS, NUM_SLIDERS, ...);
// A chaque tour de loop :
// ctl.encode(encodeurPin, canal, numeroCC);
// ctl.button(boutonPin, canal, numeroNote);
// ctl.slider(canalMux, canal, numeroCC);
// puis TOUJOURS :
void loop {
// ... scan des entrées, envois CC/Note ...
while (usbMIDI.read) { } // draine les messages entrants
}
Ruptures de compatibilité à connaître (Teensyduino ≥ 1.41)
- La plage du pitch bend est passée de 0…16383 à +8191…−8192 ; les valeurs de
getTypeont changé — les vieux sketches de contrôleurs doivent être adaptés. - MIDI-OX sous Windows : configuration « input only » spécifique nécessaire (section « Teensyduino 1.40 & Earlier » de la page PJRC).
Vérification attendue
Dans la DAW : la Teensy apparaît avec 16 câbles MIDI ; tournez l'encodeur 1 → le CC correspondant bouge sur le câble choisi ; bougez un potentiomètre multiplexé → sa valeur suit proprement, sans que les voisins sautent (preuve que le settling time de 60 µs fait son travail). Laissez la DAW renvoyer de l'horloge MIDI pendant 10 minutes : sans le drain usbMIDI.read, le contrôleur se fige — avec, il tient.
Erreurs fréquentes
- Zapper le delayMicroseconds après changement de canal du 4051 : les canaux se lisent mutuellement — le symptôme est exactement « mes potentiomètrès s'influencent entre eux ».
- Mettre des condensateurs d'anti-parasite sur chaque pot sans augmenter le settling time : plus de capacité = plus de délai nécessaire.
- Oublier le drain usbMIDI.read : plantage après quelques minutes, souvent attribué à tort à l'alimentation USB.
- Sélectionner MIDI simple au lieu de MIDIx16 : la DAW ne voit qu'un câble et les sections se marchent dessus.
- Recopier un vieux tuto pré-1.41 : pitch bend et getType inversés donnent des contrôleurs « fous » sur les modernes.
- Dépassement de broches : les 34 E/S de la 3.2 fondent vite avec 8 encodeurs en quadrature — d'où le multiplexage (ou un shift-register type 74HC165 pour les boutons).
Autres tutoriels pour cette carte
- Premiers pas sur la Teensy 3.2 : Teensyduino, HalfKay et premier Blink
- Broches, ADC 13 bits, DAC 12 bits et PWM : dompter les E/S de la Teensy 3.2
- Un instrument MIDI USB en 10 minutes : Bounce, boutons et règle d'or du drain
- Audio Shield SGTL5000 : boucle stéréo 44,1 kHz et outil de conception graphique
- OctoWS2811 : piloter 8 rubans WS2812 en parallèle par DMA (presque zéro CPU)
- Timers matériels, interruptions imbriquées et FASTRUN : la vitesse Cortex-M4
Exemples de code pour cette carte
clignotante.inoArduinotouche-capacitive.inoArduinoanalogique-12-bits.inoArduinomidi-piano.inoArduinopwm-respiration.inoArduinoservo-angle.inoArduino