Blog

ArduinoでMIDIを受信して2個以上の電球を点滅させるための手順

Twitterでそれとなく書きましたが、ただいま電子回路とプログラミング記述を使って、電球の点滅をMIDIでコントロールできる装置を作っています。

MIDIっつーのは、音楽やってる人なら知ってると思うけど、そうじゃない人にとってはほぼ馴染みのない響きだよね。

ミディ。って口語的には言います。

MIDIってなんぞ

簡単に言うと、打ち込み音楽に必要なデータ規格のことだ。

「このタイミングでドラムのキックを鳴らす」

「このタイミングでベースのラの音を鳴らす」

みたいなことをMIDIを使って、パソコンに打ち込んでいく。

※こんなブロックが、音の高さや音符の長さを示している。

これを書き込むと、そのタイミングで音が鳴るようになる。

その積み重なりが、音楽になっていく(特に打ち込み系音楽ではこれがメイン)

現代の大半のミュージシャンは、少なからずMIDIを使ってる。

これがないと困るほど現代の音楽制作には必要不可欠なもの。

で、これを流用して音が出るのと同時に電球のオンオフを制御できる装置が作れたら、音楽に合わせてピカピカ自動で点滅してくれるお利口マシンが誕生することになる。

絶対にタイミングがずれない照明装置とも言える。

更にこのMIDIってやつは拡張性に長けているので、例えばキーボードを弾いて、リアルタイムに電球をピカピカ点滅させることもできる。

88鍵全てのドレミファソラシドにMIDIナンバーという独自の数字が割り当てられているから、指定の音にだけ反応して電球を光らせることもできる。

MIDIナンバーと鍵盤の対応表の参照はこちら

 

ちなみにMIDIの規格は日本発祥です!しかも世界基準。やばいぜジャパン!

 

つー感じで、MIDIについてなんとなく想像がつきましたでしょうか。

 

このMIDIの反応と照明の切り替わり、これを映像作品内で使う装置として組み上げよう!と言うのが今回の趣旨であります。

先日のある日、芸術家大川くんに「こんなのできたりしませんか?」という提案を受け、僕は手伝ってあげることにしたのだった。

いい大人が遊びでやるにはちょっとハードル高いけど笑。

やつは地元の後輩だからな。

しょうがないからやってあげよう!

おらもワクワクしてっぞぉ

技術的な問題

今回必要な電子回路や電球をパチパチするアナログ回路は、実は大したことがないくらい簡単なものだ。

リレースイッチって部品を使って、電球のオンオフを切り替えるだけ。

リレースイッチとは、ある一定の電圧の電流を流すと、「カチ」っと切り替わるスイッチのこと。

人間が指で押して電気をつけるスイッチと変わらない。

指で押すか、電気信号で押すかの違いだ。

-この黒い四角がリレースイッチ-

リレースイッチについて詳しくはこちら

で、この電気信号でスイッチを押す役をさっき書いたMIDIに任せることが今回の最大の目的。

鍵盤で例えると、ミを押した時にでるMIDI信号を受けた場合にだけリレースイッチに電気信号を送るようにプログラミングする。

すると、ミを押すたびに電球がチカチカと点滅するようになる。

この仕組みを実現してくれるのがArduinoという、今回の心臓部分になる機械。

アルドゥイーノって読んでます。

-凛々しいArduinoさま-

このArduinoに「ミを押した時にでるMIDI信号を受けた場合にだけリレースイッチに電気信号を送る」というプログラムを書き込むのだ。

そうすると、ミを押すたびにArduinoがリレースイッチをカチカチするための電気信号を送ってくれるようになる。

その結果、晴れて電球は点滅を繰り返し、今回の製作任務完了!となるわけであります。

 

しかしね、今回一番大変なのはこれを実現するためのプログラムを書くこと、、、。

電子回路製作の経験はまだあるにせよ、プログラミングはズブの素人の僕。

プログラミングの基礎部分だけでもなんとなくわかってないと、マジで意味不明でしかない。

ちなみにArduinoにはArduino専用のプログラミング言語があるので、それに倣って記述していきます。

でも元になっているのはC言語という、コンピュータープログラミングの元祖的言語。

これをもっと簡単にした(らしい)のがArduinoの言語のようです(全然簡単じゃないよ、、、)

1個の電球を制御するのは楽、2個以上がクソ難しい、、、

このように電球のピカピカをプログラミングを使って制御していくんだけど、電球一個動かすだけならめっちゃ簡単やねん。

なぜならネットに転がってるやつをコピペすればできるから!

しかし2個以上制御するには、プログラミングの中身が理解出来てないと何をいじればいいのかマジでわからない。

どこをいじってもエラーになる。

勘でいじると、ほぼエラー。

その理由をググれど、日本語で説明されているページがほぼない。

それがこの界隈のマニアックさだ。

Arduinoの日本語ページはすごく少ないね。

利用者はそこそこいるはずなのに、皆さん技術力を隠しすぎでしょう笑。

もっと末端に情報を公開してほしい限りでございます、、、。

ツーことで、こちらのサイトさんを朝から何回も読み続けました。

はっきり言って、むずい。

けど、他に比べたら一番詳細にわかりやすく書いてくださっている。

このページのこの記述を今回参考させていただくことにした。

#include <MIDI.h>

MIDI_CREATE_DEFAULT_INSTANCE();

void handleNoteOn(byte channel, byte pitch, byte velocity)
{
    // ノートの鳴り始めにさせたいことを何でも書いて

    // できるだけコールバックの中は短くするように、
    // でないとloop関数が遅くなり、リアルタイム性能に悪影響が出てしまう
}

void handleNoteOff(byte channel, byte pitch, byte velocity)
{
    // ノートの鳴り終わりにさせたいことを何でも
    // ベロシティ0のノートオンメッセージもNoteOffとして解釈される(つまりここで処理される)点に注意
}

void setup()
{
    // handleNoteOn関数をMIDIライブラリに結びつけ、NoteOn時に呼び出されるようにする
    MIDI.setHandleNoteOn(handleNoteOn);  // 引数にはハンドラの「関数名」を書く

    // NoteOffにも同様
    MIDI.setHandleNoteOff(handleNoteOff);

    // 全チャンネルを読む形でMIDIインスタンスを初期化
    MIDI.begin(MIDI_CHANNEL_OMNI);
}

void loop()
{
    // リアルタイム性の確保のため、MIDI.readをできるだけ早く呼ぶように
    MIDI.read();
}

これだけだとなんのこっちゃですが、要約すると、MIDI信号を受け取ったらストレスなくそれを処理するためのプログラム例です。

これを使うと、変な遅延(MIDI信号と電球のオンオフのずれ)も起きづらくなる。

つまりやりたいことの理想により近くなる。

 

これを元に、今回やりたいことの基礎プログラミングを頑張って作ったのだ!↓

 

#include <MIDI.h>

MIDI_CREATE_DEFAULT_INSTANCE();

void handleNoteOnkick(byte channel , byte note , byte velocity)
{
switch(note)
{

case 21:
digitalWrite(12,HIGH);
break;

case 22:
digitalWrite(13,HIGH);
break;
}
}

void handleNoteOffkick(byte channel, byte note, byte velocity)
{
switch(note)

case 21:
digitalWrite(12,LOW);
break;

case 22:
digitalWrite(13,LOW);
break;
}
}

void setup()
{
MIDI.setHandleNoteOn(handleNoteOnkick);
MIDI.setHandleNoteOff(handleNoteOffkick);

pinMode(12,OUTPUT);
pinMode(13,OUTPUT);

MIDI.begin(MIDI_CHANNEL_OMNI);
}

void loop()
{
MIDI.read();
}

 

以上!

、、、ソースコードが汚いとか、そんなことは言わないでほしい。

動いただけで大収穫である。素人にしては上出来でしょう、、、

 


ほぼいないと思うけど、こんなのをやりたい人向けに一応プログラムの中身についてとその他のこと。

-プログラムの中身-

  • switch case文で条件を定義。
  • MIDIのnote21とnote22が入ってきた時だけデジタルピン12と13から5Vが出力されるようになってます。
  • case 21、case 22の数字部分がnoteの値になります。
  • midiと鍵盤の対応表でいうとnote21とnote22はそれぞれトランスポーズ-1のAとA#、つまりラとラ#になります。
  • この値はもちろん任意のものに変更できますし、数を増やしていくこともできます。
  • 同様にベロシティーも条件に指定できるので、例えばヒットの強さを3段階に分けて出力するデジタルピンを分けたりもできそう!その場合は演算子でベロシティーを3つに分けるとかが良いのかな?

 

-ArduinoをUSB-MIDI化して使う方法-

ArduinoをUSB-MIDI化する手順はこちらの記事が一番わかりやすかったです。

お世話になりました。

 

-リレースイッチの回路についての補足-

リレースイッチの回路にはバッファー回路(電流量増加目的)が必要っぽいんですが、とりあえず現状なくても動作しているので今は組んでません。

しかし最終的に10個以上の電球を制御する予定なので、バッファーはトランジスタを使ったエミッタフォロワ回路を作って追加する予定。

>ミッタフォロワ回路(コレクタ接地回路)


 

そんで上記のプログラムを作れたので、これができるようになったのです!

電球二つを、違うMIDI信号から制御する。

1個と2個じゃ難易度が大違い!

これが地味に大変だったよ、大川くん。

あとはプログラム次第で幾つでも電球をMIDIで制御できるようになる。

はず、、、。

そしてこのプログラムを使えば、いろいろな面白マシンが作れるかもしれない!という妄想例がこちら。

くだらないマシンの例

妄想!変なマシン1

二つのモータータイヤがついた台車に電子ドラムセットがのっかっている。

※電子ドラムはデフォルトでMIDIの送受信機がついています。

  1. ドラムのキックを踏むとタイヤが前進
  2. ドラムのスネアを叩くとタイヤがストップ
  3. ドラムのタム1を叩くと左車輪のスピードUP(つまり右にカーブする)
  4. ドラムのタム2を叩くと右車輪のスピードUP(つまり左にカーブする)
  5. ドラムのハイハットを叩くとライトが点灯する、再度叩くとライト消灯

セグウェイっぽいドラマーの誕生である。

スイッチのオンオフが制御できれば、もちろんモーターも制御できる

馬力のあるモーターを使えば、こんなの作れるんじゃね?

超いらないけど〜!

妄想!変なマシン2

  1. サンプラーに「ダウト!」という音声を読み込ませる。
  2. 「ダウト!」ボタンを押した時、midi信号→Arduino→リレースイッチになるようにする。
  3. リレースイッチが作動し、0.5秒電気が流れるようにする。
  4. トランプのダウトゲームで、ダウトを宣言するたびにダウトボタンを押すのを義務付ける。
  5. その度にゲーム参加者全員が被っているヘッドセットにバチっと電流が流れるようにする。
  6. 最高に緊迫した「ダウト」ゲームになること間違いなし!

疑いの坩堝から君は脱出できるのか、、、?

っていうキャッチコピーで大ヒットするはず。

パクっても良いぜ。

ゴミのようなアイディアから金の卵が生まれるかもしれない

俺のような凡人からは、さっき書いたみたいなウンコネタしか出て来ませんが、、、

しかし、あなただったらより高次なアイディアを生み出せるかもしれない。

なんにせよ、人は進化していく生き物だと言われて久しい。

どうか素晴らしいアイディアが、この世界に生まれ続けますように!

 

撮影テストを今度やりに行くんだけど、すげえ楽しみだよ。

良い映像作れますように!

関連記事一覧