Arduino jako MIDI zařízení

S MIDI protokolem může být sranda. Zvlášť, pokud máte doma nějaké elektronické klávesy, syntetizér, nebo jiné zařízení s MIDI (ovšem bude stačit i počítač s USB). Díky tomu, že Arduino má sériové rozhraní UART, pomocí kterého je možné komunikovat rychlostí 31 250 baudů, můžete si jednoduše vyrobit vlastní MIDI zařízení.

Základy

Pokud zadáte do Google klíčová slova Arduino a MIDI, vypadne na vás spousta zajímavých projektů i návodů jak na to.

Úplný základ, jak na MIDI popisuje MIDI Note Player přímo na oficiálních stránkách Arduina. Je zde ukázáno nejjednodušší zapojení s jedním DIN 5 konektorem (také známým jako MIDI jack) a rezistorem a základní kód, který opakovaně odesílá jednu notu.

Toto zapojení je opravdu jednoduché a zvládnete jej rozchodit za pár minut. Ovšem na další experimenty bych doporučil spíše zapojení s optočlenem, které doporučuje specifikace MIDI.

Vstup MIDI do Arduina.
MIDI vstup do digitálního pinu číslo 0 na Arduinu.

Pokud chcete v Arduinu používat i MIDI out, podívejte se na odkaz výše, kde je doporučené zapojení.

MIDI Knihovna

Potřebujete poradit?
Pokud se vám nedaří MIDI knihovnu zprovoznit, nebo jste narazili na problém, zeptejte se v našem QA fóru.

Jakmile budete mít hotové rozhraní pro MIDI, už vám nic nebrání začít experimentovat. K vlastnímu přijímání (odesílání) zpráv pak můžete využít vlastní kód, nebo šikovnou knihovnu MIDI Library (a dokumentace). Pokud nevíte jak do Arduino IDE přidat novou knihovnu, přečtěte si o tom v mém článku Arduino a knihovny.

Tato knihovna je relativně jednoduchá a docela dobře dokumentovaná, ale i přesto ukážu několik příkladů použití. Pro příjem MIDI zprávy může sloužit následující kód:

#include <MIDI.h>

// Pokud používáte Arduino Mega a chcete použít jiné UART
// rozhraní, než 'Serial', změňte konstantu USE_SERIAL_PORT
// #define USE_SERIAL_PORT   Serial1

void setup() {
  MIDI.begin();           // Zahájí komunikaci na Serial (UART)
                          // rychlostí 31250 baudů a MIDI kanálu 1.
  // MIDI.begin(channel); // To samé, ale bude poslouchat zprávy
                          // na MIDI kanálu 'channel'.
}

void loop() {
  // Zjistíme, jestli jsou na MIDI vstupu nějaká data
  if (MIDI.read()) {
    // Jaký typ dat přišel?
    switch(MIDI.getType()) {
      // -
      case ProgramChange:
        // Udělej něco užitečného.
        break;
      // -
      case NoteOn:
        // Udělej něco užitečného.
        break;
      // -
      case NoteOff:
        // Udělej něco užitečného.
        break;
      // -
      case PitchBend:
        // Udělej něco užitečného.
        break;
      default:
        break;
    }
  }
}

Pokud zavoláte MIDI.begin() bez parametrů, bude se poslouchat jenom MIDI kanál 1. V případě, že chcete poslouchat všechny kanály, zavolejte MIDI.begin(MIDI_CHANNEL_OMNI). Také se podívejte na všechny typy zpráv, které vrací metoda MIDI.getType().

Tento kód ale není nijak vhodný pro složitější aplikace, proto knihovna MIDI obsahuje i asynchronní funkce využívající callbacky. Příklad, který bude na všech kanálech sledovat zprávy typu NoteOn:

#include <MIDI.h>

void HandleNoteOn(byte channel, byte pitch, byte velocity) {
  // Zde může být libovolný kód, který smysluplně reaguje na
  // příchod zprávy NoteOn. Třeba:
  if (velocity == 0) {
    // ...
  }
}

void setup() {
  // Budeme poslouchat na všech MIDI kanálech
  MIDI.begin(MIDI_CHANNEL_OMNI);
  // Připojíme naši funkci ke callbacku.
  MIDI.setHandleNoteOn(HandleNoteOn);

}

void loop() {
  // Tato metoda by se měla v hlavní smyčce volat
  // co nejčastěji!
  MIDI.read();
}

To by byla ukázka použití knihovny MIDI Library. Pro podrobnější informace se podívejte do dokumentace a samozřejmě také zdrojového kódu.

Ještě upozorním, že knihovna používá rozhraní UART, které má Arduino Uno pouze jedno a to na pinech 0 (RX) a 1 (TX). To znamená, že pokud budete chtít vytvořit z Arduina plnohodnotné MIDI zařízení se třemi DIN5 konektory (tzn. MIDI in, out a thru), nebudete moct komunikovat přes USB s počítačem. Na druhou stranu, pokud chcete vyrobit USB-MIDI převodník z Arduina, je to možné.

Arduino jako USB-MIDI device

Pokud máte v počítači (nebo iPodu, iPadu, Androidu) nějakou aplikaci, která umí pracovat s MIDI (například GarageBand, nebo MaxMSP) a chtete do ní posílat MIDI zprávy z Arduina, budete muset provést ještě jeden krok.

Samotné Arduino se po připojení k USB hlásí jako sériová linka. To znamená, že (v případě Una) mikrokontrolér ATMega8U2 funguje jako překladač mezi UART<>USB. Pokud se pokusíte do počítače odeslat MIDI zprávu, budete ji schopni přijmout pouze přes sériové rozhraní. Pokud v Arduino IDE otevřete Serial Monitor, uvidíte přijímaná data.

Programy jako je například GarageBand ale umí pracovat jenom s USB-MIDI zařízením, a proto je nutné nainstalovat program, který vytvoří virtuální USB-MIDI zařízení a data bude číst ze sériové linky Arduina. To je sice jednoduché řešení, ale docela nepohodlné, protože potřebujete speciální aplikaci na převod.

Pokud ale přeprogramujete mikrokontrolér ATMega8U2 tak, aby se hlásil jako MIDI zařízení a dokázal do počítače odesílat data z UART ve správném formátu, máte vyhráno. Nebude pak potřeba žádné virtuální rozhraní a Arduino pak bude odesílat (přijímat) data přímo z GarageBand (nebo jiné aplikace).

Tento problém naštěstí už několik lidí řešilo. Jedním z projektů je i MocoLUFA, která využívá vynikající knihovnu LUFA pro Atmel mikrokontroléry. MocoLufa je nový firmware pro ATMega8U2 a Arduino Uno (nebo Mega), který způsobí, že se bude Arduino hlásit jako USB-MIDI zařízení.

Sám jsem tohle zatím nezkoušel, a proto sem uvedu jenom odkazy ze kterých jsem čerpal. Jakmile si tento postup prakticky ověřím, napíšu o tom samostatný článek, protože je to téma velmi rozsáhlé.