Edited at

ArduinoとMIDIキーボードを組み合わせて楽器をつくる方法

More than 3 years have passed since last update.

今日は楽器の日

ということで、MIDIキーボードからArduinoを制御して、簡単な楽器を作ってみます。

作り方は簡単

ArduonoArduino USB Host Shieldをガッチャンコして、

USBケーブルでMIDIキーボードを繋げるだけ


使ったもの


ライブラリ

バージョンは両方とも最新の使っています。

わかりにくいですが、USB Host Library Rev.2.0という名前のライブラリーのバージョン1.2.1です。


とりあえず動かしてみる

試しにUSBH_MIDIのサンプルにあるコードを動かしてみます。

https://github.com/YuuichiAkagawa/USBH_MIDI/blob/master/examples/USBH_MIDI_dump/USBH_MIDI_dump.ino

PCからコードを書き込んで、シリアルモニタで確認できます。

鍵盤を押すとこんな感じのログが表示されます。

0002310D: 64: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

00027C13: 64: 09 90 48 76 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00027CA7: 64: 08 80 48 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00027D80: 64: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00027D80: 64: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0002CA5C: 64: 09 90 48 5A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0002CAF0: 64: 08 80 48 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0002CBC7: 64: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

bufMidiに16進数で1バイトずつMIDIの信号が入っているのですが、細かい仕様はこちら

このログでいうと

xxxxxxxx: xx: 00 00 00 00 00 ~の2桁毎に表示されている数字の部分がそれです。

例えば1バイト目が、

09だったら鍵盤を押したタイミング(Note On)、

08だったら鍵盤を離したタイミング(Note Off)になります。

音程は3バイト目が取得できるので、

00027C13: 64: 09 90 48 76 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

これは48番目の鍵盤を押したということが分かります。

音程はピアノの中央の60として半音毎に1変化します。

ド - 60

ド# - 61

レ - 62

レ# - 63

ミ - 64

ファ - 65

ソ - 67

といった具合です。

使われるのは7ビットで0(とても低いド)~127(とても高いソ)までの128音対応してます。


Arduinoを楽器にしてみる

そんなわけで、鍵盤に対応した音を圧電スピーカーから鳴らしてみます。

使い方はBuilt-In ExamplesのtoneMelodyとほぼいっしょ

image

Note Numberは丁度0から始まるので配列にしてしまいます。

対応した周波数の配列、60番目が基準の440Hzです。

double tones[128] = {8.2, 8.7, 9.2, 9.7, 10.3, 10.9, 11.6, 12.2, 13, 13.8, 14.6, 15.4, 16.4, 17.3, 18.4, 19.4, 20.6, 21.8, 23.1, 24.5, 26, 27.5, 29.1, 30.9, 32.7, 34.6, 36.7, 38.9, 41.2, 43.7, 46.2, 49, 51.9, 55, 58.3, 61.7, 65.4, 69.3, 73.4, 77.8, 82.4, 87.3, 92.5, 98, 103.8, 110, 116.5, 123.5, 130.8, 138.6, 146.8, 155.6, 164.8, 174.6, 185, 196, 207.7, 220, 233.1, 246.9, 261.6, 277.2, 293.7, 311.1, 329.6, 349.2, 370, 392, 415.3, 440, 466.2, 493.9, 523.3, 554.4, 587.3, 622.3, 659.3, 698.5, 740, 784, 830.6, 880, 932.3, 987.8, 1046.5, 1108.7, 1174.7, 1244.5, 1318.5, 1396.9, 1480, 1568, 1661.2, 1760, 1864.7, 1975.5, 2093, 2217.5, 2349.3, 2489, 2637, 2793.8, 2960, 3136, 3322.4, 3520, 3729.3, 3951.1, 4186, 4434.9, 4698.6, 4978, 5274, 5587.7, 5919.9, 6271.9, 6644.9, 7040, 7458.6, 7902.1, 8372, 8869.8, 9397.3, 9956.1, 10548.1, 11175.3, 11839.8, 12543.9};

上の2つのサンプルを組み合わせて、鍵盤を押した時に対応する音が鳴るようにしてみました。


miditone.ino

#include <usbh_midi.h>

#include <usbhub.h>
#include <SPI.h>

USB Usb;
USBH_MIDI Midi(&Usb);

int pin = 8;
int melo = 200;
double tones[128] = {8.2, 8.7, 9.2, 9.7, 10.3, 10.9, 11.6, 12.2, 13, 13.8, 14.6, 15.4, 16.4, 17.3, 18.4, 19.4, 20.6, 21.8, 23.1, 24.5, 26, 27.5, 29.1, 30.9, 32.7, 34.6, 36.7, 38.9, 41.2, 43.7, 46.2, 49, 51.9, 55, 58.3, 61.7, 65.4, 69.3, 73.4, 77.8, 82.4, 87.3, 92.5, 98, 103.8, 110, 116.5, 123.5, 130.8, 138.6, 146.8, 155.6, 164.8, 174.6, 185, 196, 207.7, 220, 233.1, 246.9, 261.6, 277.2, 293.7, 311.1, 329.6, 349.2, 370, 392, 415.3, 440, 466.2, 493.9, 523.3, 554.4, 587.3, 622.3, 659.3, 698.5, 740, 784, 830.6, 880, 932.3, 987.8, 1046.5, 1108.7, 1174.7, 1244.5, 1318.5, 1396.9, 1480, 1568, 1661.2, 1760, 1864.7, 1975.5, 2093, 2217.5, 2349.3, 2489, 2637, 2793.8, 2960, 3136, 3322.4, 3520, 3729.3, 3951.1, 4186, 4434.9, 4698.6, 4978, 5274, 5587.7, 5919.9, 6271.9, 6644.9, 7040, 7458.6, 7902.1, 8372, 8869.8, 9397.3, 9956.1, 10548.1, 11175.3, 11839.8, 12543.9};

void setup() {
Serial.begin(9600);
pinMode(pin, OUTPUT);

if (Usb.Init() == -1) {
while(1);
}
delay(200);
}

void loop() {
Usb.Task();

if (Usb.getUsbTaskState() == USB_STATE_RUNNING) {
getTone();
}
delay(2);
}

void getTone() {
char buf[20];
uint8_t bufMidi[64];
uint16_t rcvd;

if (Midi.RecvData(&rcvd, bufMidi) == 0 ) {
if (bufMidi[0] == 9) {
int note = bufMidi[2];
tone(pin, tones[note], 200);
}
}
}


image

実際に弾いてみた


おわり

今回使ってないですが、ベロシティとかピッチベンドとか他のパラメーターも取れるし、

キーボードにオクターブシフトがついていれば128個のボタンが手に入ります。

MIDI機器なら結構安いものもあるし、楽器以外にもいろいろ活用できそうです。