USB MIDI контролер на Arduino

Більшість статей в інтернеті по виготовленню MIDI клавіатур, контролерів, пультів тощо базуються на використанні MIDI-роз'ємів, підключення яких до сучасного комп'ютера може виявитися проблематичним. На старих звукових картах був Game-порт, до якого можна було підключити джойстик або MIDI-пристрій:

Шнур MIDI

Однак, всі нові материнські плати йдуть зі вбудованим звуковим контролером, та й на звукових картах часто відсутня можливість підключення MIDI-пристроїв.
Залишається або купувати сучасну MIDI-клавіатуру, ді-джейський пульт тощо з USB виходом для підключення до комп'ютера, або купувати/паяти перехідник, або ж купувати спеціальну звукову карту з можливістю підключення MIDI-пристроїв. Купити, звісно, не проблема, але ми ж на цьому сайті не для цього зібралися, вірно?

У цій статті я хочу показати, як можна на недорогому контролері Arduino виготовити простішу MIDI-клавіатуру з USB-підключенням на 8 клавіш і колесом прокрутки.

Отже, я використав:
контролер Arduino UNO
8 шт. кнопок
8 резисторів 10 кОм
поворотний енкодер 25LB22-Q
макетну плату і перемички

Схема підключення наступна:

Схема підключення

Для підключення я використав найпростіший варіант: 1 клавіша - 1 вхід. Однак при більшій кількості клавіш, різних контролерів тощо входів може не вистачити, тому доведеться задействувати зчитування даних або через аналогові входи (шляхом додавання резисторів різного номіналу), або шляхом мультиплексування. Однак, якщо повісити кілька клавіш на аналоговий вхід, можуть виникнути проблеми зі зчитуванням стану, коли натиснуті одночасно кілька клавіш. Тому, на мій погляд, мультиплексування більш прийнятний варіант.

Фото підключення

Програмне забезпечення Arduino

Структуру MIDI-даних я не буду розглядати, оскільки це описано в статті: передача MIDI даних від Arduino в комп'ютер

Енкодер підключений до входів апаратного переривання, опис роботи з ним я розглядати не буду, оскільки програма проста і взята з офіційного сайту Arduino.

У даному проекті енкодер використовується як колесо прокрутки для зміни модуляції (modulation wheel), однак його можна переназначити і для інших цілей (pitch bend тощо).

MIDI-дані від енкодера, з Arduino посилаються наступним рядком:
noteOn(0xB0, 0x01, encoder0Pos);
де 0xB0 - повідомлення контролера (control change)
0x01 - код контролера (в нашому випадку Modulation)
encoder0Pos - значення контролера (в нашому випадку 0-127).
Змінюючи коди контролера, ви можете використовувати колесо прокрутки (енкодер) для найрізноманітніших контролерів.

Окремо варто згадати Pitch Bend. З специфікації MIDI слід, що необхідно надіслати повідомлення з трьох байт: 0xE0 (код Pitch Bend), MSB (старший байт), LSB (молодший байт).

Два крайніх байта містять 14-бітне значення pitch, яке може лежати в межах 0...16383 (0x3FFF). Середина знаходиться 0x2000, все, що вище цього значення - відбувається зміна висоти тону вгору, якщо нижче, то висота тону змінюється вниз.
У коді програми я закоментував рядки, якщо ви раптом замість modulation захочете використовувати Pitch Bend (середина значення, розкладання на 2 байти тощо).

Код визначення натискання клавіші включає в себе три стани: клавіша натиснута, клавіша утримується і клавіша відпущена. Зроблено це для того, щоб можна було передавати значення тривалості натискання клавіші. Якщо це не потрібно, можна залишити тільки один стан (натискання клавіші), програма в даному випадку суттєво спроститься.
Для обробки стану кожної з восьми клавіш використовується наступний код:

  if (buttonState_C == HIGH && note_C_send_on == false)  // Натискання клавіші
  {
    noteOn(0x90, note_C, 0x7F);
    note_C_send_on = true;    // Команда Note On надіслана
    note_C_send_off = false;  // Команда Note Off не надіслана 
  }
  else if (buttonState_C == HIGH && note_C_send_on == true)  // Якщо клавіша утримується
  {
    noteOn(0x00, note_C, 0x7F);
    note_C_send_on = true;
    note_C_send_off = false;
  }
  else if (buttonState_C == LOW && note_C_send_off == false)  // Якщо клавішу відпустили
  {
    noteOn(0x90, note_C, 0x00);
    note_C_send_on = false;
    note_C_send_off = true;
    encoder0Pos = 0;  // Повертаємо позицію колеса до нуля
  }
  .......
  .......
  .......
  // Функція відправки MIDI-повідомлення в послідовний порт
  void noteOn(int cmd, int pitch, int velocity) {
    Serial.write(cmd);
    Serial.write(pitch);
    Serial.write(velocity);
    delay(20);
  }
  

Зверніть увагу, що якщо буде використовуватися pitch bend, то encoder0Pos потрібно буде повертати не в нуль, а в 0x2000 (а краще задати define на початку програми).

Отже, схема зібрана, скетч в контролер залитий, запускаємо Serial Monitor, змінюємо швидкість передачі на 115200 і натискаючи клавіші або крутячи енкодер дивимося значення.
Якщо все нормально, то переходимо до наступної частини. Скажу відразу, що для мене вона виявилася найпроблемнішою, і якби я не знайшов віртуального USB -> Midi конвертера, то цієї статті не було б.

Програмне забезпечення ПК (Windows)

Для того, щоб приймати дані через USB віртуальний COM-порт від Arduino і передавати їх у якусь програму MIDI-секвенсор, необхідна спеціальна утиліта: Serial MIDI Converter V2D (оф. сайт)

Програма мультиплатформенна, у мене запрацювала під Windows 7 x64, правда з деякими затримками.

Запускаємо її, вибираємо порт USB, швидкість передачі (115200) та MIDI Input Port і MIDI Output Port.

Serial MIDI Converter

Тепер, всі ті MIDI-дані, які надходять на USB віртуальний COM-порт 12, перенаправляються на порт MIDI Yoke 6 (для створення віртуальних MIDI портів я скористався програмою MIDI Yoke). Можна перенаправити їх на Microsoft GS Wavetable Synth та інші порти.
Програма постійно повинна бути включеною. При натисканні клавіш або повороті ручки енкодера, внизу повинен мигати індикатор Serial RX.

Для візуального відображення надходячих MIDI даних з порту мені дуже пригадалася програма MIDI-OX (оф. сайт):

MIDI-OX

Зверніть увагу, що в налаштуваннях MIDI Devices необхідно виставити порт MIDI Input.

Тепер, натискаючи клавіші нот або обертаючи колесо, в Monitor-Output ви побачите MIDI-дані.

Таким чином, за допомогою програмно-апаратних засобів ми отримали можливість зробити на контролері Arduino простішу MIDI-клавіатуру з передачею даних у комп'ютер, для подальшої їх обробки, наприклад, у Cubase, в т. ч. в реальному часі.
На основі цього проекту можна зробити DJ-пульт, повноцінну MIDI-клавіатуру тощо.

Нижче ви можете скачати скетч INO, Serial MIDI Converter V2D, MIDI-OX та MIDI Yoke

Прикреплені файли:
Top