Arduino Nano キッチンタイマー作成

c

1#define SEG_G 32#define SEG_F 43#define SEG_E 54#define SEG_D 65#define SEG_C 76#define SEG_B 87#define SEG_A 98#define SEG7_BIN0 109#define SEG7_BIN1 1110 11#include <TimerOne.h>12#include "pitches.h"13 14unsigned int timecount = 0;15byte st = 0; // ステータス0~216// 0:時間設定用モード(起動時)17// 1:カウントダウン開始18// 2:カウントダウン終了。1度Beepが鳴ると、時間設定用モードに切り替わる。19 20struct note {21 unsigned int frequency;22 unsigned long duration;23};24 25struct note melody[] = {26 {NOTE_D5, 500}27};28 29void setup() {30 // 7SEG用pinの設定31 pinMode(SEG_G, OUTPUT);32 pinMode(SEG_F, OUTPUT);33 pinMode(SEG_E, OUTPUT);34 pinMode(SEG_D, OUTPUT);35 pinMode(SEG_C, OUTPUT);36 pinMode(SEG_B, OUTPUT);37 pinMode(SEG_A, OUTPUT);38 39 // 欠けているピンの設定を行う40 pinMode(SEG7_BIN1, OUTPUT);41 pinMode(SEG7_BIN0, OUTPUT);42 43 pinMode(2, OUTPUT);44 45 pinMode(16, INPUT); //A2 モード切り替え用ボタン46 pinMode(17, INPUT); //A3 インクリメント47 pinMode(A6, INPUT); // デクリメント48 pinMode(A7, INPUT);49 Serial.begin(9600);50 51 Timer1.initialize(1000000);52 Timer1.attachInterrupt(count_down);53 Serial.begin(9600);54}55 56void write_a_digit(byte digit, byte data) {57 58 // 2bit で表示桁を指定するためのエンコード59 static const byte SEG7_DIG0[] = {1, 0, 1, 0};60 static const byte SEG7_DIG1[] = {1, 1, 0, 0};61 62 // 2bit で表示桁を指定63 digitalWrite(SEG7_BIN0, SEG7_DIG0[digit]);64 digitalWrite(SEG7_BIN1, SEG7_DIG1[digit]);65 66 // 対応する数字  0 1 2 3 4 5 6 7 8 967 static const byte SEG_GP[] = {0, 0, 1, 1, 1, 1, 1, 0, 1, 1};68 static const byte SEG_FP[] = {1, 0, 0, 0, 1, 1, 1, 0, 1, 1};69 static const byte SEG_EP[] = {1, 0, 1, 0, 0, 0, 1, 0, 1, 0};70 static const byte SEG_DP[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 1};71 static const byte SEG_CP[] = {1, 1, 0, 1, 1, 1, 1, 1, 1, 1};72 static const byte SEG_BP[] = {1, 1, 1, 1, 1, 0, 0, 1, 1, 1};73 static const byte SEG_AP[] = {1, 0, 1, 1, 0, 1, 1, 1, 1, 1};74 75 if (data < 10) { // 0~9 の時はその数字を表示76 digitalWrite(SEG_G, SEG_GP[data]);77 digitalWrite(SEG_F, SEG_FP[data]);78 digitalWrite(SEG_E, SEG_EP[data]);79 digitalWrite(SEG_D, SEG_DP[data]);80 digitalWrite(SEG_C, SEG_CP[data]);81 digitalWrite(SEG_B, SEG_BP[data]);82 digitalWrite(SEG_A, SEG_AP[data]);83 } else { // 10 以上の時は数字でも文字でも無いパターンを表示84 digitalWrite(SEG_G, 1);85 digitalWrite(SEG_F, 0);86 digitalWrite(SEG_E, 0);87 digitalWrite(SEG_D, 1);88 digitalWrite(SEG_C, 0);89 digitalWrite(SEG_B, 0);90 digitalWrite(SEG_A, 1);91 }92}93 94void clear_7seg() {95 digitalWrite(SEG_G, 0);96 digitalWrite(SEG_F, 0);97 digitalWrite(SEG_E, 0);98 digitalWrite(SEG_D, 0);99 digitalWrite(SEG_C, 0);100 digitalWrite(SEG_B, 0);101 digitalWrite(SEG_A, 0);102}103 104void count_down() {105 if (st == 1) {106 timecount--;107 }108}109 110 111void loop() {112 static unsigned long clicked = 0; // スイッチ押し始めの時刻113 static unsigned long last_beat = 0; // キーリピートした時刻114 unsigned int now; // 現在時刻115 unsigned int tmp; // 10 進数に変換するための一時変数116 int tmp_sw[4]; // 一時的に読み取った値を保持117 byte current_sw[4] ; // 現在のスイッチの状態を保持118 static byte last_sw[] = {0, 0, 0, 0}; // 一つ前のスイッチの状態を保持119 static byte digit[] = {0, 0, 0, 0}; // 各スイッチに対応する値を保持120 byte i; // ループ制御変数121 const unsigned long repeat_delay = 1000;122 const unsigned long interval = 200;123 124 now = millis(); // 現在時刻を記憶125 126 // 統一して扱うために全てアナログで読む。127 // index と表示位置の関係は一対一。 0 右端の桁、3 左端の桁128 tmp_sw[0] = analogRead(A2);129 tmp_sw[1] = analogRead(A3);130 tmp_sw[2] = analogRead(A6);131 tmp_sw[3] = analogRead(A7);132 133 if (st == 0) {134 for (i = 0; i <= 3; i++) { // 全てのタクトスイッチ(桁)について135 // 読み取った値が閾値以上なら current_sw[i] の値を 1 にする。136 if (200 <= tmp_sw[i]) {137 current_sw[i] = 1;138 } else {139 current_sw[i] = 0;140 }141 last_sw[i] = current_sw[i]; // 一つ前のキーの値を今の値で更新142 143 switch (i) {144 case 0:145 if (last_sw[i] == 0 && current_sw[i] == 1) {146 // カウントダウン開始147 st = 1;148 }149 break;150 151 case 1:152 if (last_sw[i] == 0 && current_sw[i] == 1) {153 // timecountのインクリメント154 timecount += 1;155 clicked = now;156 }157 if (last_sw[i] == 1 && current_sw[i] == 1) {158 if ( repeat_delay <= now - clicked && interval <= now - last_beat ) {159 timecount += 1;160 last_beat = now;161 }162 }163 break;164 165 case 2:166 if (last_sw[i] == 0 && current_sw[i] == 1 && timecount > 0) {167 // timecountのディクリメント168 timecount -= 1;169 clicked = now;170 }171 if (last_sw[i] == 1 && current_sw[i] == 1 && timecount > 0 ) {172 if ( repeat_delay <= now - clicked && interval <= now - last_beat ) {173 timecount -= 1;174 last_beat = now;175 }176 }177 break;178 }179 }180 }181 182 if ( st == 1) {183 if (last_sw[0] == 0 && current_sw[0] == 1 && timecount > 0) {184 // 時間設定モードになる185 st = 0;186 }187 }188 189 190 /**********************************************************/191 /***** ここで count の値を 4 桁の 7segment LED に表示 *****/192 /**********************************************************/193 tmp = timecount % 3600;194 195 unsigned int minu = tmp / 60;196 digit[3] = minu / 10;197 minu -= digit[3] * 10;198 digit[2] = minu;199 200 unsigned int sec = tmp - minu * 60;201 digit[1] = sec / 10;202 sec -= digit[1] * 10;203 digit[0] = sec;204 205 if (st == 1 && timecount == 0) {206 st = 2;207 if (st == 2) {208 tone(2, melody[0].frequency); // 音を出力209 delay(melody[0].duration);210 noTone(2);211 st = 0;212 }213 }214 215 for (i = 0; i <= 3; i++) { // ここがダイナミック点灯の部分216 write_a_digit(i, digit[i]); // 一桁出力217 delay(1);218 clear_7seg(); // 一度全セグメントを消灯する。219 // delayMicrosecond(10);220 }221}

コメントを投稿

0 コメント