Набор USB-MIDI адаптера для Arduino Micro / Leonardo — полный список деталей
Компоненты и материалы
| Arduino Micro | или Arduino Leonardo | ×1 |
| Оптопара 6n137 | ×1 | |
| Диод 1N4148 — быстрый коммутационный | ×1 | |
| Конденсатор 100 нФ | ×1 | |
| Резистор 220 Ом | ×3 | |
| Резистор 10 кОм | ×1 | |
| Резистор 470 Ом (в корпусном исполнении) | ×1 | |
| Светодиод (любой) | ×1 | |
| Держатель для светодиода | для монтажа LED в пластиковом корпусе | ×1 |
| DIN-разъем (аудио/видео), 5 контактов | + болты и гайки для крепления | ×2 |
| Корпус (пластиковый) | чтобы поместились все компоненты | ×1 |
| Печатная плата (любая универсальная) | ×1 | |
| Крепежи для платы | например, нержавеющие стойки | ×1 |
Приложения и онлайн-сервисы
- Arduino IDE
О проекте
Искал в интернете, как собрать USB-MIDI адаптер на Arduino, но нашел только решения с плохой реализацией MIDI (программной или аппаратной). Решил сделать свой и выложить на hackster.io.
Сначала собрал прототип на Arduino Leonardo с макетной платой. Когда всё заработало, сделал паяльную версию на Arduino Micro — он компактнее. Оба построены на ATmega32u4, у которого нативный USB, позволяющий представляться как USB-MIDI интерфейс для ПК.
MIDI использует оптопару и резисторы для создания полностью изолированного токового контура. Схема стандартная, использовал 6n137 — быстрый и доступный. Как показывает схема, только у MIDI OUT разъема pin 2 соединен с землёй — это стандарт MIDI.
Фото готового устройства:




На программной стороне выбрал отличную библиотеку Control Surface. В отличие от других библиотек или ручных реализаций, Control Surface корректно обрабатывает все аспекты довольно сложного MIDI-протокола.
Control Surface позволяет легко добавлять экстра: потенциометры, педали, кнопки на аналоговых/цифровых входах для дополнительных MIDI-контроллеров. Подробнее на сайте Control Surface — очень просто!
Можно регистрировать коллбэки для обработки данных перед передачей MIDI→USB или USB→MIDI. Я использовал это для исправления сломанной MIDI-реализации своего синтезатора Roland D50. D50 шлёт команду «All Notes Off» каждый раз, когда отпускается последняя клавиша. Современные VST-инструменты трактуют это как мгновенное жесткое прекращение всех удерживаемых нот. Отфильтровав «All Notes Off», D50 снова стал пригоден как мастер-клавиатура.
Одна проблема с Control Surface — она плохо работает с большими SysEx-пакетами. Это вызывало ошибки при использовании редактора/библиотекаря D50, который шлёт большие SysEx. В заголовочном комментарии исходного кода есть инструкции, как это исправить. Автор библиотеки сказал, что в версии 2.x это будет исправлено.
Включены оба варианта исходного кода: базовый USB-MIDI интерфейс и версия с фильтром «All Notes Off».
Можно использовать другие библиотеки или написать свою — железо будет работать с любой MIDI-библиотекой с поддержкой USB MIDI и Serial MIDI.
Совет по устранению неисправностей: если адаптер не общается с внешними MIDI-устройствами, возможно, вы перепутали пины 4 и 5. Распиновки разъемов иногда запутаны — не всегда понятно, с какой стороны смотрят.
Надеюсь, схемы и код пригодятся. Ставьте лайк, если понравилось, и пишите вопросы в комментариях.
Код
Исходный код базового MIDI-USB интерфейса
/* USB MIDI адаптер.
* ---
* Для поддержки больших SysEx-пакетов измените библиотеку Control Surface:
* В src\MIDI_Parsers\MIDI_MessageTypes.hpp:
* uint8_t length; → size_t length;
* В src/Settings/Settings.hpp:
* constexpr size_t SYSEX_BUFFER_SIZE = 128; → constexpr size_t SYSEX_BUFFER_SIZE = 320;
* Исправится в Control Surface 2.x.
* ---
* Для другого USB-имени устройства отредактируйте hardware/arduino/avr/boards.txt в Arduino IDE (админ права).
* leonardo.build.usb_product="Arduino Leonardo" → leonardo.build.usb_product="..."
* Верните обратно после прошивки.
*/
#include <Control_Surface.h>
USBMIDI_Interface midiusb;
// USBDebugMIDI_Interface midiusb; // для дампа MIDI в Serial Monitor
HardwareSerialMIDI_Interface midiser = {Serial1, MIDI_BAUD};
MIDI_PipeFactory<5> pipes;
// Пример добавления контроллеров:
// CCPotentiometer pot = { A0, MIDI_CC::Expression_Controller };
const int ledPin = 10; // пин индикатора питания
void setup() {
Serial.begin(115200);
pinMode(ledPin, OUTPUT); digitalWrite(ledPin, HIGH);
midiusb >> pipes >> midiser; // USB MIDI → Serial MIDI
midiser >> pipes >> midiusb; // Serial MIDI → USB MIDI
Control_Surface >> pipes >> midiusb; // Control Surface → USB MIDI
midiser >> pipes >> Control_Surface; // Serial MIDI → Control Surface
midiusb >> pipes >> Control_Surface; // USB MIDI → Control Surface
Control_Surface.begin(); // инициализация ПОСЛЕ подключения интерфейсов
}
void loop() {
Control_Surface.loop();
}
Исходный код MIDI-USB адаптера с фильтром «All Notes Off»
/* USB MIDI адаптер с фильтром "All Notes Off".
* (Те же изменения библиотеки Control Surface для больших SysEx)
* ---
* Для другого USB-имени — см. комментарий выше.
*/
#include <Control_Surface.h>
USBMIDI_Interface midiusb;
HardwareSerialMIDI_Interface midiser = {Serial1, MIDI_BAUD};
MIDI_PipeFactory<4> pipes;
const int ledPin = 10;
// Пользовательский коллбэк MIDI
struct MyMIDI_Callbacks : MIDI_Callbacks {
void onChannelMessage(Parsing_MIDI_Interface &midi) override {
ChannelMessage cm = midi.getChannelMessage();
if (cm.header == 0xb0 && cm.data1 == 0x7b) {
// игнорируем "All Notes Off"
return;
} else if (cm.header == 0x90 && cm.data2 == 0x00) {
// "Note On" с velocity 0 → "Note Off"
cm.header = 0x80;
}
midiusb.send(cm);
}
void onSysExMessage(Parsing_MIDI_Interface &midi) override {
SysExMessage se = midi.getSysExMessage();
midiusb.send(se); // SysEx без изменений
}
void onRealTimeMessage(Parsing_MIDI_Interface &midi) override {
RealTimeMessage rt = midi.getRealTimeMessage();
midiusb.send(rt); // Real-time без изменений
}
} 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();
}
Схемы
Только вкладка schematic заполнена.
usb_midi_interface_twiE32gvR3.fzz
Производственный процесс
- Умный датчик полива «Thirst Alert» на Arduino — DIY сигнализация засухи для растений
- Итальянские словесные часы на Arduino Nano, NeoPixel, LCD и RTC
- Экономия пинов Arduino: подключение 4×3 клавиатуры по трём аналоговым входам
- Компактная MIDI-барабанная установка с 3D-печатью
- Надежный счетчик кВт·ч на Sigfox с Arduino MKR Fox 1200
- Bluetooth-монитор температуры на Arduino Nano с NTC-термистором
- DIY Автоматический измеритель емкости (10 пФ – 10 мкФ) на Arduino Nano
- Бесконтактный жестовый замок: APDS-9960 + Arduino для безопасного доступа
- Гальванически разделённый аналоговый вход для Arduino на LM331 и оптопаре 4N25
- Точный тест времени реакции на Arduino UNO