MIDIデバイスを自作し、ブラウザのWeb MIDI APIと通信した。
rkistner/arcoreを使ったら簡単にできた。

もともとLeonardo以降のATMega32U4を使っているArduinoはMPU内にUSB機能が内蔵されていて、その部分もプログラマブルなのでキーボードやマウスにしたりとかできる。

セットアップ


% git clone git@github.com:rkistner/arcore.git
% cd arcore/
% ./install.sh

~/Documents/Arduino/hardware/arcore にシンボリックリンクが貼られる。Arduino IDEを再起動するとターゲットボードが増えてるので選択する。



プログラムを書く


analogReadでセンサーを読んでMIDI channel1にコントロールメッセージを送る。analogReadは10bitだがMIDIデータは7bitなので下3bitを捨てる。
MIDIEventの0x0Bはコントロールメッセージという意味。0xB0は10110000で下4bitの1〜16でMIDIチャンネルを表すので論理和する。(0から始まるので、この場合チャンネル2になる)
3、4番目の引数は7bit(0~127)ならなんでもいい。
void setup() {
}

int an;

void loop() {
an = analogRead(0);
if(MIDIUSB.available()){
MIDIEvent e = {0x0B, 0xB0|1, 10, an>>3};
MIDIUSB.write(e);
}
}

ChromeのWeb MIDI APIがちょうどコントロールメッセージをonmessageイベントで受信できるので、ブラウザからMIDIデバイス化したArduinoのセンサーが読めるようになった。
http://shokai.github.io/WebMidiAPIStudy/dump/

関連:AndroidタブレットでWeb MIDI API


USBシリアル通信と併用もできる。ブラウザにMIDIデータが流れるし、同時にArduino等のシリアルコンソールを開くとそっちにも数値が流れてくる。
void setup() {
pinMode(13, true);
Serial.begin(9600);
}

int an;

void loop() {
an = analogRead(0);
if(MIDIUSB.available()){
MIDIEvent e = {0x0B, 0xB0|1, 10, an>>3};
MIDIUSB.write(e); // MIDI送信
}
Serial.println(an); // シリアル通信からもAD変換器の値を送ってみる

// 動作確認用にLEDを点滅させる
digitalWrite(13, true);
delay(100);
digitalWrite(13, false);
delay(100);
}