Unopad : contrôleur MIDI Arduino fluide pour Ableton Live
Composants et fournitures
| Arduino UNO | × | 1 |
| Interrupteurs poussoirs éclairés série APEM A01 | × | 9 |
| Fils de liaison (génériques) | × | 1 |
Outils et machines nécessaires
- Fer à souder (générique) – optionnel
Applications et services en ligne
- loopMIDI
- Hairless MIDI↔Serial Bridge
- Ableton Live 10 (version d'essai)
À propos de ce projet
Résumé
La plupart des tutoriels et projets pour contrôleurs MIDI se concentrent uniquement sur la partie Arduino, mais peu expliquent comment l'utiliser dans un DAW. Je voulais créer un tutoriel regroupant tout au même endroit. Avec ce projet, je souhaite aider les débutants à mieux comprendre le processus de création et d'utilisation d'un contrôleur, et j'espère qu'il sera utile à quelqu'un.
Je voulais faire un contrôleur MIDI depuis longtemps et je l'ai enfin réalisé ; je partage maintenant le projet avec vous. J'ai utilisé un Arduino Uno qui ne peut pas envoyer de messages MIDI via USB, donc des programmes spéciaux étaient nécessaires (expliqués plus loin).
Les sections suivantes décrivent le circuit électrique, le code Arduino, ainsi que la connexion à un ordinateur et à un DAW, ici Ableton.
Circuit
C'est un circuit très simple. J'ai utilisé 9 boutons poussoirs, mais pas en matrice, car je voulais la possibilité d'appuyer sur plusieurs boutons simultanément (c'est plus facile et j'ai des broches numériques inutilisées – j'en utilise 9, une matrice en aurait nécessité 6).
Bouton 3 → D2
Bouton 2 → D3
Bouton 1 → D4
Bouton 6 → D5
Bouton 5 → D6
Bouton 4 → D7
Bouton 9 → D8
Bouton 8 → D9
Bouton 7 → D10
Mappages MIDI
J'ai défini 9 notes MIDI, de 36 à 45, avec NOTE_ON et NOTE_OFF.
Ce tutoriel MIDI vous aidera à comprendre comment utiliser le langage MIDI pour contrôler tout appareil utilisant le protocole MIDI.
#define NOTE_UN 36
#define NOTE_DEUX 37
// Définir toutes les notes ici.
#define NOTE_ON_CMD 0x90
#define NOTE_OFF_CMD 0x80
#define MAX_MIDI_VELOCITY 127
MIDI via USB
Comme l'Arduino Uno ne peut pas envoyer de notes MIDI au DAW par lui-même, nous devons utiliser deux programmes supplémentaires : LoopMIDI et Hairless MIDI↔Serial Bridge.
Avec LoopMIDI, nous créons un port MIDI virtuel que nous pouvons utiliser dans Hairless MIDI pour connecter avec le port série de l'Arduino.
Explication du code
J'ai créé une classe Button que j'utilise ainsi :
int NOMBRE_BOUTONS = 9;
Button Bouton1(4, NOTE_UN);
Button Bouton2(3, NOTE_DEUX);
Button Bouton3(2, NOTE_TROIS);
Button Bouton4(7, NOTE_QUATRE);
Button Bouton5(6, NOTE_CINQ);
Button Bouton6(5, NOTE_SIX);
Button Bouton7(10, NOTE_SEPT);
Button Bouton8(9, NOTE_HUIT);
Button Bouton9(8, NOTE_NEUF);
Button *Boutons[] {&Bouton1,&Bouton2,&Bouton3,&Bouton4,&Bouton5,&Bouton6,&Bouton7,&Bouton8,&Bouton9};
Pour en savoir plus sur l'implémentation des boutons, voir Buttons.cpp.
Comme nous n'utilisons aucune résistance et connectons simplement le bouton à la broche numérique et à la masse, nous utilisons INPUT_PULLUP au lieu de INPUT.
// Buttons.cpp
pinMode(_pin, INPUT_PULLUP);
La seule subtilité est qu'on ne recherche pas un signal HIGH comme on pourrait le supposer – le bouton renvoie LOW (0) quand il est pressé.
// Le bouton est pressé
if (state == 0) {
midiNoteOn(Boutons[i]->Note, 127);
}
// Le bouton n'est pas pressé
if (state == 1) {
}
Cela signifie aussi que l'état initial du bouton est 1, pas 0.
// Buttons.cpp
_state = 1;
Chaque message NOTE ON nécessite son message NOTE OFF correspondant. Quand le bouton est pressé, il envoie un message NOTE_ON. Quand il est relâché, il envoie NOTE_OFF, donc en plus de l'état initial, j'ai ajouté le dernier état mémorisé dans le code.
// Buttons.cpp
_lastState = 1;
Nous n'envoyons des messages MIDI que si l'état actuel diffère du dernier état.
// Buttons.cpp
if(state != _lastState) {
//....
}
Utilisez ces deux fonctions pour envoyer des messages MIDI. Les paramètres sont note et midiVelocity (j'ai utilisé la vélocité maximale).
void midiNoteOn(byte note, byte midiVelocity) {
Serial.write(NOTE_ON_CMD);
Serial.write(note);
Serial.write(midiVelocity);
}
void midiNoteOff(byte note, byte midiVelocity) {
Serial.write(NOTE_OFF_CMD);
Serial.write(note);
Serial.write(midiVelocity);
}
J'ai mis la logique du programme dans la fonction updateButtons.
void updateButtons() {
for (int i = 0; i < NOMBRE_BOUTONS; i++) {
int state = Boutons[i]->getButtonState();
// Le bouton est pressé
if (state == 0) {
midiNoteOn(Boutons[i]->Note, 127);
}
// Le bouton n'est pas pressé
if (state == 1) {
midiNoteOff(Boutons[i]->Note, 0);
}
}
}
La fonction est appelée dans la méthode loop.
void loop() {
if (NOMBRE_BOUTONS != 0) updateButtons();
}
Utiliser votre contrôleur avec un DAW (Ableton Live)
En tant que débutant dans l'utilisation des DAW, je ne savais pas comment connecter quoi que ce soit. Quand j'ai connecté mon Korg Nanokey, Ableton l'a reconnu tout seul et je pouvais l'utiliser immédiatement. Ce n'était bien sûr pas le cas avec le contrôleur Arduino, car ce n'est pas un périphérique HID et le PC le reconnaît toujours comme un Arduino.
Je vais vous montrer ici comment connecter et utiliser votre contrôleur MIDI Arduino dans Ableton Live 10.
Connexion avec Ableton
- Ouvrez loopMIDI et créez un nouveau port MIDI virtuel comme sur les images suivantes.
- Ouvrez hairless-midiserial et assignez le port série, MIDI Out et MIDI In comme sur les images suivantes. Pour le port série, choisissez le port de l'Arduino Uno, et pour MIDI In et Out, utilisez le port MIDI virtuel créé à l'étape précédente.
- Réglez le baudrate sur la même valeur que dans votre sketch Arduino. Allez dans Fichier > Préférences, et là vous devez régler le baudrate.
- Si tout est bien fait, vous pourrez déboguer les messages MIDI envoyés par le contrôleur. Appuyez sur un bouton du contrôleur et vérifiez les messages MIDI entrants dans Hairless MIDI.
Ne fermez pas Hairless MIDI !
- Ouvrez Ableton Live, allez dans l'onglet Options, puis Préférences. L'onglet Link MIDI devrait ressembler à cet exemple.
- Pour vérifier que tout est bien connecté et qu'Ableton lit les messages MIDI, regardez dans le coin supérieur droit d'Ableton. La case du haut devrait clignoter quand un bouton du contrôleur est pressé, comme montré dans l'exemple suivant.
Le contrôleur est prêt à l'emploi !
Utiliser le contrôleur comme Drum Rack ou Clavier
Sélectionnez une piste MIDI. Dans la section Monitor, choisissez In au lieu de Auto, et dans MIDI to choisissez votre sortie audio. Vous devriez entendre votre clavier maintenant. La même chose doit être faite pour le Drum Rack.
Mon projet fini
J'ai utilisé une vieille boîte d'enceinte pour ce projet et du plastique trouvé à la maison. J'ai découpé les deux plaques de plastique aux dimensions du boîtier et percé des trous pour les boutons et une LED que j'ajouterai plus tard.
J'ai aussi une autre vieille enceinte avec le même boîtier que j'utiliserai pour un autre contrôleur MIDI, cette fois avec des potentiomètres et des joysticks.
À faire
- Appui long sur un bouton pour basculer en mode CC (Control Change).
Code
- MidiDrumPad.ino
- Buttons.cpp
- Buttons.h
MidiDrumPad.ino
#include "Buttons.h"
//------Notes-------------
#define NOTE_UN 36
#define NOTE_DEUX 37
#define NOTE_TROIS 38
#define NOTE_QUATRE 39
#define NOTE_CINQ 40
#define NOTE_SIX 41
#define NOTE_SEPT 42
#define NOTE_HUIT 43
#define NOTE_NEUF 44
#define NOTE_ON_CMD 0x90
#define NOTE_OFF_CMD 0x80
#define MAX_MIDI_VELOCITY 127
//------------------------
int NOMBRE_BOUTONS = 9;
Button Bouton1(4, NOTE_UN);
Button Bouton2(3, NOTE_DEUX);
Button Bouton3(2, NOTE_TROIS);
Button Bouton4(7, NOTE_QUATRE);
Button Bouton5(6, NOTE_CINQ);
Button Bouton6(5, NOTE_SIX);
Button Bouton7(10, NOTE_SEPT);
Button Bouton8(9, NOTE_HUIT);
Button Bouton9(8, NOTE_NEUF);
Button *Boutons[] {&Bouton1,&Bouton2,&Bouton3,&Bouton4,&Bouton5,&Bouton6,&Bouton7,&Bouton8,&Bouton9};
int red_light_pin = 11;
int green_light_pin = 12;
int blue_light_pin = 13;
void setup() {
Serial.begin(9600);
}
void loop() {
if (NOMBRE_BOUTONS != 0) updateButtons();
}
void updateButtons() {
for (int i = 0; i < NOMBRE_BOUTONS; i++) {
int state = Boutons[i]->getButtonState();
// Le bouton est pressé
if (state == 0) {
midiNoteOn(Boutons[i]->Note, 127);
}
// Le bouton n'est pas pressé
if (state == 1) {
midiNoteOff(Boutons[i]->Note, 0);
}
}
}
void RGB_color(int red_light_value, int green_light_value, int blue_light_value) {
analogWrite(red_light_pin, red_light_value);
analogWrite(green_light_pin, green_light_value);
analogWrite(blue_light_pin, blue_light_value);
}
// Envoi note MIDI ON
void midiNoteOn(byte note, byte midiVelocity) {
Serial.write(NOTE_ON_CMD);
Serial.write(note);
Serial.write(midiVelocity);
}
// Envoi note MIDI OFF
void midiNoteOff(byte note, byte midiVelocity) {
Serial.write(NOTE_OFF_CMD);
Serial.write(note);
Serial.write(midiVelocity);
}
Buttons.cpp
#include "Buttons.h"
Button::Button(int pin, short note) {
_pin = pin;
pinMode(_pin, INPUT_PULLUP);
_state = 1;
_lastState = 1;
Note = note;
}
int Button::getButtonState() {
int returnValue = -1;
int state = digitalRead(_pin);
if (state == _lastState) return 5;
if (state != _lastState) {
if (state == 0) {
returnValue = 0;
} else {
returnValue = 1;
}
}
_lastState = state;
return returnValue;
}
Buttons.h
#ifndef Buttons_h
#define Buttons_h
#include
// Button (Numéro de broche, Numéro de note)
class Button {
public:
Button(int pin, short note);
int getButtonState();
int Note;
private:
int _pin;
short _note;
int _state;
int _lastState;
};
#endif
Vous pouvez télécharger le code depuis mon GitHub :
https://github.com/sadreactonly/MidiDrumpad
Schémas
Processus de fabrication
- Contrôler la Luminosité de LEDs par PWM avec un Bouton Poussoir sur Arduino Mega
- Construire un jeu gyroscopique temps réel avec Arduino Nano et capteur MPU-6050
- Projet capteur DHT11 température/humidité avec indicateurs LED et buzzer piézo
- Construire un Iron Man animé avec Arduino : capteurs, sons et relais
- Capteur d'obstacle IR simple avec Arduino — LED IR + Photodiode
- Find Me : Localisateur d'objets intelligent avec Arduino et Bluetooth
- Contrôleur d'humidificateur DIY avec Arduino et relais – Installation haute tension sécurisée
- Construire un Cube LED 4x4x4 avec Arduino Uno et 1Sheeld – Projet LED Interactif
- Volant Joystick Arduino Personnalisé pour Jeux Vidéo