今日は楽器の日
!
ということで、MIDIキーボードからArduinoを制御して、簡単な楽器を作ってみます。
作り方は簡単
Arduono
とArduino 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とほぼいっしょ
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つのサンプルを組み合わせて、鍵盤を押した時に対応する音が鳴るようにしてみました。
#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);
}
}
}
おわり
今回使ってないですが、ベロシティとかピッチベンドとか他のパラメーターも取れるし、
キーボードにオクターブシフトがついていれば128個のボタンが手に入ります。
MIDI機器なら結構安いものもあるし、楽器以外にもいろいろ活用できそうです。