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]; // 秒
}
