2020年11月30日 | 更新。 |
以前、抵抗分圧器を使った、多くのスイッチのセンシングの記事で、Arduinoのアナログ入力ピン1つで多くのスイッチの状態をセンシングする方法を紹介しました。今回は、この方法を用いて、13個のスイッチの状態をセンシングし、それらのスイッチを鍵盤に見立てて演奏できる電子オルガンを作ってみました。
今回製作した電子オルガンの大まかな構成を表したブロック図を図1に示します。
電子オルガンは、Arduinoにコンソール基板と呼ぶ、鍵盤と圧電ブザーからなる基盤を取り付ける事により構成します。
鍵盤は、図1ではピアノの鍵盤風の図を描きましたが、実際には6mm角のタクトスイッチを13個並べただけのものです。13個のスイッチで、Cから1オクターブ上のCまで(ハ長調において、ドから1オクターブ上のドまで)の1オクターブを、半音階でカバーできます。
鍵盤の回路を詳しく書いたのが図2です。5VとGNDの電源を抵抗分圧する回路になっており、どのボタンが押されるかで分圧比が変わる仕組みになっています。その結果、押されるボタンに応じて出力電圧(ArduinoのA0ピンに入力する)が変化します。詳しい原理は抵抗分圧器を使った、多くのスイッチのセンシングの記事を参照してください。
使う抵抗の精度は5%で十分です。定格電力(許容損失)も1/8Wで十分ですが、1/4Wの抵抗を使っても構いません。
tone関数で、キーに応じた音程を出すため、圧電ブザーには、発振器を内蔵していない他励式の物を使う必要があります。他励式の圧電ブザーに、ある周波数の交流電圧を印加すると、その周波数の音が出ます。
一方で、圧電ブザーには、交流の発振回路を内蔵しており、直流の電源につなげるだけで音が出るものもあります。これを自励式の圧電ブザーと呼びます。自励式の圧電ブザーは、内蔵する発振回路の発振周波数で音が鳴るように設計されていますので、音程を変えることはできません。
秋月電子では、他励式の圧電ブザーの事を圧電スピーカーと呼び、自励式の圧電ブザーの事を電子ブザーと呼んで区別しているみたいですが、この区別は、必ずしも一般的なものではありません。
他励式の圧電ブザーは、入力インピーダンスがダイナミックスピーカー(磁石とコイルを使った一般的なスピーカー)に比べて高いため、5VのGPIOの出力電圧を端子に加えても、マイコンに過負荷がかかる程の大電流が流れない事や、直流バイアス(印加する信号の平均電圧)が0でなくても、問題なく使えるなどの性質のため、マイコンに直結できるので、使いやすい発音素子です。ただし、音質は良くありません。
音質を良くしようとしてダイナミックスピーカーを使うと、一般的にはアンプ回路が必要になりますので、回路が複雑になります。
先ほど他励式圧電ブザーはマイコンに直結できると書きましたし、インターネット上で、実際にマイコンに直結している作例も多くあるのですが、他励式圧電ブザーには、振動を加えると、電圧を発生する性質があり、共振現象や外部からの振動により、圧電ブザーが発生した電圧が、マイコンを壊してしまう可能性もあります。そこで、1kΩ程度の抵抗を直列に入れて、保護するのが一般的です。(図1のブロック図にはその保護抵抗は省略されていますが、実際の回路には保護抵抗を入れてあります。)
なお、今回の作例で用いた圧電ブザーは、マルツの店頭で安売りしていた外径約20mmのものです。型番など、詳細な情報は不明です。しかし、他励式であれば、たいていの圧電ブザーが使えるでしょう。
Arduinoを含む、全体の回路図を次に示します。
この回路図には省略してありますが、コンソール基板には4ピンのピンソケットを設けてあり1番ピンから順に、Arduinoの5V、A0、GND、D2の端子とつなぐようにしてあります。このピンソケットと、Arduinoの間は、ブレッドボードのジャンパ線などで配線できますが、今回は、後述するように専用の線を使いました。
また、回路図にはArduino Unoと書いてありますが、Arduino LeonardoとArduino Mega 2560でも動作する事を確認しています。
コンソール基板は、ユニバーサル基板に部品を半田付けして作りました。今回は、手元にあった1.2mm厚の紙ベーク基板を使いましたが、強度不足のようで、演奏中に基板が反ります。(基板の下側中央に細い金属製のスペーサを入れてあるのはその対策です) 1.6mm厚のガラスエポキシ基板を使えば、強度的な問題はなくなるでしょう。
完成したコンソール基板の写真を次に示します。
Arduinoとコンソール基板の間の接続は、次の写真の様にブレッドボードで使うジャンパ線が使用できます。
自分でオルガンを演奏して遊ぶ場合はこれでもいいのですが、人前でデモをすることを想定して、専用ケーブルを作る事にしました。専用のケーブルを作っておくと、短時間で間違いのない配線ができます。
本来は、こういうケーブルを自作するよりも、共立電子のQIケーブル4P-1PX4を買うほうが、見栄えの良いケーブルになるのですが、他の部品は全部手元にあった部品で済ませているので、このケーブルだけ発注するのが悔しくて(というより面倒くさくて)自作しました。
もしQIコネクタ01PやQIコネクタ04PやQIコネクタ用プラグコンタクトピンが手元にあれば、これらを使って見栄えの良いケーブルを作れたのですが、あいにく手元にはありませんでした。また、コンタクトピンに電線を圧着するには、圧着工具が必要で、またその使いこなしにも慣れが必要なので、あまり初心者向きの工作とはいえません。
今回は、手元にあった、カットして長さの調節できるピンヘッダと、直径3mmの熱収縮チューブを使って、専用ケーブルを作りました。安価で作り方が簡単なので、応用範囲が広いと思います。
まず、ピンヘッダをカットして、4端子のピンヘッダを作ります。つぎに、そのピンヘッダを半田付けヘルパーなどで固定し、ケーブルを半田付けしたい部分を半田めっきします。
次に、耐熱被覆線の被覆を数mm、ワイヤストリッパで剥き、露出した銅線を半田めっきします。
次に、半田めっきの終わった4端子のピンヘッダを半田付けヘルパーに固定し、半田めっきの終わった被覆線と半田付けします。この際に、新たに半田を足す必要はありません。非常に短時間で半田付けできます。
半田付けができたら熱収縮チューブを15mm位に切って、半田付けした所にかぶせます。
熱収縮チューブは、ライターで加熱して収縮させます。本来は工業用ドライヤーで加熱するのが理想ですが、高価ですし、使用頻度の低い工具を置く場所がないので買っていません。また、髪を乾かすための、家庭用のドライヤーで加熱したのでは、十分な温度まで過熱できません。ライターを扱う場合は、やけどをしないように注意してください。また、部品を加熱しすぎて溶かさない様に注意してください。
同様の方法で、被覆線の反対側にも1ピンのピンヘッダを半田付けします。この際に、半田付けよりも先に、被覆線に熱収縮チューブを通しておく事が重要です。半田付けを先にやってしまうと、ピンヘッダの太い部分が邪魔になって、後からは熱収縮チューブを通す事ができません。
全てのピンヘッダが半田付けできたら、各被覆線に、信号名を記入したタグをつけます。今回は、ダイソーで買ったインデックスタグに信号名を手書きしましたが、テプラなどを使うと見栄えが良くなるでしょう。
キーを読み取るソフトウェアは、ほぼI/Oピン一つで読み取れるキーパッドの製作のものと同じです。キーの数が違うのに合わせて手直ししてある程度です。
キーを読み取ってからの処理は、今回は圧電ブザーを鳴らせるという事で、tone関数でキーに応じた周波数の方形波を発生させています。各キーが押された場合の方形波の周波数は、frequencyというconst int型の配列にしまってあります。
周波数の計算方法について簡単に説明しておきます。音が高くなるほど周波数も高くなりますが、音階が1オクターブ上がるごとに周波数が2倍になるという規則がある事が知られています。1オクターブは12半音ですので、半音上がるごとに周波数が一定の比率で上昇するとして計算すると、音階が半音あがれば周波数は122≒1.059463倍になります。(ここではピアノの調律などに使われる平均律の話をしています。他にも、音の響きを重視した純正律などの調律法があります)
ピアノの中央ド音(C4)の上のラ音(A4)は、440Hzに調律するのが基準とされているので、この音を基準に、半音あがるごとに周波数を12√2倍していけば、全ての音階の周波数が計算できます。これをExcelで計算した結果をまとめたのが次の表です。
音階 | 周波数[Hz] | 備考 |
---|---|---|
C4 | 261.626 | ピアノの中央の ド音 |
C#4 | 277.183 | |
D4 | 293.655 | |
D#4 | 311.127 | |
E4 | 329.628 | |
F4 | 349.228 | |
F#4 | 369.994 | |
G4 | 391.995 | |
G#4 | 415.305 | |
A4 | 440.000 | 調律の基準音 |
A#4 | 466.164 | |
B4 | 493.883 |
音階 | 周波数[Hz] | 備考 |
---|---|---|
C5 | 523.251 | 中央から1オクターブ上のド音 |
C#5 | 554.365 | |
D5 | 587.330 | |
D#5 | 622.254 | |
E5 | 659.255 | |
F5 | 698.456 | |
F#5 | 739.989 | |
G5 | 783.991 | |
G#5 | 830.609 | |
A5 | 880.000 | |
A#5 | 932.328 | |
B5 | 987.767 |
音階 | 周波数[Hz] | 備考 |
---|---|---|
C6 | 1046.502 | 今回使う最低音 |
C#6 | 1108.731 | |
D6 | 1174.659 | |
D#6 | 1244.508 | |
E6 | 1318.510 | |
F6 | 1396.913 | |
F#6 | 1479.978 | |
G6 | 1567.982 | |
G#6 | 1661.219 | |
A6 | 1760.000 | |
A#6 | 1864.655 | |
B6 | 1975.533 |
音階 | 周波数[Hz] | 備考 |
---|---|---|
C7 | 2093.005 | 今回使う最高音 |
C#7 | 2217.461 | |
D7 | 2349.318 | |
D#7 | 2489.016 | |
E7 | 2637.020 | |
F7 | 2793.826 | |
F#7 | 2959.955 | |
G7 | 3135.963 | |
G#7 | 3322.438 | |
A7 | 3520.000 | |
A#7 | 3729.310 | |
B7 | 3951.066 |
ピアノの中央付近のよく使われる音階を今回の電子オルガンで使うなら、C4(261.626Hz)~C5(523.251Hz)の範囲の音が出るようにすべきでしょうが、圧電ブザーは、あまり低い音を、効率よく出す事ができません。そこで、今回は2オクターブ上のC6(1046.502Hz)~C7(2093.005Hz)の範囲の音が出るようにしました。
tone関数の第2引数は周波数ですが、unsigned int型なので、小数点以下の入力はできません。そこで、表1の周波数の小数点以下を四捨五入する必要があります。
以上のことを踏まえて電子オルガンのスケッチを作ると、次のようになります。Arduino Uno/Mega 2560/Leonardoのどれでもこのスケッチが使えます。動作確認はArduino IDE 1.0.5で行いました。
const int KeyNum = 13; // キーの数
const int threshold[KeyNum] = { 35, 115, 196, 277, 357, 433, 510, 588, 670, 751, 831, 908, 987}; // AD変換値の閾値
const int frequency[KeyNum] = { 1047,1109,1175,1245,1319,1397,1480,1568,1661,1760,1865,1976,2093}; // 各キーの周波数
// キーデコード関数
// 引数をA/D変換結果(0~1023)にして呼ぶと、押したキーの番号(0~KeyNum-1)を返す。
// 何もキーを押していない時は、-1を返す。
int KeyDecode(int n)
{
int i=0;
while(i<KeyNum && n>threshold[i]) i++;
if(i>=KeyNum) return -1;
return i;
} // KeyDecode
void setup()
{
} // setup
void loop()
{
int LastResult=-2; // 前回のキーデコード結果
int result; // 今回のキーデコード結果
int cnt=0; // デコード結果が一致した回数
static int LastDisplayed=-2; // 前回loop関数が呼ばれたと時に表示したキー
// 複数回のloop関数の呼び出しにわたって値を保持するために、static変数にしている
// キーを読み取る
// チャタリングの除去などのため、A/D変換の値が落ち着くまで待つ
// 1ms間隔でキーを読み取り、10回連続で同じキーが押されていたら、落ち着いたと判断する
do {
result=KeyDecode(analogRead(A0));
if(result==LastResult) {
cnt++;
} else {
LastResult=result;
cnt=0;
} // if
delay(1);
} while(cnt<10);
// 音を出す/止める
if(result!=LastDisplayed){
if(result<0) { // 音を止める
noTone(2);
} else { // 音を出す
tone(2,frequency[result]);
} // if
} // if
LastDisplayed=result;
} // loop
以上の様に、比較的簡単な回路で、スケッチもほぼI/Oピン一つで読み取れるキーパッドの製作の記事で紹介したスケッチを使いまわして電子オルガンを作る事ができました。製作費も安いので、夏休みなどの長期休暇に、作ってみると楽しいでしょう。