今回はキッチンタイマーのスケッチにアラーム音を追加します。
音程と周波数
前回の記事では、digitalWrite
とdelayMicroseconds
を使って、ずいぶんと面倒なプログラミング修行をしました。
電子工作では、時間の計算をすることがよくあります。それも、1秒、2秒といったものから、ミリ秒、マイクロ秒まで広い範囲の時間を扱います。面倒なプログラミングですが、この計算を通してミリ、マイクロの扱い方にぜひ慣れてみてください。
ところで、Arduinoでは音を出す指示が用意されているんです。実際のキッチンタイマーのアラーム音はこの音を出す指示を使って実装します。
ここでは新しい言葉が出てきますので確認してきましょう!
前回の記事で、スピーカーが1秒間に262回振動すると「ド」の音が出ることを説明しました。
この「1秒間に振動する回数」のことを「周波数」(しゅうはすう)と呼んでいます。単位は「Hz」(ヘルツ)です。
「ド」の音は1秒間に262回振動しますので、「ド」の周波数は「262Hz」ということになります。
世の中にはいろいろな単位がありますが、原則としてアルファベットの大文字、または大文字で始まっている単位は人名が由来です。
例えば電圧の単位の「V」(ボルト)は、電池を発明したアレッサンドロ・ボルタが由来です。そのためボルトの単位は小文字の「v」ではなく大文字の「V」になっています。
「Hz」は電波に関係する学問で大きな貢献をしたハインリヒ・ヘルツが由来です。
一方で、長さの単位の「m」(メートル)はギリシャ語の「測ること」を意味する「メトロン」という言葉が由来です。このように人の名前が由来ではない場合はアルファベットの小文字を使います。
ところで、力の大きさを表す単位は「N」です。大文字なので誰かの名前なのですが、誰だかわかりますでしょうか。おそらく誰でも一度は聞いたことのある有名な人物です。
音程は周波数、ということがわかりましたので、各音程の周波数をまとめておきます。3オクターブ分の音程を以下の表にまとめます。あとでアラーム音をカスタマイズしますので、その時に見返してみてください。また、正確な周波数は少数ですが、以下の数値は少数第一位で四捨五入しています。
1オクターブ下
通常オクターブ
1オクターブ上
音程 | 周波数(Hz) |
ド | 131 |
ド# | 139 |
レ | 147 |
レ# | 156 |
ミ | 165 |
ファ | 175 |
ファ# | 185 |
ソ | 196 |
ソ# | 208 |
ラ | 220 |
ラ# | 233 |
シ | 247 |
音程 | 周波数(Hz) |
ド | 262 |
ド# | 277 |
レ | 294 |
レ# | 311 |
ミ | 330 |
ファ | 349 |
ファ# | 370 |
ソ | 392 |
ソ# | 415 |
ラ | 440 |
ラ# | 466 |
シ | 494 |
音程 | 周波数(Hz) |
ド | 523 |
ド# | 554 |
レ | 587 |
レ# | 622 |
ミ | 659 |
ファ | 698 |
ファ# | 740 |
ソ | 784 |
ソ# | 831 |
ラ | 880 |
ラ# | 932 |
シ | 988 |
音を出す命令
Arduinoの音を出す命令を確認しましょう。
最初は音を出す命令です。
tone
は、引数に端子番号と周波数を指定します。この指示は、指定した周波数になるように指定した端子の電圧を前回の記事ように制御します。
tone
は指定した端子に信号を「出力」しますが、pinMode
でOUTPUT
に設定する必要はありません。自動的に端子を出力モードに設定してくれます。
ところで、このtone
を実行すると音がずっと鳴ったままになります。
音を止めるには次の指示をします。
例えば、A0端子に接続しているスピーカーで「ド」の音を1秒間鳴らしたい場合、次のようにスケッチを作成すればOKです。
tone(A0, 262); // 262Hzの音を出す
delay(1000); // 1秒待つ
noTone(A0); // 音を止める
これでアラーム音が簡単に鳴らせそうです!
アラーム音を追加する
それではキッチンタイマーのスケッチにアラーム音を追加しましょう。
アラーム音はどのようなものにするか悩ましいところですが、まずは「ピピピーッ」という音にしてみます。音程はちょっと高めの1オクターブ高い「ラ」の音にしてみます。
アラーム音の鳴らす時間的なタイミングですが、まずは以下のパターンで鳴らしてみます。
- 60ms鳴らす
- 60ms止める
- 60ms鳴らす
- 60ms止める
- 100ms鳴らす
- 600ms止める
また、鳴らしたままだとうるさいので、上の「ピピピーッ」のパターンを3回繰り返して停止するようにしてみました。
さらに、Arduinoボードが動作を開始したら、最初に秒を表すLEDを点灯状態にするように変更しました。点灯状態の場合はタイマースタートを待っている状態、ということを表すようにしてみました。
また、時間になったら秒を表すLEDを点灯するように変更しました。
以下が完成したスケッチです。
/*
キッチンタイマー
内容: スイッチ、LED、スピーカーを使ったキッチンタイマー
変更履歴:
2024.11.25: 新規作成
2024.12.01: スイッチが押されたらLED点滅開始
2024.12.02: スイッチ関連の#define追加
2024.12.05: 点滅回数カウント追加
2024.12.06: 繰り返し処理をforに変更
2024.12.13: アラーム音追加・動作開始時とタイマー時間の時に青色LEDを点灯
*/
// 秒を表現するLED関連の定義
#define BYOU_LED 12 // 秒を表現するLEDの接続端子
#define BYOU_ON 50 // 秒を表現するLEDを点灯している時間(単位:ミリ秒)
#define BYOU_OFF (1000 - BYOU_ON) // 秒を表現するLEDを消している時間(単位:ミリ秒)
// タイマースタートスイッチ関連の定義
#define SWITCH A5 // スイッチを接続している端子名
#define SWITCH_OFF 1 // スイッチOFFの時のdigitalReadの値
#define SWITCH_ON 0 // スイッチONの時のdigitalReadの値
// タイマー時間設定(LEDの点滅回数)
#define TIMER_JIKAN 3
// アラーム音関連
#define SPEAKER A0 // スピーカーの端子番号
#define ALARM 880 // アラーム音の音程
void setup() {
// 端子の設定
// スピーカー接続端子はtoneの指示で自動的に出力設定になるので設定していません
pinMode(BYOU_LED, OUTPUT); // 秒表現のLED接続端子の出力設定
pinMode(SWITCH, INPUT_PULLUP); // スイッチ接続端子をプルアップ設定
// 秒のLED(青色LED)を点灯する
digitalWrite(BYOU_LED, HIGH);
// スイッチが押されるまで何もしないで待つ
while( digitalRead(SWITCH) == SWITCH_OFF ) {
}
}
void loop() {
// TIMER_JIKAN分の回数を数える
for(uint8_t count=0; count<TIMER_JIKAN; count++) {
// 1秒に1回青色LEDを点滅する
digitalWrite(BYOU_LED, HIGH);
delay(BYOU_ON);
digitalWrite(BYOU_LED, LOW);
delay(BYOU_OFF);
}
// 時間になったので秒のLED(青色LED)を点灯する
digitalWrite(BYOU_LED, HIGH);
// アラーム音を3回鳴らす
for(uint8_t count=0; count<3; count++) {
// ピ
tone(SPEAKER, ALARM);
delay(60);
noTone(SPEAKER);
delay(60);
// ピ
tone(SPEAKER, ALARM);
delay(60);
noTone(SPEAKER);
delay(60);
// ピーッ
tone(SPEAKER, ALARM);
delay(100);
noTone(SPEAKER);
delay(600);
}
// 何もしないで待つ
while( true ) {
}
}
ミニチャレンジ課題
最後にミニチャレンジ課題に挑戦してみてください。
今回の記事では「ピピピーッ」というアラーム音を鳴らしました。
そこで、アラーム音が鳴るタイミングに合わせて青色LEDもそのリズムで点灯させてみてください。
アラーム音の「ピピピーッ」に合わせて、青色LEDを「ピカピカピカーッ」とつけたり消したりしてみてください。
自分のオリジナルのアラーム音に変えてみてください。
音程とパターンを変えるといろいろと面白いアラーム音を鳴らすことができると思います。
ミニチャレンジ課題解答例
課題1
アラーム音にあせてLEDを点滅したいので、tone
とnoTone
のタイミングでLEDをON、OFFにすればOKです。
/*
第31回 ミニチャレンジ課題
アラーム音に合わせてLEDを点滅
*/
// 秒を表現するLED関連の定義
#define BYOU_LED 12 // 秒を表現するLEDの接続端子
#define BYOU_ON 50 // 秒を表現するLEDを点灯している時間(単位:ミリ秒)
#define BYOU_OFF (1000 - BYOU_ON) // 秒を表現するLEDを消している時間(単位:ミリ秒)
// タイマースタートスイッチ関連の定義
#define SWITCH A5 // スイッチを接続している端子名
#define SWITCH_OFF 1 // スイッチOFFの時のdigitalReadの値
#define SWITCH_ON 0 // スイッチONの時のdigitalReadの値
// タイマー時間設定(LEDの点滅回数)
#define TIMER_JIKAN 3
// アラーム音関連
#define SPEAKER A0 // スピーカーの端子番号
#define ALARM 880 // アラーム音の音程
void setup() {
// 端子の設定
// スピーカー接続端子はtoneの指示で自動的に出力設定になるので設定していません
pinMode(BYOU_LED, OUTPUT); // 秒表現のLED接続端子の出力設定
pinMode(SWITCH, INPUT_PULLUP); // スイッチ接続端子をプルアップ設定
// 秒のLED(青色LED)を点灯する
digitalWrite(BYOU_LED, HIGH);
// スイッチが押されるまで何もしないで待つ
while( digitalRead(SWITCH) == SWITCH_OFF ) {
}
}
void loop() {
// TIMER_JIKAN分の回数を数える
for(uint8_t count=0; count<TIMER_JIKAN; count++) {
// 1秒に1回青色LEDを点滅する
digitalWrite(BYOU_LED, HIGH);
delay(BYOU_ON);
digitalWrite(BYOU_LED, LOW);
delay(BYOU_OFF);
}
// アラーム音を3回鳴らす
// toneとnoToneのタイミンくでLEDをON、OFFにする
for(uint8_t count=0; count<3; count++) {
// ピ
digitalWrite(BYOU_LED,HIGH);
tone(SPEAKER, ALARM);
delay(60);
digitalWrite(BYOU_LED,LOW);
noTone(SPEAKER);
delay(60);
// ピ
digitalWrite(BYOU_LED,HIGH);
tone(SPEAKER, ALARM);
delay(60);
digitalWrite(BYOU_LED,LOW);
noTone(SPEAKER);
delay(60);
// ピーッ
digitalWrite(BYOU_LED,HIGH);
tone(SPEAKER, ALARM);
delay(100);
digitalWrite(BYOU_LED,LOW);
noTone(SPEAKER);
delay(600);
}
// 時間になったので秒のLED(青色LED)を点灯する
digitalWrite(BYOU_LED, HIGH);
// 何もしないで待つ
while( true ) {
}
}
更新履歴
日付 | 内容 |
---|---|
2019.10.5 | 新規投稿 |
2021.8.26 | 新サイトデザイン対応 |
2024.12.13 | 関数説明フォーマット変更 |