7セグメントLED表示器を使ってみよう

7セグメントLED表示器

7つのLEDが8の字型に構成されていて、個々の部分をon/offすることによって数字などを表示させるものです。正確に言うと、小数点も含めて8個のLEDが内蔵されています。
下図のようにカソード側(cathode、マイナスに接続する方)を共通にするタイプをカソードコモン型、アノード側(anode、+電源Vccに接続する方)を共通にするタイプをアノードコモン型といいます。通常の数字を表示する場合は、A,B,C,D,E,D,Gにそれぞれ制限抵抗をつないでそこに流れる電流を制御します。例えば、一つのLEDに流れる電流の大きさをIとした場合、1を表示するときには2つのLEDに電流を流すので、共通端子には2Iの電流が流れます。また、8を表示するときには、7つのLEDに電流を流すので、共通端子には7Iの電流が流れます。
ここで、考え方を変えて、省エネ対策として全部のLEDを同時に点灯させるのではなく、一度に一つのみを点灯させるようにすれば、一時にはIの電流しか流れません。従って、制限抵抗も7本必要ではなく、たったの1本のみで点灯させることができます。つまり、抵抗はコモン側につけることになります。このような点灯方法をダイナミック点灯といいます。これをソフトウェアのみで実現してみます。

原理的にこのスイッチングを停止した場合、一か所だけ点灯するか、全て消灯します。従って、うまく使わないと実用的ではありません。



上から見たときのピンと機能の図



SevenSegmentLED.h
#include "mbed.h"

class SevenSegmentLED
{
  private:
    DigitalOut *LED_ON;
    DigitalOut *LED_G;
    DigitalOut *LED_F;
    DigitalOut *LED_A;
    DigitalOut *LED_B;
    DigitalOut *LED_E;
    DigitalOut *LED_D;
    DigitalOut *LED_C;
    Timer t;
    static const short zero[7];
    static const short one[3];
    static const short two[6];
    static const short three[6];
    static const short four[5];
    static const short five[6];
    static const short six[7];
    static const short seven[4];
    static const short eight[8];
    static const short nine[6];

    static const short *leds[10];
    short *led;
    short zeroValue, oneValue;

    void pinSetting(PinName pin[], bool cathode);

  public:
    SevenSegmentLED();
    SevenSegmentLED(PinName pin[], bool cathode);
    void clear();
    void show(int n, int time);
};
 1 
 2 
 3 
 4 
 5 
 6 オブジェクトを指すポインタ
 7 
 8 
 9 
10 
11 
12 
13 
14 タイマー
15 セグメント定数データ
16 クラスで共通な変数
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 10種類のセグメントデータ
27 使用する時に用いる変数
28 カソードコモン、アノードコモンで値を変更する
29 
30 接続ピンの設定
31 
32 
33 デフォールトコンストラクタ
34 引数付きコンストラクタ
35 消灯
36 数字nをtimeミリ秒表示
37 




SevenSegmentLED.cpp
#include "SevenSegmentLED.h"

SevenSegmentLED::SevenSegmentLED(PinName pin[], bool cathode)
{
  pinSetting(pin, cathode);
}

void SevenSegmentLED::pinSetting(PinName pin[], bool cathode)
{
  LED_ON= new DigitalOut(pin[0]);
  LED_G = new DigitalOut(pin[1]);
  LED_F = new DigitalOut(pin[2]);
  LED_A = new DigitalOut(pin[3]);
  LED_B = new DigitalOut(pin[4]);
  LED_E = new DigitalOut(pin[5]);
  LED_D = new DigitalOut(pin[6]);
  LED_C = new DigitalOut(pin[7]);

  if(cathode) {
    oneValue = 1;   // cathode common
    zeroValue = 0;
  }
  else {
    oneValue = 0;   // anode common
    zeroValue = 1;
  }
}
SevenSegmentLED::SevenSegmentLED()
{
  PinName pin[]={p13,p14,p15,p16,p17,p18,p19,p20};
  pinSetting(pin, true); // cathode common
  clear();
}
const short SevenSegmentLED::zero[7] = {7, 0,1,2,3,4,5};
const short SevenSegmentLED::one[3] = {3, 1,2};
const short SevenSegmentLED::two[6] = {6, 0, 1, 6, 4, 3};
const short SevenSegmentLED::three[6] = {6, 0, 1, 2, 3, 6};
const short SevenSegmentLED::four[5] = {5, 1, 2, 5, 6};
const short SevenSegmentLED::five[6] = {6, 0, 5, 6, 2, 3};
const short SevenSegmentLED::six[7] = {7, 0,2,3,4,5, 6};
const short SevenSegmentLED::seven[4] = {4, 0,1,2};
const short SevenSegmentLED::eight[8] = {8, 0,1,2,3,4,5,6};
const short SevenSegmentLED::nine[6] = {6, 0,1,2,5,6};

const short* SevenSegmentLED::leds[10] = {
      zero, one, two, three, four, five, six,seven,eight,nine
};

void SevenSegmentLED::clear()
{
  *LED_ON = oneValue;
  *LED_G = zeroValue;
  *LED_F = zeroValue;
  *LED_A = zeroValue;
  *LED_B = zeroValue;
  *LED_E = zeroValue;
  *LED_D = zeroValue;
  *LED_C = zeroValue;
}

void SevenSegmentLED::show(int n, int time)
{
  int i;
  t.reset();
  t.start();
  *LED_ON = zeroValue;
  while(t.read_ms()<time ) {
    led = (short int*)leds[n];
    for(i=1; i<led[0]; i++)
    {
      switch(led[i])
      {
         case 0:
           *LED_A = oneValue;wait_ms(1);
           *LED_A = zeroValue;break;
         case 1:
           *LED_B = 1;wait_ms(1);
           *LED_B = zeroValue;break;
         case 2:
           *LED_C = 1;wait_ms(1);
           *LED_C = zeroValue;break;
         case 3:
           *LED_D = 1;wait_ms(1);
           *LED_D = zeroValue;break;
         case 4:
           *LED_E = oneValue;wait_ms(1);
           *LED_E = zeroValue;break;
         case 5:
           *LED_F = oneValue;wait_ms(1);
           *LED_F = zeroValue;break;
         case 6:
           *LED_G = oneValue;wait_ms(1);
           *LED_G = zeroValue;break;
      } // switch
    } //for
  } // while
  *LED_ON = oneValue;
}
 1 
 2 
 3 引数付きコンストラクタ
 4 
 5 接続ピンの設定
 6 
 7 
 8 接続ピンの設定
 9 
10 各ピンのオブジェクトを作り
11 そのアドレスをポインタに入れる
12 
13 
14 
15 
16 
17 
18 
19 カソードコモンだったらば
20 
21 
22 
23 
24 
25 
26 
27 
28 デフォールトコンストラクタ
29 LED_ON,G,F,A,B,E,D,Cの順番でPinName配列に入れる
30 後ろの変数にはカソードコモンかどうかのbool値
31 以上の設定を行う
32 
33 
34 データの初期設定
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 データ配列
46 
47 
48 
49 消灯メソッド
50 
51 
52 
53 
54 
55 
56 
57 
58 
59 
60 
61 数字nをtimeミリ秒表示
62 
63 
64 時間計測のためタイマーのリセット
65 タイマースタート
66 コモン端子を表示にする
67 表示時間だけ表示する
68 数字nの表示データ配列の取得
69 0番目は配列の大きさ
70 
71 データでどこを点灯させるか判断する
72 
73 
74 1ミリ秒だけセグメントを点灯させる
75 すぐに消灯させる
76 
77 
78 
79 
80 
81 
82 
83 
84 
85 
86 
87 
88 
89 
90 
91 
92 
93 
94 
95 
96 
97 消灯する
98 
99




main.cpp
#include "mbed.h"
#include "SevenSegmentLED.h"

int main()
{
  // SevenSegmentLED segment;
  PinName pin[]={p13,p14,p15,p16,p17,p18,p19,p20};
  SevenSegmentLED segment(pin, true);
  int time=1000;
  while(true)
  {
    for(int i=0; i<10; i++)
      segment.show(i, time);
  }
}
 1 
 2 
 3 
 4 
 5 
 6 デフォールトの設定で接続する場合
 7 任意のピンに接続する場合
 8 trueはカソードコモンを用いるという意味
 9 1秒ごとに数字を変える
10 無限に続ける
11 
12 0~9までの数字を
13 表示させる
14 
15 


2桁表示に改造する

2桁繋がっている7セグメント表示器を用いてみます。完成写真は下のようになります。
カソードコモンであるKNR261を用いています。

上から見たときのピンと機能の図




SevenSegmentLED.h
#include "mbed.h"

class SevenSegmentLED
{
  private:
    DigitalOut *LED_ON1; // 上の桁
    DigitalOut *LED_ON2;
    DigitalOut *LED_G;
    DigitalOut *LED_F;
    DigitalOut *LED_A;
    DigitalOut *LED_B;
    DigitalOut *LED_E;
    DigitalOut *LED_D;
    DigitalOut *LED_C;
    Timer t;
    static short zero[7];
    static short one[3];
    static short two[6];
    static short three[6];
    static short four[5];
    static short five[6];
    static short six[7];
    static short seven[4];
    static short eight[8];
    static short nine[6];

    static short *leds[10];
    short *led;
    short zeroValue, oneValue;

    void pinSetting(PinName pin[], bool cathode);
    void disp(int n, int digit);

  public:
    SevenSegmentLED();
    SevenSegmentLED(PinName pin[], bool cathode);
    void clear();
    void show(int n, int time);
};




SevenSegmentLED.cpp
#include "SevenSegmentLED.h"

SevenSegmentLED::SevenSegmentLED(PinName pin[], bool cathode)
{
  pinSetting(pin, cathode);
}

// 2桁用
void SevenSegmentLED::pinSetting(PinName pin[], bool cathode)
{
  LED_ON1= new DigitalOut(pin[0]);
  LED_ON2= new DigitalOut(pin[1]);
  LED_G = new DigitalOut(pin[2]);
  LED_F = new DigitalOut(pin[3]);
  LED_A = new DigitalOut(pin[4]);
  LED_B = new DigitalOut(pin[5]);
  LED_E = new DigitalOut(pin[6]);
  LED_D = new DigitalOut(pin[7]);
  LED_C = new DigitalOut(pin[8]);

  if(cathode) {
    oneValue = 1;   // cathode common
    zeroValue = 0;
  }
  else {
    oneValue = 0;   // anode common
    zeroValue = 1;
  }
}

SevenSegmentLED::SevenSegmentLED()
{
  //             ON1,ON2, G,  F,  A,  B,  E,  D,  C
  PinName pin[]={p12,p13,p14,p15,p16,p17,p18,p19,p20};
  pinSetting(pin, true); // cathode common
  clear();
}

short SevenSegmentLED::zero[7] = {7, 0,1,2,3,4,5};
short SevenSegmentLED::one[3] = {3, 1,2};
short SevenSegmentLED::two[6] = {6, 0, 1, 6, 4, 3};
short SevenSegmentLED::three[6] = {6, 0, 1, 2, 3, 6};
short SevenSegmentLED::four[5] = {5, 1, 2, 5, 6};
short SevenSegmentLED::five[6] = {6, 0, 5, 6, 2, 3};
short SevenSegmentLED::six[7] = {7, 0,2,3,4,5, 6};
short SevenSegmentLED::seven[4] = {4, 0,1,2};
short SevenSegmentLED::eight[8] = {8, 0,1,2,3,4,5,6};
short SevenSegmentLED::nine[6] = {6, 0,1,2,5,6};


short* SevenSegmentLED::leds[10] = {
      zero, one, two, three, four, five, six,seven,eight,nine
    };

void SevenSegmentLED::clear()
{
  *LED_ON1 = oneValue;
  *LED_ON2 = oneValue;
  *LED_G = zeroValue;
  *LED_F = zeroValue;
  *LED_A = zeroValue;
  *LED_B = zeroValue;
  *LED_E = zeroValue;
  *LED_D = zeroValue;
  *LED_C = zeroValue;
}

void SevenSegmentLED::show(int n, int time)
{
  int high=n/10;
  int low =n%10;
  t.reset();
  t.start();
  while(t.read_ms()<time ) {
    disp(low, 0);
    disp(high,1);
  } // while
}

void SevenSegmentLED::disp(int n, int digit)
{
  led = leds[n];
  if(digit==0) *LED_ON2 = zeroValue;
  else if(digit==1) *LED_ON1 = zeroValue;
  for(int i=1; i<led[0]; i++)
  {
    switch(led[i])
    {
       case 0:
         *LED_A = oneValue;wait_ms(1);
         *LED_A = zeroValue;break;
       case 1:
         *LED_B = 1;wait_ms(1);
         *LED_B = zeroValue;break;
       case 2:
         *LED_C = 1;wait_ms(1);
         *LED_C = zeroValue;break;
       case 3:
         *LED_D = 1;wait_ms(1);
         *LED_D = zeroValue;break;
       case 4:
         *LED_E = oneValue;wait_ms(1);
         *LED_E = zeroValue;break;
       case 5:
         *LED_F = oneValue;wait_ms(1);
         *LED_F = zeroValue;break;
       case 6:
         *LED_G = oneValue;wait_ms(1);
         *LED_G = zeroValue;break;
    } // switch
  } //for
  if(digit==0) *LED_ON2 = oneValue;
  else if(digit==1) *LED_ON1 = oneValue;
}


main.cpp
#include "mbed.h"
#include "SevenSegmentLED.h"
// KNR261はカソードコモン
int main()
{
  // SevenSegmentLED segment;
  //             ON1, ON2, G,  F,  A,  B,  E,  D,  C
  PinName pin[]={p12, p13,p14,p15,p16,p17,p18,p19,p20};
  SevenSegmentLED segment(pin, true);
  int time=500;
  while(true)
  {
    for(int i=0; i<100; i++){
      segment.show(i, time);
    }
  }
}

カラーLEDもついでに光らせてみよう

下のように3つのタスクを走らせることも可能です。各自トライしてみてください。

下のビデオはカラーLEDが明るすぎて飽和してしまい白くなってしまっています。目で見ると綺麗に見えるのですが・・・。人間の目のダイナミックレンジとか自動調節機能が素晴らしいということです。