見出し画像

7seg+NANO(1)

7セグLEDでNANOからのコントロールを試みた。
1ケタの場合は7セグの8本の足をNANOに、コモンを5VまたはGNDに繋いだ。3ケタの場合は各ケタのコモンもNANOに繋いだ。ライブラリ SevSeg.h を使う方法も試みた。
どちらの方法もケタ数が3ケタのときはチラついたり暗くなったりした。


1 7seg、1ケタ

 arduinoNANO+7seg(1ケタ)
 7seg:C-551SRD 順電圧1.8V、順電流max30mA、カソードコモン
      R=E/I=(5-1.8)V/(1.5×10^(-3))A=213ohm
      220ohmで試したところ明るすぎるので、1kohmとする。
      このとき I=3.2V/1kohm=3.2×10^{-3}=3.2mA
      LED8個では 3.2mA×8=25.6mA
 カソードコモンをGNDに接続。

/* NANO_7seg_01.ini(1ケタ)

    Arduino NANO                         serial port is COM3 for hp_PC.
                  1・     ・VIN             3,11 is interfered by tone().
                  0・     ・GND             A6,A7 is analog only.
              Reset・     ・Reset
                GND・     ・5V                g f - a b
            c --> 2・     ・A7                ・ ・ ・ ・ ・    C-551SRD
           DP --> 3・     ・A6                    a          cathode common
            a --> 4・     ・19/A5                ___         1.8V  red
            b --> 5・     ・18/A4              f|   |b
            f --> 6・     ・17/A3               |_g_|
            g --> 7・     ・16/A2              e|   |c
            e --> 8・     ・15/A1               |___|  DP
            d --> 9・     ・14/A0                 d
                 10・     ・AREF              ・ ・ ・ ・ ・
                 11・     ・3.3V              e d - c DP
                 12・ USB ・13
*/

// 変数宣言
byte andData = { B10000000 };   // AND用基本データ
byte tmpData;   // AND用仮置き用変数
// セグメント表示用ピン情報
byte segData[12] = {
  B11111100,  // 0
  B01100000,  // 1
  B11011010,  // 2
  B11110010,  // 3
  B01100110,  // 4
  B10110110,  // 5
  B10111110,  // 6
  B11100100,  // 7
  B11111110,  // 8
  B11110110,  // 9
  B00000001,  // DP
  B11111111   // 全セグ表示
};
// 各セグ接続ピン番号(a,b,c,d,e,f,g,DP)
int pinData[8] = { 4, 5, 2, 9, 8, 6, 7, 3 };

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);   // シリアルポート設定(9600bps)

  // 使用ピン初期化
  for (int i = 0; i < 8; i++ ) {
    pinMode(pinData[i], OUTPUT);      // OUTPUT設定
    digitalWrite(pinData[i], LOW);   // アノードコモン:HIGH、カソードコモン:LOW
  }
}

void loop() {
  // put your main code here, to run repeatedly:
  // 0~9,DP,全セグ表示用ループ
  for (int i = 0; i < 12; i++ ) {
    // AND用基本データ準備
    tmpData = andData;
    // LOW,HIGHセグの選択(a~g,DP)
    for (int j = 0; j < 8; j++ ) {
      if ( segData[i] & tmpData ) {
        // 指定ビット位置が1の場合
        digitalWrite(pinData[j], HIGH);   // アノードコモン:LOW、カソードコモン:HIGH
        Serial.print( "1" );
      } else {
        // 指定ビット位置が0の場合
        digitalWrite(pinData[j], LOW);   // アノードコモン:HIGH、カソードコモン:LOW
        Serial.print( "0" );
      }
      // AND用基本データを1ビット右シフト
      tmpData = tmpData >> 1;
    }
    Serial.println( );
    delay( 1000 );  // 1000ms待機
  }
}

2 7seg、1ケタ、by SevSeg.h

 と同じ条件でライブラリ<SevSeg.h>を使ってみた。
 カソードコモンはPin1に接続。

/*
   NANO_7seg_SevSeg_01.ini(1ケタ)

    Arduino NANO                         serial port is COM3 for hp_PC.
  cathode com --> 1・     ・VIN             3,11 is interfered by tone().
                  0・     ・GND             A6,A7 is analog only.
              Reset・     ・Reset
                GND・     ・5V                g f - a b
            c --> 2・     ・A7                ・ ・ ・ ・ ・
           DP --> 3・     ・A6                    a
            a --> 4・     ・19/A5                ___
            b --> 5・     ・18/A4              f|   |b
            f --> 6・     ・17/A3               |_g_|
            g --> 7・     ・16/A2              e|   |c
            e --> 8・     ・15/A1               |___|  DP
            d --> 9・     ・14/A0                 d
                 10・     ・AREF              ・ ・ ・ ・ ・
                 11・     ・3.3V              e d - c DP
                 12・ USB ・13
*/

#include "SevSeg.h"
SevSeg digit; // 変数digitで制御

void setup() {
  byte numDigits = 1; // 桁数
  byte digitPins[] = {1}; // COM端子をつなぐピン
  // (a, b, c, d, e, f, g, DP)
  byte segmentPins[] = {4, 5, 2, 9, 8, 6, 7, 3 };
  bool resistorsOnSegments = true;
  //電流制限用の抵抗がA〜G・DP端子につながっているか?(COM端子の場合はfalse)
  byte hardwareConfig = COMMON_CATHODE; // カソードコモン
  digit.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments);
  digit.setBrightness(90);
}

void loop() {
  for (int i = 0; i < 10; i++) {
    digit.setNumber(i); // 表示したい数字
    digit.refreshDisplay(); // 表示の切り替え
    delay(1000);
  }
}

3 7seg、3ケタ、by SevSeg.h

 で<SevSeg.h>を使い方がわかったので3ケタに挑戦した。

 7seg:2831BS 順電圧1.8V、アノードコモン、1,2と同じ1kohmを使用
 comの接続 百位:pin8、十位:pin7、一位:pin6
 ところが、動作が遅くうまく表示しない。

/*
   NANO_7seg_SevSeg_02.ini(3ケタ)

   ★動作が遅い! ちゃんと表示しない

    Arduino NANO                         serial port is COM3 for hp_PC.
            g <-- 1・     ・VIN             3,11 is interfered by tone().
                  0・     ・GND             A6,A7 is analog only.
              Reset・     ・Reset
                GND・     ・5V                1 a f 1 1 b
            c <-- 2・     ・A7                ・ ・ ・ ・ ・ ・
                  3・     ・A6                    a        2831BS
           DP <-- 4・     ・19/A5                ___         anode common
            b <-- 5・     ・18/A4              f|   |b       1.8V red
          1位 <-- 6・     ・17/A3               |_g_|
         10位 <-- 7・     ・16/A2              e|   |c
        100位 <-- 8・     ・15/A1               |___|  DP
            a <-- 9・     ・14/A0                 d
            f <--10・     ・AREF              ・ ・ ・ ・
            d <--11・     ・3.3V              e d DP c
            e <--12・ USB ・13
*/

#include "SevSeg.h"
SevSeg digit; // 変数digitで制御

void setup() {
  //  Serial.begin(9600);
  byte numDigits = 3; // 桁数
  byte digitPins[] = {8, 7, 6}; // COM端子をつなぐピン
  // (a, b, c, d, e, f, g, DP)
  byte segmentPins[] = {9, 5, 2, 11, 12, 10, 1, 4 };
  bool resistorsOnSegments = true;
  //電流制限用の抵抗がA〜G・DP端子につながっているか?(COM端子の場合はfalse)
  byte hardwareConfig = COMMON_ANODE; // アノードコモン
  digit.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments);
  digit.setBrightness(90);//(90)
}

void loop() {
  for (int i = 0; i < 1000; i++) {
    //      Serial.println(i);
    digit.setNumber(i); // 表示したい数字
    digit.refreshDisplay(); // 表示の切り替え
    delay(1000);
  }

}

4 7seg、3ケタ、ライブラリなし

 3でうまくいかなかったので<SevSeg.h>なしでやってみた。
 やはりチラつく。
 2ケタではdelayを1msecにするとチラつかないが、3ケタではチラつく。
 50μsecまで小さくすると3ケタでもチラつかないが、暗くて見にくい。

 2ケタ( iPadで撮影、人間の眼と見え方が違う)

 3ケタ( iPadで撮影、人間の眼と見え方が違う)

/* NANO_7seg_02.ini(3ケタ)

    Arduino NANO                         serial port is COM3 for hp_PC.
            g <-- 1・     ・VIN             3,11 is interfered by tone().
                  0・     ・GND             A6,A7 is analog only.
              Reset・     ・Reset
                GND・     ・5V                + a f + + b
            c <-- 2・     ・A7                ・ ・ ・ ・ ・ ・
                  3・     ・A6                    a        2831BS
           DP <-- 4・     ・19/A5                ___         anode common
            b <-- 5・     ・18/A4              f|   |b       1.8V red
          1位 <-- 6・     ・17/A3               |_g_|
         10位 <-- 7・     ・16/A2              e|   |c
        100位 <-- 8・     ・15/A1               |___|  DP
            a <-- 9・     ・14/A0                 d
            f <--10・     ・AREF              ・ ・ ・ ・
            d <--11・     ・3.3V              e d DP c
            e <--12・ USB ・13
*/

// 変数宣言
byte andData = { B10000000 };   // AND用基本データ
byte tmpData;   // AND用仮置き用変数

byte segData[12] = {  // セグメント表示用ピン情報
  B11111100,  // 0
  B01100000,  // 1
  B11011010,  // 2
  B11110010,  // 3
  B01100110,  // 4
  B10110110,  // 5
  B10111110,  // 6
  B11100100,  // 7
  B11111110,  // 8
  B11110110,  // 9
  B00000001,  // DP
  B11111111   // 全セグ表示
};
// 各セグ接続ピン番号(a,b,c,d,e,f,g,DP)
int pinData[8] = { 9, 5, 3, 11, 12, 10, 2, 4 };

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);   // シリアルポート設定(9600bps)
  for (int i = 0; i < 8; i++ ) {    // 使用ピン初期化
    pinMode(pinData[i], OUTPUT);      // OUTPUT設定(a-DPの各ピンについて)
    digitalWrite(pinData[i], HIGH);   // アノードコモン:HIGH、カソードコモン:LOW
  }
  pinMode(8, OUTPUT); digitalWrite(8, LOW);
  pinMode(7, OUTPUT); digitalWrite(7, LOW);
  pinMode(6, OUTPUT); digitalWrite(6, LOW);
}

void disp_kazu(int i, int keta) {
  digitalWrite(6, LOW); digitalWrite(7, LOW); digitalWrite(8, LOW); // アノード・オフ
  tmpData = andData;  // AND用基本データ準備
  for (int j = 0; j < 8; j++ ) {  // LOW,HIGHセグの選択(a~g,DP)
    if ( segData[i] & tmpData ) {
      // 指定ビット位置が1の場合
      digitalWrite(pinData[j], LOW);   // アノードコモン:LOW、カソードコモン:HIGH
      Serial.print( "1" );
    } else {
      // 指定ビット位置が0の場合
      digitalWrite(pinData[j], HIGH);   // アノードコモン:HIGH、カソードコモン:LOW
      Serial.print( "0" );
    }
    // AND用基本データを1ビット右シフト
    tmpData = tmpData >> 1;
  }
  Serial.println(i);

  switch (keta) { // ケタに応じてアノードをオン
    case 1:
      digitalWrite(6, HIGH); break;
    case 10:
      digitalWrite(7, HIGH); break;
    case 100:
      digitalWrite(8, HIGH); break;
  }
}

void loop() {
  int t=50; // -32,768 <= int <= 32,768
  disp_kazu(3, 100); delayMicroseconds(t);  // 50usec にすると3ケタでも
  disp_kazu(5, 10); delayMicroseconds(t);   // チラつかないが、暗くて見にくい
  disp_kazu(0, 1); delayMicroseconds(t);  

  //  disp_kazu(3, 100); delay(1);  // delay(1); 3ケタにするとチラつく
  //  disp_kazu(5, 10); delay(1);
  //  disp_kazu(0, 1); delay(1);
}

まとめ

2ケタ以上の表示は各ケタを交替で点灯させる(ダイナミック点灯)のワザがあるが、表示がチラついたり暗かったりする。
暗くなることの対策として
・コモンの抵抗値を下げる → ケタ数が多いとNANOの最大出力を超えるかも
・トランジスタで増幅する
が考えられる。これらの方法はそのうち試みたい。

お世話になったサイト
 Arduinoで7セグメントディスプレイ(7セグLED)を制御する
 7セグメントLED表示器を使ってみる(Arduino)
 PICことはじめ~7セグメントLED