[動画]
今回のプログラムを書き込むとこのように動きます。
今回はtone関数やKTR-1上のボリュームを使用しKTR-1上のブザーを鳴らしたり音程を変えたりします。
便利なmap関数を使用してみたりもします。
const int LED1 = 14;
const int LED2 = 15;
const int BUZZ = 5;
const int Trig = 7;
const int AIN1 = 3;
const int AIN2 = 6;
const int BIN1 = 9;
const int BIN2 = 10;
const int VR = A0;
const int SW1 = A1;
const int SW2 = A2;
const int ECHO = 8;
int VRvol = 0; // センサーからの値を格納する変数
冒頭は前回のものと、さほど変わりません。
メインで使うBUZZはD5ピンに接続されています。
VR(ボリューム)はA0ピンに接続されています。A?ピンにはアナログ値の入力が可能です。
また、ボリュームの値を格納するVRvol変数が宣言されています。
void setup() {
//ブザーピンを出力として初期化します
pinMode(BUZZ, OUTPUT);
pinMode(SW1, INPUT);
pinMode(SW2, INPUT);
//アナログ入力ピンは宣言しなくても入力できる
}
書いてあるままブザーのピンをアウトプットに設定します。
また、アナログ入力ピンはインプットに設定しなくても使用できるので特に記述しません。
void loop() {
VRvol = analogRead(VR); // アナログピンを読み取る
VRvol = map(VRvol, 0, 1023, 220, 880); //値を丸める
if (digitalRead(SW1) == HIGH) {
tone(BUZZ, VRvol, 500); delay(500);//音の出力
} else if (digitalRead(SW2) == HIGH) {
for (int i = VRvol; i >= 150; i--) {
tone(BUZZ, i, 10); delay(10);
}
} else {
noTone(BUZZ);// BUZZをオフにします:
}
}
まずanalogRead関数が呼ばれています。
analogRead(ピン番号)
こちらでアナログ値(ピンにかかる電圧)を取得します。
Arduinoは0から5Vの入力電圧を0から1023の数値として取得することが出来ます。
KTR-1ではボリュームが真ん中だと512ぐらいの値が
右にMAXひねると1023が現れるような回路になっています。
0~1023という値をHzとしてブザーに周波数を指示しても良いのですがそれだとちょっとつまらないので
次にmap関数が呼ばれています。
map(変換したい数値,現在の範囲の下限 , 現在の範囲の上限 ,変換後の範囲の下限 ,変換後の範囲の上限 )
map関数にmap(VRvol, 0, 1023, 220, 880);こう書かれていた場合
VRvolが0なら220を、512なら550を、1023なら880を返してくれるわけです。
今はピンとこないかもしれませんが便利な関数なので頭の片隅に置いておいてください。
ちなみに220HzはA3のラで、880Hzは2オクターブ上のA5のラです。お好きな音程に書き換えても楽しいと思います。
if (digitalRead(SW1) == HIGH) {
tone(BUZZ, VRvol);//音の出力
} else if (digitalRead(SW2) == HIGH) {
for (int i = VRvol; i >= 150; i--) {
tone(BUZZ, i, 10); delay(10);
}
} else {
noTone(BUZZ);// BUZZをオフにします:
}
}
お次はif文で条件分岐が行われています。
前項ではdigitalReadの値を変数に入れて条件式に入れていましたが直接(digitalRead(SW1) == HIGH)と書くことも可能です。
余談ですが条件式内が正しければコンピュータはそれを1に。そうでなければ0に変換するため、
if(1)やif(true)と書くと必ず条件式が満たされるようになります。デバッグ時などに便利です。
tone(ピン番号, 周波数,鳴らす時間(省略可能))
次にtone関数が呼ばれています。
tone(BUZZ, VRvol);//音の出力
この場合ブザーピンをボリュームで鳴らし、noTone(ピン番号)が呼ばれるまで音を出し続けます。
noTone(BUZZ);は何もボタンを押さなかったときの分岐に居ます。
SW2を押したときの分岐には鳴らす時間を指定したtone関数を置きました。
} else if (digitalRead(SW2) == HIGH) {
for (int i = VRvol; i >= 150; i--) {
tone(BUZZ, i, 10); delay(10);
}
for文の中に居るため現在のVR値で指定されたHzから150Hzまでだんだん周波数を下げていくような処理です。
tone(BUZZ, i, 10); delay(10);
ここでは感覚的にわかりやすいようにdelayまで同じ行で書いています。セミコロンの位置を間違えなければこのような記述でも問題ありません。
逆にわかりづらい場合は普通に改行してください。
ここで鳴らした秒数だけ待機させないとちょっとうまく行かないと思います。休符のような次の音が出るまでの待ちです。
現実世界は時間軸があってめんどくさいですね。delayを消して試してみるのもいいと思います。
本項ではアナログ値取得とブザー鳴らしを行いました。
ブザーの音程を変えてコードがどっちの分岐に入ったかなどのデバッグが容易になったり、
アナログ値を持ってきて、点滅周期をユーザーが調整できたり、
幅のあるプログラムが可能になりました。ぜひマスターしてみてください。
ボタンが押されたら三三七拍子でLEDを光らせて、光ると同時にビープ音が鳴る用にしてみよう