🛠 Contrôleur MIDI complet : encodeurs, multiplexage 74HC4051 et MIDIx16

Teensy 3.2 · avance · Schéma : IMG-teensy-32-avance-8-teensy32-controleur-midi-diy.svg — boîtier DIY ouvert : Teensy 3.2 au centre, 8 encodeurs rotatifs et 16 potentiomètres multiplexés via deux puces 74HC4051 (broches A/B/S annotées), nappe USB partant vers un ordinateur affichant une DAW avec 16 câbles MIDI ; en médaillon, le délai de stabilisation ≥ 50 µs après changement de canal du multiplexeur.

Objectives

Move from the 3 buttons in the beginner tutorial to a real DIY MIDI controller — the historical specialty of the Teensy 3.2: buttons, rotary encoders, and rows of potentiometers, multiplexed to save pins, published over 16 virtual MIDI cables (MIDIx16). You will use the MIDIcontroller library (Josh Nishikawa), published for this use case, and you will address the two documented pitfalls: crosstalk in multiplexed potentiometers and USB buffer overflow.

Hardware

Architecture

The 74HC4051 pitfall: letting the signal stabilize

When changing the selected channel of a 74HC4051 multiplexer, the analog input needs a settling time of at least 50 µs — more if capacitors are present — otherwise the previous channel continues to influence the reading: potentiometers "read into each other" (PJRC forum thread "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
}

Sending 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 entrees, envois CC/Note ...
  while (usbMIDI.read) { }   // draine les messages entrants
}

Compatibility breaks to know (Teensyduino ≥ 1.41)

Expected verification

In the DAW: the Teensy appears with 16 MIDI cables; turn encoder 1 → the corresponding CC moves on the chosen cable; move a multiplexed potentiometer → its value follows cleanly, without neighbors jumping (proof that the 60 µs settling time is doing its job). Let the DAW send MIDI clock for 10 minutes: without the usbMIDI.read drain, the controller freezes — with it, it holds.

Common errors

Other tutorials for this board

Code examples for this board

← Back to the board 🛠 All tutorials