先日、Arduino Uno R3でMIDIコントローラーを作るというページを見つけたので、100円ショップで孫の手を2本買ってきて、バイオリンのように弾けるMIDIコントローラーを作ってみた。
片方がバイオリン本体でもう一方が弓。
弓は孫の手の指の間にゴムバンドを引っ掛けただけ。
音階を決めるネック部分は2cm毎に5mmのCdS(光センサ)を7つ埋め込んであって、指で隠すことで音階を決める。
弓でこする弦の代わりにロータリーエンコーダーを回すことで弾いていることを検出する。
CdSを7つとロータリーエンコーダーの3端子なので手持ちの10芯のフラットケーブルを使った。
黒がGND。ロータリーエンコーダーのGNDは種類によって違うらしいので注意!
スケッチはロータリーエンコーダーの処理を参考にしたページとMIDIコントローラーのページからコピペしてちょっと変えただけなので、無駄な変数も残っています。
#define NOTE_ON 144 #define NOTE_OFF 128 #define CONTROL_CHANGE 176 #define ALL_NOTE_OFF 120 volatile int state = 0; volatile boolean Flag_A = true; volatile boolean Flag_B = false; #define BUTTON_MAX 7 int pin_no[] = {4,5,6,7,8,9,10}; //ピン番号を保存 int sw_state[] = {0,0,0,0,0,0,0}; //スイッチ状態を保存 int note_no[] = {60,61,62,63,64,65,66,67}; //スイッチ毎のノートナンバー int curr_note = 0; int prev_state = 0; void setup() { pinMode(2, INPUT_PULLUP); pinMode(3, INPUT_PULLUP); attachInterrupt(0, Fall_A, FALLING); attachInterrupt(1, Change_B, CHANGE); pinMode(4, INPUT); pinMode(5, INPUT); pinMode(6, INPUT); pinMode(7, INPUT); pinMode(8, INPUT); pinMode(9, INPUT); pinMode(10, INPUT); Serial.begin(31250); sendMidi(CONTROL_CHANGE, ALL_NOTE_OFF, 0); } void loop() { int save_state = state; delay(1000); if (curr_note && (save_state == state)) { sendMidi(NOTE_ON, curr_note, 0); curr_note = 0; } } void Fall_A() { if (!Flag_A) { return; } Flag_B = true; Flag_A = false; } void Change_B() { if (!Flag_B) { return; } if (HIGH == digitalRead(2)) { if (HIGH == digitalRead(3)) { state--; } else { state++; } Flag_B = false; Flag_A = true; int new_note = 60; if (HIGH == digitalRead(4)) { new_note = 61; } if (HIGH == digitalRead(5)) { new_note = 62; } if (HIGH == digitalRead(6)) { new_note = 63; } if (HIGH == digitalRead(7)) { new_note = 64; } if (HIGH == digitalRead(8)) { new_note = 65; } if (HIGH == digitalRead(9)) { new_note = 66; } if (HIGH == digitalRead(10)) { new_note = 67; } if (curr_note != new_note) { if (curr_note != 0) { sendMidi(NOTE_ON, curr_note, 0); } curr_note = new_note; sendMidi(NOTE_ON, curr_note, 127); } prev_state = state; } } void sendMidi(int cmd, int pitch, int velocity) { Serial.write(cmd); Serial.write(pitch); Serial.write(velocity); }
見ての通り、Serial.write
で書き出すだけなので、最初のうちはprint
にしておいてシリアルモニターでデバッグできるのが便利。
最終的にwrite
にして、Arduino Uno R3上のAtmega16U2のプログラムを書き換えてUSB MIDIデバイスにすればOKという手軽さ。
しかし、このAtmega16U2のプログラムを書き換えるのに四苦八苦した。
この件は別に記す。
参考にしたページ
ロータリーエンコーダーの処理:ロータリーエンコーダとArduinoを直結する
MIDIコントローラー:【DJ】Arduinoで自作MIDIコントローラーを作ってみる【VJ】
MIDI Firmware:Midi Firmware for Arduino Uno (Moco)
Cdsセルでデジタル入力させる時はどのようにしてHIGH、LOWの振り分けをしましたか?
Cdsがある抵抗をもっている以上電圧がかかってしまいどうしてもデジタル入力が常にHIGHの状態になってしまいます。。。
じゃじゃさん
回路図を描いてなかったので、どう接続していたのか忘れてしまいましたが、写真をよく見たら8素子の集合抵抗器(多分10kΩ)が見えたので抵抗分圧していると思います。
返信ありがとうございます。アナログで読み込んで閾値で振り分けることにしました。
さらに質問なのですが、ロータリーエンコーダの取り付けについてです。僕は発泡スチロールを加工して発泡スチロール中にロータリーエンコーダを埋めるという方法を用いようとしたのですがロータリーエンコーダを回す際にぐらぐらして固定できません。何か良い固定方法はありませんか。(Yujiさんのリンク先が消えていましたので)
じゃじゃさん
グルーガンを使ったらいかがでしょう?
接着してしまうので、基本的に一回限りになりますけど。
(部品を溶かさないので、綺麗に剝がせれば何回でもやり直せますし。)
グルーガンつかえますね!ありがとうございました。
じゃじゃさん
頑張ってください!