/*
* キッチンタイマー
*
* 内容: スイッチ、LED、スピーカーを使ったキッチンタイマー
* 変更履歴:
* 2019. 8.11: 新規作成
* 2019. 8.15: スタートスイッチ処理を追加
* 2019. 8.17: スイッチ関連の#define追加
* 2019. 9. 8: 点滅回数カウント追加
* 最終的に繰り返し処理をfor文で作成
* 2019. 9.16: スケッチ動作開始時にLEDを点滅
* 2019.10. 5: アラーム音追加
* 動作開始時とタイマー時間の時に青色LEDを点灯するように変更
* 2019.10.13: 残り時間LED制御追加
* 2019.10.14: 残り時間が5秒以下になったらスピーカーを鳴らす動作を追加
* 2019.11. 4: アラーム音をメロディーに変更
* 音階定義をファイル化
* 2019.11.11: メロディーを配列化
* 2019.11.23: 残り時間表示LEDの関数化
* 2019.11.24: 残り時間表示LED関数をswitch文に変更
* 2019.12. 1: 残り時間を列挙型で宣言
* 2019.12. 7: メロディーの長さを変えられるように変更
* 2019.12.21: メロディーデータを構造体の配列に変更
*/
// 音階定義ファイルのインクルード
// 秒を表現するLED関連(青色LED)
#define BYOU_LED 12 // 秒を表現する青色LEDの端子番号
#define BYOU_ON 50 // 秒を表現するLEDをつけている時間 (単位:ミリ秒)
#define BYOU_OFF 1000 - BYOU_ON // 秒を表現するLEDを消している時間 (単位:ミリ秒)
// 残り時間を表現するLED関連(緑色、黄色、赤色LED)
#define LED_MIDORI 8 // 緑色LEDの端子番号
#define LED_KIIRO 6 // 黄色LEDの端子番号
#define LED_AKA 4 // 赤色LEDの端子番号
// スタートスイッチ関連
#define SWITCH A5 // スイッチを接続している端子番号
#define SWITCH_OFF 1 // スイッチOFFの時のdigitalReadの値
#define SWITCH_ON 0 // スイッチONの時のdigitalReadの値
// タイマー時間設定(単位:秒)
#define TIMER_JIKAN 100
// 残り時間を表現するLEDの制御時間
#define KIIRO_JIKAN TIMER_JIKAN / 3
#define AKA_JIKAN TIMER_JIKAN / 3 * 2
// アラーム音関連
#define SPEAKER 13 // スピーカーの端子番号
#define ALARM 880 // 通常のアラーム音周波数
#define DO_4 262
#define DOS_4 277
#define RE_4 294
#define RES_4 311
#define MI_4 330
#define FA_4 349
#define FAS_4 370
#define SO_4 392
#define SOS_4 415
#define RA_4 440
#define RAS_4 466
#define SI_4 494
#define DO_5 523
// アラームメロディー関連
#define ALARM_ONKAISUU 13 // アラームメロディーの音の数
// 音データの構造体
struct oto {
uint16_t onkai;
uint16_t nagasa;
};
// 音データの構造体配列
struct oto alarm_melody[] = {
{DO_4, 200},
{MI_4, 200},
{SO_4, 400},
{MI_4, 400},
{DO_4, 200},
{MI_4, 200},
{SO_4, 400},
{MI_4, 400},
{DO_4, 200},
{MI_4, 200},
{SO_4, 400},
{SI_4, 400},
{DO_5, 800}
};
// 残り時間のenum型宣言
// 十分 半分以下 もうすぐ
enum nokori {jyuubun, hanbun, mousugu};
// 残り時間表示用LEDの制御関数
// パラメータ: 残り時間目安
// jyuubun: 残り時間十分
// hanbun: 残り時間少ない
// mousugu: もうすぐ設定時間
// 返り値:
// なし
//
void controlTimeLed(enum nokori nokori_jikan) {
// 残り時間に応じた処理
switch(nokori_jikan) {
// 残り時間十分
case jyuubun:
digitalWrite(LED_MIDORI, HIGH);
digitalWrite(LED_KIIRO, LOW);
digitalWrite(LED_AKA, LOW);
break;
// 残り時間半分以下
case hanbun:
digitalWrite(LED_MIDORI, LOW);
digitalWrite(LED_KIIRO, HIGH);
digitalWrite(LED_AKA, LOW);
break;
// もうすぐ設定時刻
case mousugu:
digitalWrite(LED_MIDORI, LOW);
digitalWrite(LED_KIIRO, LOW);
digitalWrite(LED_AKA, HIGH);
break;
}
}
void setup() {
// 端子の設定
pinMode(BYOU_LED, OUTPUT); // 青色LED接続端子設定
pinMode(LED_MIDORI, OUTPUT); // 緑色LED接続端子設定
pinMode(LED_KIIRO, OUTPUT); // 緑色LED接続端子設定
pinMode(LED_AKA, OUTPUT); // 緑色LED接続端子設定
pinMode(SWITCH, INPUT_PULLUP); // スイッチ接続端子の設定
// 秒のLED(青色LED)を点灯する
digitalWrite(BYOU_LED, HIGH);
// スイッチが押されるまで待つ
while(digitalRead(SWITCH) == SWITCH_OFF) {
}
// タイマー開始時に緑色LEDを点灯
controlTimeLed(jyuubun); // 「残り時間十分」の表示
}
void loop() {
uint8_t count; // for文で回数を数えるために使用する変数
uint8_t oto_bangou; // for文でメロディーを鳴らすために使用する変数
// TIMER_JIKAN分の回数を数える
for( count=0; count<TIMER_JIKAN; count++) {
// 残り時間表現用LEDの制御
if( count == KIIRO_JIKAN ) {
controlTimeLed(hanbun); // 「残り時間少ない」の表示
}
if( count == AKA_JIKAN ){
controlTimeLed(mousugu); // 「もうすぐ設定時間」の表示
}
// 残り時間に応じて処理を変える
if( count >= (TIMER_JIKAN - 5) ) {
// 残り時間が5秒以下になったら、1秒に1回青色LEDを点滅して音を鳴らす
digitalWrite(BYOU_LED, HIGH);
tone(SPEAKER, ALARM);
delay(BYOU_ON);
digitalWrite(BYOU_LED, LOW);
noTone(SPEAKER);
delay(BYOU_OFF);
} else {
// そうでなければ、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( count=0; count<3; count++) {
// メロディーを演奏する
for( oto_bangou=0; oto_bangou<ALARM_ONKAISUU; oto_bangou++ ) {
//tone(SPEAKER, alarm_melody[oto_bangou][0]);
//delay(alarm_melody[oto_bangou][1]);
tone(SPEAKER, alarm_melody[oto_bangou].onkai);
delay(alarm_melody[oto_bangou].nagasa);
}
// 音を消す
noTone(SPEAKER);
// 1.5秒あける
delay(1500);
digitalWrite(LED_AKA, LOW);
}
// 何もしないで待つ
while(digitalRead(SWITCH) == SWITCH_OFF) {
}
}