USB-MIDI-Adapter für Arduino Micro / Leonardo – Komplettes Bauteil-Kit & Code
Komponenten & Zubehör
| Bauteil | Menge | Hinweise |
|---|---|---|
| Arduino Micro (oder Leonardo) | 1 | ATmega32u4 – nativer USB (HID/MIDI) |
| 6N137 Optokoppler (High-Speed) | 1 | Für MIDI-In (galvanische Trennung) |
| 1N4148 Schnellschalt-Diode | 1 | Schutzdiode am Optokoppler-Eingang |
| Keramikkondensator 100 nF | 1 | Entkopplung am Optokoppler |
| Widerstand 220 Ω | 3 | LED, MIDI-Out Treiber, Pull-up |
| Widerstand 10 kΩ | 1 | Pull-up am Optokoppler-Ausgang |
| Widerstand 470 Ω | 1 | MIDI-Out Strombegrenzung |
| LED (Status/Power) | 1 | |
| LED-Halter (für Gehäusefront) | 1 | |
| DIN-5-Buchse (MIDI In / Out) | 2 | Mit Schraubbefestigung |
| Kunststoffgehäuse (passend für PCB & Buchsen) | 1 | |
| Lochrasterplatine / PCB | 1 | ca. 5×7 cm |
| PCB-Abstandshalter (Nylon, Schrauben) | 1 Set |
Software
- Arduino IDE
- Bibliothek: Control Surface (von tttapa) – professionelle MIDI/USB-Implementierung
Projektbeschreibung
Der Autor suchte eine zuverlässige USB-MIDI-Schnittstelle für seine Synthesizer (u. a. Roland D-50). Existierende DIY-Lösungen litten unter unvollständiger MIDI-Implementierung (SysEx, Timing, Running Status). Er entwickelte daher eine eigene Hardware auf Basis des ATmega32u4 (Arduino Micro/Leonardo) und nutzt die Control Surface Library, die das komplette MIDI-Protokoll (Channel Voice, System Exclusive, Real-Time, Running Status) korrekt abbildet.
Hardware-Architektur
- MIDI In: Optokoppler 6N137 (schnell, 31250 Baud) mit 1N4148 als Eingangs-Schutz (Richtungsumkehr). Ausgang per 10 kΩ Pull-up an Arduino
Serial1 RX (Pin 0). - MIDI Out: Arduino
Serial1 TX (Pin 1)→ 470 Ω → MIDI-Out Buchse Pin 5; Buchse Pin 4 an 5 V; Pin 2 an GND (Standard-MIDI-Verdrahtung). - USB: Native USB des 32u4 → PC erkennt Gerät als „Arduino Leonardo“ (oder benutzerdefinierten Namen via
boards.txt). - Status-LED an Pin 10 (PWM-fähig).
Wichtig: Nur MIDI-Out Pin 2 wird geerdet – das vermeidet Ground-Loops. Pin-Belegung der DIN-Buchsen genau prüfen (Ansicht: Vorder-/Rückseite verwechseln leicht).
Software-Architektur (Control Surface)
Die Bibliothek stellt USBMIDI_Interface und HardwareSerialMIDI_Interface bereit. Ein MIDI_PipeFactory verbindet beide bidirektional. Zusätzliche Controller (Potis, Pedale, Taster) lassen sich per CCPotentiometer, CCButton etc. einfach hinzufügen.
Der Autor nutzt einen Callback, um fehlerhafte „All Notes Off“ (Controller 0x7B) seines Roland D-50 zu filtern – moderne VSTs interpretieren dies als hartes Abschalten aller Sustain-Noten. Der Callback prüft jedes Channel-Message und verwirft 0xB0/0x7B. Auch „Note On mit Velocity 0“ wird in „Note Off“ umgewandelt.
SysEx-Puffer-Problem (Workaround)
Control Surface < 2.x begrenzt SysEx auf 128 Byte. Für große SysEx (D-50 Librarian) muss im Library-Code angepasst werden:
src/MIDI_Parsers/MIDI_MessageTypes.hpp:uint8_t length;→size_t length;src/Settings/Settings.hpp:constexpr size_t SYSEX_BUFFER_SIZE = 128;→320(oder mehr)
Fix kommt mit Control Surface 2.x.
Arduino-Code – Variante 1: Basis USB↔MIDI Bridge
/* USB MIDI Adapter – Basic Bridge
* Library: Control Surface (https://github.com/tttapa/Control-Surface)
* SysEx-Buffer-Workaround siehe Projekthinweise.
*/
#include
USBMIDI_Interface midiusb;
HardwareSerialMIDI_Interface midiser = {Serial1, MIDI_BAUD};
MIDI_PipeFactory<5> pipes;
const int ledPin = 10;
void setup() {
Serial.begin(115200);
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, HIGH);
// USB <-> Serial1 bidirektional
midiusb >> pipes >> midiser;
midiser >> pipes >> midiusb;
// Control Surface (z. B. extra Potis) nur an USB
Control_Surface >> pipes >> midiusb;
midiser >> pipes >> Control_Surface;
midiusb >> pipes >> Control_Surface;
Control_Surface.begin();
}
void loop() {
Control_Surface.loop();
}
Arduino-Code – Variante 2: Mit „All Notes Off“ Filter & Note-On(0)→Note-Off
/* USB MIDI Adapter – mit Roland D-50 Fix */
#include
USBMIDI_Interface midiusb;
HardwareSerialMIDI_Interface midiser = {Serial1, MIDI_BAUD};
MIDI_PipeFactory<4> pipes;
const int ledPin = 10;
// Custom Callback: filtert 0xB0 0x7B (All Notes Off) & wandelt NoteOn(vel=0) -> NoteOff
struct MyMIDI_Callbacks : MIDI_Callbacks {
void onChannelMessage(Parsing_MIDI_Interface& midi) override {
ChannelMessage cm = midi.getChannelMessage();
if (cm.header == 0xB0 && cm.data1 == 0x7B) return; // All Notes Off ignorieren
if (cm.header == 0x90 && cm.data2 == 0x00) cm.header = 0x80; // NoteOn(0) -> NoteOff
midiusb.send(cm);
}
void onSysExMessage(Parsing_MIDI_Interface& midi) override {
midiusb.send(midi.getSysExMessage());
}
void onRealTimeMessage(Parsing_MIDI_Interface& midi) override {
midiusb.send(midi.getRealTimeMessage());
}
} callbacks;
void setup() {
Serial.begin(115200);
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, HIGH);
midiusb >> pipes >> midiser;
Control_Surface >> pipes >> midiusb;
midiser >> pipes >> Control_Surface;
midiusb >> pipes >> Control_Surface;
Control_Surface.begin();
midiser.setCallbacks(callbacks);
}
void loop() {
Control_Surface.loop();
}
Schaltplan & PCB
Fritzing-Datei: usb_midi_interface_twiE32gvR3.fzz (nur Schaltplan-Tab befüllt). Der Schaltplan zeigt:
- 6N137: Pin 1 (VCC), 4 (GND), 2 (Anode via 1N4148 von MIDI-In Pin 4), 3 (Kathode an MIDI-In Pin 5), 6 (Ausgang → 10k Pull-up → Arduino RX), 7 (GND), 8 (VCC).
- MIDI-Out: Arduino TX → 470 Ω → DIN Pin 5; DIN Pin 4 → 5 V; DIN Pin 2 → GND.
- LED an Pin 10 (220 Ω → GND).
- 100 nF zwischen VCC/GND am 6N137.
Tipps & Troubleshooting
- Keine MIDI-Kommunikation? → Prüfen, ob MIDI-In Pin 4/5 nicht vertauscht sind (Buchsen-Ansicht beachten!).
- Gerätename ändern: In Arduino IDE
hardware/arduino/avr/boards.txt→leonardo.build.usb_product="Dein Name"(Admin-Rechte nötig, nach Upload zurückändern). - Andere MIDI-Libs (z. B.
MIDIUSB,ArduinoMIDILibrary) funktionieren ebenfalls – Hardware ist generisch.
Herstellungsprozess
- Smart Thirst Alert: DIY Pflanzen-Alarm für optimale Bewässerung
- Italienische Word Clock mit Arduino Nano, NeoPixel, LCD & RTC
- Arduino-Pins sparen: 4x3 Tastenfeld mit nur 3 Anschlüssen verbinden
- Kompaktes MIDI-Schlagzeug mit 3D-Druck selbst bauen
- Zuverlässiger Sigfox-kWh-Zähler mit Arduino MKR Fox 1200
- Bluetooth-Temperaturmonitor mit Arduino Nano
- DIY Auto-Ranging Kapazitätsmesser (10 pF – 10 µF) – Einfacher Arduino-Nano-Bau
- Berührungsloses Gesten-Schloss: Sicherer Zugang mit APDS-9960 & Arduino
- Isolierter Analogeingang für Arduino: Spannung/Strom galvanisch trennen
- Präziser Reaktionszeit-Test mit Arduino UNO