1 x Arduino nano
1 x Breadboard
1 x TD62083AP(Transistor Array)
3 x 7 segment led(Common cathode)
8 x register 220ohm
1 x Electric buzzer
まず、 loop() 内でLED表示ルーチンを回す方法から。
表示をし続けるためには、ループの中にLED表示ルーチンを含めておく必要があります。
// **************************************** // * 7seg LED * // * 2009/02/06 - 2015/04/09 * // * juncoffee * // **************************************** const int led_pin = 13; // 確認用LED接続ピン番号 // pin Digital I/O const int led_cathode[3] = { 10, 11, 12 }; // 7segLED カソード・ピン番号 const int led_anode[8] = { 2, 3, 4, 5, 6, 7, 8, 9 }; // 7segLED アノード・ピン番号 const byte led_7seg_data[19] = // セグメントデータ(値:表示パターン) // dp. g - a { B00111111, // 0:0 B00000110, // 1:1 B01011011, // 2:2 B01001111, // 3:3 B01100110, // 4:4 B01101101, // 5:5 B01111101, // 6:6 B00100111, // 7:7 B01111111, // 8:8 B01101111, // 9:9 B01110111, // 10:A B01111100, // 11:b B01011000, // 12:c B01011110, // 13:d B01111001, // 14:E B01110001, // 15:F // dp. g - a B10000000, // 16: [.] B11111111, // 17: [8.] B00000000 }; // 18:[blank] // 7seg_LED volatile byte digit_data[3] = {B11111111, B11111111, B11111111}; // 表示データ(3桁分)[8.][8.][8.] // LED long led_timer; // LED点灯終了時間 // 時間処理用 long disp_timer; // 時間表示処理用 long start_timer; // 開始時間 long onesec_timer; // 警報出力時間 int minute_u; // 分(一位:0-9) int second_t; // 秒(十位:0-5) int second_u; // 秒(一位:0-9) long rahmen_timer = 180000; // ラーメンタイマー(3分:3x60x1000=180000msec) long tornado_timer = 0; // 竜巻タイマー int pattern = 0; int led_digit = 0; void setup() { pinMode(led_pin, OUTPUT); // 動作チェック用LED→出力 for (int i=0; i<3; i++) { pinMode(led_cathode[i], OUTPUT); // 7segLEDカソード→出力 } for (int i=0; i<8; i++) { pinMode(led_anode[i], OUTPUT); // 7segLEDアノード→出力 } // -------------------- [8.][8.][8.]表示のためのディレイ // delay(3000); // -------------------- テストパターンの表示 onesec_timer = millis(); // 開始後すぐに処理実行 while (pattern <= 15) { // パターンは0-15 if (onesec_timer <= millis()) { // 実行時間? // ----------------------------- 7segLED表示データ設定 digit_data[0] = led_7seg_data[pattern]; digit_data[1] = led_7seg_data[pattern + 1]; digit_data[2] = led_7seg_data[pattern + 2]; pattern++; // パターンを+1する onesec_timer += 100; // 0.1秒後に再度処理を実行する } digitalWrite(led_cathode[led_digit], LOW); // カソード出力:OFF if (++led_digit > 2) led_digit = 0; for (int i=0; i<8; i++) { // 各セグメント分繰り返し digitalWrite(led_anode[i], bitRead(digit_data[led_digit],i) == 0 ? LOW : HIGH); // セグメントのビット状態でアノード出力をON/OFF } digitalWrite(led_cathode[led_digit], HIGH); // カソード出力:ON delay(2); // 輝度確保のディレイ } // -------------------- テストパターン終了/ディレイ digitalWrite(led_pin, HIGH); // 確認用LEDを点灯 delay(1000); digitalWrite(led_pin, LOW); // 確認用LEDを消灯 // -------------------- タイマー関連変数のリセット reset_timer(30000); // 180000 (3分:3x60x1000=180000msec) } void loop() { // -------------------- 7segLED表示 digitalWrite(led_cathode[led_digit], LOW); // カソード出力:OFF if (++led_digit > 2) led_digit = 0; for (int i=0; i<8; i++) { // 各セグメント分繰り返し digitalWrite(led_anode[i], bitRead(digit_data[led_digit],i) == 0 ? LOW : HIGH); // セグメントのビット状態でアノード出力をON/OFF } digitalWrite(led_cathode[led_digit], HIGH); // カソード出力:ON delay(2); // 輝度確保のディレイ // -------------------- LED点滅 if (led_timer > millis()) digitalWrite(led_pin, HIGH); // 確認用LEDを点灯 else digitalWrite(led_pin, LOW); // 確認用LEDを消灯 // -------------------- 一秒ごとの処理 if (onesec_timer <= millis()) { // 一秒経過していたら・・・ disp_timer = onesec_timer - start_timer; // 経過時間の計算 if(disp_timer >= 960000) { // 960秒(16分)でリセット reset_timer(180000); // 180000 (3分:3x60x1000=180000msec) } minute_u = int((disp_timer / 60000) % 16); // 分(一位)0-15(0-F) second_t = int((disp_timer / 10000) % 6); // 秒(十位) second_u = int((disp_timer / 1000) % 10); // 秒(一位) // ------------------ 7segLED表示データ設定 digit_data[0] = led_7seg_data[minute_u]; // 分 digit_data[1] = led_7seg_data[second_t]; // 十秒 digit_data[2] = led_7seg_data[second_u]; // 秒 // -------------------- LED点灯 if (led_timer < onesec_timer) led_timer = onesec_timer + 10; // LEDが消灯中なら、次の消灯時間を設定 // -------------------- ラーメンタイマー動作 if (rahmen_timer > 0 && disp_timer >= rahmen_timer) { led_timer = onesec_timer + 5000; // ラーメンが出来たら5秒間LEDを点灯する tornado_timer = onesec_timer + 10000; // 10秒間@@@竜巻表示 rahmen_timer = 0; // ラーメンタイマー動作停止 } onesec_timer += 1000; // 一秒後を設定 } // ---------------------- 竜巻@@@表示 if (tornado_timer > millis()) { // ---------------------- 7segLED表示データ設定 for(int i = 0; i < 3; i++) { digit_data[i] = led_7seg_data[0]; // [0] bitClear(digit_data[i], ((millis() / 100) + i) % 6); // アノード#0-#5の一つをLOWにする } } } void reset_timer(long rahmen) { start_timer = millis(); // スタート時間の保存 onesec_timer = start_timer + 1000; // 一秒後に処理実行 disp_timer = 0; // 経過時間の計算 minute_u = 0; // 分(一位) second_t = 0; // 秒(十位) second_u = 0; // 秒(一位) rahmen_timer = rahmen; // ラーメンタイマー設定 tornado_timer = 0; // 竜巻タイマー // ----------------------- 7segLED表示データ設定 digit_data[0] = led_7seg_data[minute_u]; // 分 digit_data[1] = led_7seg_data[second_t]; // 十秒 digit_data[2] = led_7seg_data[second_u]; // 秒 }
次に、割り込みを使ってLED表示をする方法。
LED表示用のデータをセットしておくだけですから、かなり楽です。
// **************************************** // * 7seg LED (割り込みバージョン) * // * 2009/02/06 - 2015/04/09 * // * juncoffee * // **************************************** const int led_pin = 13; // 確認用LED接続ピン番号 // pin Digital I/O const int led_cathode[3] = { 10, 11, 12 }; // 7segLED カソード・ピン番号 const int led_anode[8] = { 2, 3, 4, 5, 6, 7, 8, 9 }; // 7segLED アノード・ピン番号 const byte led_7seg_data[19] = // セグメントデータ(値:表示パターン) // dp. g - a { B00111111, // 0:0 B00000110, // 1:1 B01011011, // 2:2 B01001111, // 3:3 B01100110, // 4:4 B01101101, // 5:5 B01111101, // 6:6 B00100111, // 7:7 B01111111, // 8:8 B01101111, // 9:9 B01110111, // 10:A B01111100, // 11:b B01011000, // 12:c B01011110, // 13:d B01111001, // 14:E B01110001, // 15:F // dp. g - a B10000000, // 16: [.] B11111111, // 17: [8.] B00000000 }; // 18:[blank] // 7seg_LED volatile byte digit_data[3] = {B11111111, B11111111, B11111111}; // 表示データ(3桁分)[8.][8.][8.] // LED long led_timer; // LED点灯終了時間 // 時間処理用 long disp_timer; // 時間表示処理用 long start_timer; // 開始時間 long onesec_timer; // 警報出力時間 int minute_u; // 分(一位:0-9) int second_t; // 秒(十位:0-5) int second_u; // 秒(一位:0-9) long rahmen_timer = 180000; // ラーメンタイマー(3分:3x60x1000=180000msec) long tornado_timer = 0; // 竜巻タイマー int pattern = 0; // テストパターン先頭番号 void setup() { // -------------------- 出力端子の設定 pinMode(led_pin, OUTPUT); // 動作チェック用LED→出力 // -------------------- カソード用端子 for (int i=0; i<3; i++) { pinMode(led_cathode[i], OUTPUT); // 7segLEDカソード→出力 } // -------------------- アノード用端子 for (int i=0; i<8; i++) { pinMode(led_anode[i], OUTPUT); // 7segLEDアノード→出力 } // -------------------- 割り込みの設定~~~ここから7segLEDの表示開始~~~ OCR2A = 249; // 250クロックごとに割り込みをかける TCCR2B = B101; // clkT2S / 128 (プリスケーラ出力) bitWrite(TIMSK2, OCIE2A, 1); // タイマー/カウンター2 比較一致A 割り込みイネーブル // -------------------- [8.][8.][8.]表示のためのディレイ delay(1000); // -------------------- テストパターンの表示 onesec_timer = millis(); // 最初に処理実行 while (pattern <= 15) { // パターンは0-15 if (onesec_timer <= millis()) { // 実行時間? // ----------------------------- 7segLED表示データ設定 digit_data[0] = led_7seg_data[pattern]; digit_data[1] = led_7seg_data[pattern + 1]; digit_data[2] = led_7seg_data[pattern + 2]; pattern++; // パターンを+1する onesec_timer += 100; // 0.1秒後に再度処理を実行する } } // ----------------------- 7segLED表示データ設定 digit_data[0] = led_7seg_data[17]; // [8.]分 digit_data[1] = led_7seg_data[17]; // [8.]十秒 digit_data[2] = led_7seg_data[17]; // [8.]秒 // -------------------- テストパターン終了/ディレイ digitalWrite(led_pin, HIGH); // 確認用LEDを点灯 delay(1000); digitalWrite(led_pin, LOW); // 確認用LEDを消灯 // -------------------- タイマー関連変数のリセット reset_timer(30000); // 180000 (3分:3x60x1000=180000msec) } void loop() { // ----------------------- LED点滅 if (led_timer > millis()) digitalWrite(led_pin, HIGH); // 確認用LEDを点灯 else digitalWrite(led_pin, LOW); // 確認用LEDを消灯 // ----------------------- 一秒ごとの処理 if (onesec_timer <= millis()) { // 一秒経過していたら・・・ disp_timer = onesec_timer - start_timer; // 経過時間の計算 if(disp_timer >= 600000) { // 600秒(10分)でリセット reset_timer(180000); // 180000 (3分:3x60x1000=180000msec) } minute_u = int((disp_timer / 60000) % 16); // 分(一位)0-15(0-F) second_t = int((disp_timer / 10000) % 6); // 秒(十位) second_u = int((disp_timer / 1000) % 10); // 秒(一位) // ----------------------- 7segLED表示データ設定 digit_data[0] = led_7seg_data[minute_u]; // 分 digit_data[1] = led_7seg_data[second_t]; // 十秒 digit_data[2] = led_7seg_data[second_u]; // 秒 // ----------------------- LED点灯 if (led_timer < onesec_timer) led_timer = onesec_timer + 10; // LEDが消灯中なら、次の消灯時間を設定 // ----------------------- ラーメンタイマー動作 if (rahmen_timer > 0 && disp_timer >= rahmen_timer) { led_timer = onesec_timer + 5000; // ラーメンが出来たら5秒間LEDを点灯する tornado_timer = onesec_timer + 10000; // 10秒間@@@竜巻表示 rahmen_timer = 0; // ラーメンタイマー動作停止 } onesec_timer += 1000; // 一秒後を設定 } // ----------------------- 竜巻@@@表示 if (tornado_timer > millis()) { // ----------------------- 7segLED表示データ設定 for(int i = 0; i < 3; i++) { digit_data[i] = led_7seg_data[0]; // [0] bitClear(digit_data[i], ((millis() / 100) + i) % 6); // アノード#0-#5の一つをLOWにする } } } // ----------------------- 割り込み時の動作を定義 ISR(TIMER2_COMPA_vect) { set_7segled(); // 7segLED表示ルーチンを呼び出す } // ----------------------- 7segLED表示ルーチン void set_7segled() { static int led_digit = 2; // 表示中の桁位置(0-2) // ----------------------------------------- 7segLED表示 digitalWrite(led_cathode[led_digit], LOW); // カソード出力:OFF if (++led_digit > 2) led_digit = 0; for (int i=0; i<8; i++) { // 各セグメント分繰り返し digitalWrite(led_anode[i], bitRead(digit_data[led_digit],i) == 0 ? LOW : HIGH); // セグメントのビット状態でアノード出力をON/OFF } digitalWrite(led_cathode[led_digit], HIGH); // カソード出力:ON } void reset_timer(long rahmen) { start_timer = millis(); // スタート時間の保存 onesec_timer = start_timer + 1000; // 一秒後に処理実行 disp_timer = 0; // 経過時間の計算 minute_u = 0; // 分(一位) second_t = 0; // 秒(十位) second_u = 0; // 秒(一位) rahmen_timer = rahmen; // ラーメンタイマー設定 tornado_timer = 0; // 竜巻タイマー // ----------------------- 7segLED表示データ設定 digit_data[0] = led_7seg_data[minute_u]; // 分 digit_data[1] = led_7seg_data[second_t]; // 十秒 digit_data[2] = led_7seg_data[second_u]; // 秒 }