Raspberry Piで電子工作(5) 4桁7セグメントLED

今回は、前回の7セグディスプレイを拡張した、4桁7セグメントLEDを使用して、カウンターを作成したいと思う。

必要なもの

4桁7セグメントLED

7セグメントLEDが4桁分表示できるものである。

ただし、1度に4桁すべてを表示することはできない。そこで、1桁ずつONとOFFを高速で切り替える作業を指定された時間だけループさせることによって、あたかも4桁同時に表示させているように見せている。

端子は以下の3つに分類される

アノードコモンのため、論理が反転し、0で点灯となることに注意する。

今回製作する回路

今回は以下のように接続した。

作成したプログラム

#include <wiringPi.h>
#include <time.h>
#include <math.h>

int main(void) {
    // 外側が表示させる数字、内側がa~gの信号出力
    int num[10][7] = {
        {0, 0, 0, 0, 0, 0, 1}, // 0
        {1, 0, 0, 1, 1, 1, 1}, // 1
        {0, 0, 1, 0, 0, 1, 0}, // 2
        {0, 0, 0, 0, 1, 1, 0}, // 3
        {1, 0, 0, 1, 1, 0, 0}, // 4
        {0, 1, 0, 0, 1, 0, 0}, // 5
        {0, 1, 0, 0, 0, 0, 0}, // 6
        {0, 0, 0, 1, 1, 1, 1}, // 7
        {0, 0, 0, 0, 0, 0, 0}, // 8
        {0, 0, 0, 0, 1, 0, 0}  // 9
    };
    int i = 0; // カウント用(最大9999)
    int start; // 時間制御用
    int pw; // 桁数調節用

    wiringPiSetup();
    // a~gのビットを出力に設定し、HIGH(1)で初期化
    for (int count = 21; count < 28; count++) {
        pinMode(count, OUTPUT);
        digitalWrite(count, HIGH);
    }
    // 桁数を指定する端子を出力に設定し、LOW(0)で初期化
    for (int count = 2; count < 6; count++) {
        pinMode(count, OUTPUT);
        digitalWrite(count, LOW);
    }

    // 開始時間を初期化
    start = (int)time(NULL);

    // 数字が9999になるまで繰り返す
    while (i <= 9999) {
        // 表示する桁を指定(下位桁から表示)
        for (int count = 5; count > 1; count--) {
            // HIGHにして、指定された桁を表示
            digitalWrite(count, HIGH);
            // 指定された桁のセグメントを1つずつ点灯
            for (int seg = 21; seg < 28; seg++) {
                // 1の位から順番に
                pw = (int)pow(10, (5 - count));
                // 表示させる数字を指定して、セグメントに0(LOW)を指定
                digitalWrite(seg, num[i % (pw * 10) / pw][seg - 21]);
            }
            // 1ms待ち
            delay(1);
            // 現在の桁の表示を消灯
            digitalWrite(count, LOW);
        }
        // while文実行から1秒経っていたら次の数字に進める
        if (((int)time(NULL) - start) >= 1) {
            i++;
            // 時間のリセット
            start = (int)time(NULL);
        }
    }
    return 0;
}

コンパイル時の注意

このプログラムでは、math.hのpow()関数を使うため、コンパイルするときにオプションとして、-lmを付ける必要がある。

プログラムの説明

  1. 各セグメントの点灯組み合わせを格納した配列num、カウント用変数i、時間測定用start、桁数指定用変数pwを初期化する。(7~21行目)
  2. セグメント指定ピンと桁指定ピンを初期化する。(24~33行目)
  3. 現在の時間を開始時間に指定する。(36行目)
  4. while文で、数字が9999になるまで繰り返す。(39行目~)
  5. for文で桁指定する。1の位から順番に割り当てたかったが、今回は逆に接続してしまったため、逆(最後のピン)からfor文を回して、下位桁からになるようにしている。(41行目~)
  6. 次の行で、指定されたピンをHIGHにし、表示の準備をする。(42行目)
  7. 内側のfor文で、セグメントの情報を順番に送っている。
    i % (pw * 10) / pwは、指定された桁の数を抜き出すための計算である。
    seg - 21は、配列のインデックスが、0~7に合わせるための計算である。
  8. delay(1)は、処理時間を調節するためのものである。(52行目)
  9. 外側for文の最後で、表示を終了している。(54行目)
  10. このままだと、あっという間にカウントしてしまうので、time関数で時間を計測し、 1秒経つまでは同じ数字を表示し続け、1秒経ったら、次の番号に進むようにしてある。(57~61行目)
    この処理を追加することで、やっと目で見えるようになる。


トップページに戻る