Arduino : 7seg LED を使う


らぅめんたいまぁ

らぅめんたいまぁ


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]; // 秒
}
カテゴリー: Arduino, Arduino, LEDを使った工作 パーマリンク