7 Segment (FND) 사용하기

FND의 종류#

  • FND는 Anode형과 Cathode형으로 분류되며, 이 중 Anode형이 주로 사용되고 있는데요. Anode형은 중앙핀이 VCC이며, Cathode형은 GND입니다. 우리가 사용하는 것은 5611BH로 Common Anode형입니다.

  • 7 Segment (FND)는 숫자나 문자를 표현하는 7개의 LED와 소수점을 표현하는 1개의 LED가 포함되어 있는 부품을 의미합니다. FND는 16X2 LCD와 비교할 때 표현할 수 있는 문자의 개수가 제한되고, 각 문자의 표현을 위하여 총 8개의 LED를 하나씩 조절해주어야 하는 등 사용이 복잡하다는 단점이 있습니다. 그렇지만, 전력소모가 적고 크기가 큰 Segment를 선택하면 비교적 큰 문자도 표현할 수 있다는 장점이 있어 다양한 용도로 사용되고 있습니다.


숫자표시 방법#


NumDPGFEDCBA2진수16진수
0110000000b110000000xC0
1111110010b111110010xF9
2101001000b101001000xA4
3101100000b101100000xB0
4100110010b100110010x99
5100100100b100100100x92
6100000100b100000100x82
7111110000b111110000xF8
8100000000b100000000x80
9100100000b100100000x90

10진수 숫자와의 구분을 위해 2진수 앞에는 0b, 16진수 앞에는 0x를 표기하고 16진수 표현에 있어서, 각 숫자에 소수점을 포함시키는 경우에는 80을 빼주면 됩니다. 예를 들어,

  • 0. → 0xC0 - 0x80 = 0x40
  • 1. → 0xF9 - 0x80 = 0x79
  • 2. → 0xA4 - 0x80 = 0x24
  • 3. → 0xB0 - 0x80 = 0x30
  • 4. → 0x99 - 0x80 = 0x19
  • 5. → 0x92 - 0x80 = 0x12
  • 6. → 0x82 - 0x80 = 0x12
  • 7. → 0xF8 - 0x80 = 0x78
  • 8. → 0x80 - 0x80 = 0x00
  • 9. → 0x90 - 0x80 = 0x10

Pin Map#

7 SegmentArduino
A2
B3
C4
D5
E6
F7
G8
DP9

schematic#

아래 회로에서는 330Ω 저항 1개를 VCC에 직접 연결하여 사용하였습니다. 상단부와 하단부 중앙핀은 서로 연결이 되어 있으므로, 둘 중 하나만 +5V에 연결하여 사용합니다.


주의 : 위 회로에서는 간단한 회로 구성을 위해 VCC에 저항을 직접 연결하여 사용하였으나, 이것이 좋은 방법은 아닙니다. FND의 각 LED가 직렬이 아닌 병렬로 연결되어 있는데, 이렇게 구성하는 경우 동일한 전류로 “1”를 표시할때는 2개의 Segment만 켜고, “8”을 표시할때는 7개의 Segment를 모두 키므로, 각 숫자마다 밝기의 차이가 생기길 수 있기 때문이죠. 실제 LED의 밝기에 미세한 변화가 생기는 것을 볼 수 있습니다.

이러한 문제를 해결하기 위해서는 각 LED마다 저항을 따로 사용하여야 합니다. 아래 그림과 같이 220~330Ω 저항 8개를 사용하는 것이 원칙이며, 이렇게 하면 밝기를 고르게 유지할 수 있습니다.


sketch : 0~9까지 차례대로 표시하기#

const int A = 2;
const int B = 3;
const int C = 4;
const int D = 5;
const int E = 6;
const int F = 7;
const int G = 8;
const int DP = 9;
int dt = 1000;

void setup() {
pinMode(A, OUTPUT);
pinMode(B, OUTPUT);
pinMode(C, OUTPUT);
pinMode(D, OUTPUT);
pinMode(E, OUTPUT);
pinMode(F, OUTPUT);
pinMode(G, OUTPUT);
pinMode(DP, OUTPUT);

// 7 Segment Ready
digitalWrite (A,HIGH);
digitalWrite (B,HIGH);
digitalWrite (C,HIGH);
digitalWrite (D,HIGH);
digitalWrite (E,HIGH);
digitalWrite (F,HIGH);
digitalWrite (G,HIGH);
digitalWrite (DP,HIGH);
}

void loop() {

// digit 0
digitalWrite (A,LOW);
digitalWrite (B,LOW);
digitalWrite (C,LOW);
digitalWrite (D,LOW);
digitalWrite (E,LOW);
digitalWrite (F,LOW);
digitalWrite (G,HIGH);
digitalWrite (DP,HIGH);
delay(dt);

// digit 1
digitalWrite (A,HIGH);
digitalWrite (B,LOW);
digitalWrite (C,LOW);
digitalWrite (D,HIGH);
digitalWrite (E,HIGH);
digitalWrite (F,HIGH);
digitalWrite (G,HIGH);
digitalWrite (DP,HIGH);
delay(dt);

// digit 2
digitalWrite (A,LOW);
digitalWrite (B,LOW);
digitalWrite (C,HIGH);
digitalWrite (D,LOW);
digitalWrite (E,LOW);
digitalWrite (F,HIGH);
digitalWrite (G,LOW);
digitalWrite (DP,HIGH);
delay(dt);

// digit 3
digitalWrite (A,LOW);
digitalWrite (B,LOW);
digitalWrite (C,LOW);
digitalWrite (D,LOW);
digitalWrite (E,HIGH);
digitalWrite (F,HIGH);
digitalWrite (G,LOW);
digitalWrite (DP,HIGH);
delay(dt);

// digit 4
digitalWrite (A,HIGH);
digitalWrite (B,LOW);
digitalWrite (C,LOW);
digitalWrite (D,HIGH);
digitalWrite (E,HIGH);
digitalWrite (F,LOW);
digitalWrite (G,LOW);
digitalWrite (DP,HIGH);
delay(dt);

// digit 5
digitalWrite (A,LOW);
digitalWrite (B,HIGH);
digitalWrite (C,LOW);
digitalWrite (D,LOW);
digitalWrite (E,HIGH);
digitalWrite (F,LOW);
digitalWrite (G,LOW);
digitalWrite (DP,HIGH);
delay(dt);

// digit 6
digitalWrite (A,LOW);
digitalWrite (B,HIGH);
digitalWrite (C,LOW);
digitalWrite (D,LOW);
digitalWrite (E,LOW);
digitalWrite (F,LOW);
digitalWrite (G,LOW);
digitalWrite (DP,HIGH);
delay(dt);

// digit 7
digitalWrite (A,LOW);
digitalWrite (B,LOW);
digitalWrite (C,LOW);
digitalWrite (D,HIGH);
digitalWrite (E,HIGH);
digitalWrite (F,HIGH);
digitalWrite (G,HIGH);
digitalWrite (DP,HIGH);
delay(dt);

// digit 8
digitalWrite (A,LOW);
digitalWrite (B,LOW);
digitalWrite (C,LOW);
digitalWrite (D,LOW);
digitalWrite (E,LOW);
digitalWrite (F,LOW);
digitalWrite (G,LOW);
digitalWrite (DP,HIGH);
delay(dt);

// digit 9
digitalWrite (A,LOW);
digitalWrite (B,LOW);
digitalWrite (C,LOW);
digitalWrite (D,LOW);
digitalWrite (E,HIGH);
digitalWrite (F,LOW);
digitalWrite (G,LOW);
digitalWrite (DP,HIGH);
delay(dt);

// digit 0.
digitalWrite (A,LOW);
digitalWrite (B,LOW);
digitalWrite (C,LOW);
digitalWrite (D,LOW);
digitalWrite (E,LOW);
digitalWrite (F,LOW);
digitalWrite (G,HIGH);
digitalWrite (DP,LOW);
}

sketch : 배열을 사용하여 숫자 출력하기#

int numArray[11][8] = {
  {0,0,0,0,0,0,1,1}, // 0
  {1,0,0,1,1,1,1,1}, // 1
  {0,0,1,0,0,1,0,1}, // 2
  {0,0,0,0,1,1,0,1}, // 3
  {1,0,0,1,1,0,0,1}, // 4
  {0,1,0,0,1,0,0,1}, // 5
  {0,1,0,0,0,0,0,1}, // 6
  {0,0,0,1,1,1,1,1}, // 7
  {0,0,0,0,0,0,0,1}, // 8
  {0,0,0,0,1,0,0,1}, // 9
  {0,0,0,0,0,0,1,0}  // 0.
};
int pins[] = {2, 3, 4, 5, 6, 7, 8, 9};
 
void setup() {
  for (int r = 0; r < 8; r++) {
    pinMode(pins[r], OUTPUT);
    digitalWrite(pins[r], 1); // 7 Segment Ready
  }

  // 8 출력
  for (int r = 0; r < 8; r++) {
    digitalWrite(pins[r], numArray[8][r]); // numbers[8][r]이면 8을 출력
  }
  delay(1000);
}
 
void loop()
{
  for (int num = 0; num < 11; num++) {
    for (int r = 0; r < 8; r++) {
      digitalWrite(pins[r], numbers[num][r]); // num의 값을 출력
    }
    delay(1000);
  }
}

sketch : 2진수나 16진수를 이용하여 표시하기#

int numArray[10] = {
  0b11000000,   // 0
  0b11111001,   // 1
  0b10100100,   // 2
  0b10110000,   // 3
  0b10011001,   // 4
  0b10010010,   // 5
  0b10000010,   // 6
  0b11111000,   // 7
  0b10000000,   // 8
  0b10010000    // 9
};
// int numArray[10] = { 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90 };
// 16진수를 사용해도 됨
// 소수점 포함 int numArray[10] = { 0x40, 0x79, 0x24, 0x30, 0x19, 0x12, 0x02, 0x78, 0x00, 0x10 };

int segPins[7] = {2, 3, 4, 5, 6, 7, 8};
int i, j;

void setup() {                
  for (i=0; i < 8; i++) {
    pinMode(segPins[i], OUTPUT);
  }
}

void loop() {
  for (i=0; i < 10; i++)
  {
    segLED(i);                         // i=1이면 1을 출력
    delay(1000);
  }
}

void segLED(int num) {                 // num값을 넘겨받아
  int data = numArray[num];            // num번째 배열값을 data로 지정
  
  for (j = 0; j < 8; j++)
  {                                    // 2진수 배열 8비트를 &연산자로 가장 오른쪽11 비트값부터 검사
    if(data & 0x01) {                  // 1이면
      digitalWrite(segPins[j], HIGH);  // HIGH(끄고)
    }
    else {
      digitalWrite(segPins[j], LOW);   // 1이 아니면(0이면)
    }                                  // LOW(킨다)
  data >>= 1;                          // data값을 1비트씩 오른쪽으로 쉬프트한 후
  }                                    // 7번 추가 실행 (총 8번 실행)
}

sketch : 시리얼모니터에서 값을 입력받아 출력하기#

int numArray[10] = { 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90 };
// 소수점 포함 int numArray[10] = { 0x40, 0x79, 0x24, 0x30, 0x19, 0x12, 0x02, 0x78, 0x00, 0x10 };
int segPins[7] = {2, 3, 4, 5, 6, 7, 8};
int i, j;

void setup() { 
  Serial.begin(9600); 
  for (i=0; i < 8; i++) {
    pinMode(segPins[i], OUTPUT);
  }
}

void loop() {
  Serial.println("Press any number!(0~9)"); 
  delay(1000); 

  if (Serial.available()) {
  int number = Serial.read();
    if(number < 10) {
	  Serial.println(number");  
	  segLED(number);                  // i=1이면 1을 출력
	  delay(1000);
    }
    else {
      Serial.println("Please input a lower number than 10!")
    }
  }
}

void segLED(int num) {                 // num값을 넘겨받아
  int data = numArray[num];            // num번째 배열값을 data로 지정
  
  for (j = 0; j < 8; j++)
  {                                    // 2진수 배열 8비트를 &연산자로 가장 오른쪽11 비트값부터 검사
    if(data & 0x01) {                  // 1이면
      digitalWrite(segPins[j], HIGH);  // HIGH(끄고)
    }
    else {
      digitalWrite(segPins[j], LOW);   // 1이 아니면(0이면)
    }                                  // LOW(킨다)
  data >>= 1;                          // data값을 1비트씩 오른쪽으로 쉬프트한 후
  }                                    // 7번 추가 실행 (총 8번 실행)
}



2개의 7 Segment를 사용하여 2자리 숫자 나타내기#

1개의 7 Segment를 사용하는데 8개의 Digital Pin이 필요하므로, 2개 이상의 7 Segment를 사용하려면 16개의 Digital Pin이 필요합니다. 핀의 개수로만 보면 Arduino Uno로는 표현할 수 없겠지요. 그러므로 2개의 7 Segment를 전원부 제어를 통해 빠른 시간동안 on/off를 반복함으로써 우리 눈에 나타나는 잔상효과를 이용하는 방법으로 여러개의 FND를 사용하는 Dynamic 구동 방식을 사용합니다.

아래 회로를 예로들면 아두이노의 Digital 2~9번핀이 각각 두개의 FND로 병렬연결 되어 있고, 10번핀은 10의 자리를 나타내는 FND1에, 11번 핀은 1의 자리를 나타내는 FND2에 연결되어 있는 것을 볼 수 있습니다. 이 회로를 통해 10번핀을 LOW, 11번핀을 HIGH로 두면 FND1이 작동하고, 마찬가지로 10번핀을 HIGH, 11번핀을 LOW로 두면 FND2가 작동하게 되죠. 이러한 방식으로 2개의 FND를 10개의 핀으로 작동할 수 있게 되는 것입니다.


sketch#

int numArray[10] = {
  0b01000000,   // 0
  0b01111001,   // 1
  0b00100100,   // 2
  0b00110000,   // 3
  0b00011001,   // 4
  0b00010010,   // 5
  0b00000010,   // 6
  0b01111000,   // 7
  0b00000000,   // 8
  0b00010000    // 9
};
// int numArray[10] = { 0x40, 0x79, 0x24, 0x30, 0x19, 0x12, 0x02, 0x78, 0x00, 0x10 };
// 16진수를 사용해도 됨

const int segPins[] = { 2, 3, 4, 5, 6, 7, 8, 9 };  // Segment핀 번호
const int segNum = 2;                              // Segment 개수 (숫자 자리수)
const int vccPins[segNum] = { 10, 11 };            // 10, 11번 핀을 통해 seg#1, seg#2의 전원 인가

void setup() {
  for (int i = 0; i < 8; i++) {
    pinMode(segPins[i], OUTPUT);                   // Segment핀 설정
  } 
  for (int i = 0; i < segNum; i++) {
    pinMode(vccPins[i], OUTPUT);                   // seg#0, seg#1의 전원인가 핀 설정
  }
}

void loop() {
  for (int i = 0; i < 100; i++) {                  // 0~99까지 숫자를 표시
    for (int n = 0; n < 10; n++) {                 // 빠르게 카운트할 경우 모든 LED가 켜져 있는 것처럼 보여 
      showNumber(i);                               // 숫자를 구분할 수 없으므로, 빠르게 10번씩 점멸시키면서 표시
    }  
  }                                  
}                                    

void showNumber(int number) {
  if (number == 0) {
    showDigit(number, 0);                         // 0의 경우 (1의 자리수) Segment에만 0을 출력
  }
  else {
    for (int j = 0; j < segNum; j++) {            // 10의 자리, 1의 자리 출력을 위해 2번 실행
      if (number > 0) {                           // 출력값이 0보다 큰 경우에만 실행
        showDigit(number % 10, j);                // 1의 자리 숫자(%10)를 seg#0(j=0)에 출력 (if 10의 자리 숫자 = (number % 100) / 10))
        number = number / 10;                     // ※ 숫자를 10으로 나눠 10의 자리 숫자를 1의 자리 숫자로 만듦
      }                                           // if 처음에 주어진 숫자가 한 자리 수였으면,
      delay(5);                                   //    → 10으로 나눈 후에는 1의 자리값이 0이 되어, 0보다 큰 값이 안되므로 10의 자리 출력하지 않음
    }                                             // if 처음에 주어진 숫자가 두 자리 수였으면
  }                                               //    → 10으로 나눈 후 10의 자리 숫자가 1의 자리 수가 되므로, 10이 자리수를 seg#1(j=1)에 출력 
}

void showDigit(int num, int digit) {              // num값과 digit(0→1의 자리수에 표시, 1→10의 자리수에 표시)을 넘겨받아
  int data = numArray[num];                       // num번째 배열값을 digit자리수에 표시할 data로 지정

  digitalWrite(vccPins[0], HIGH);                 // vcc핀에 전원 인가
  digitalWrite(vccPins[1], HIGH);                 // [0] = Arduino Pin10, [1] = Arduino Pin11

  for (int segLED = 0; segLED < 7; segLED++)      // 숫자 2진수의 7세그먼트 ON, OFF
  {
    if (data & 0x01) {                            // 1이면
      digitalWrite(segPins[segLED], HIGH);        // HIGH(끄고)                  
    }
    else {                                        // 1이 아니면(0이면)
      digitalWrite(segPins[segLED], LOW);         // LOW(끈다)               
    }
    data >>= 1;                                   // data값을 1비트씩 오른쪽으로 쉬프트한 후
  }
  digitalWrite(vccPins[digit], LOW);              // 숫자 LED 한 자리 ON
}



4 FND#

4개의 FND를 Dynamic 방식으로 구동하기 위해서는 8개의 데이터 핀과 4개의 전원부 핀이 필요합니다.


schematic#


Pin Map#

FNDArduinoSegment자리수
16E
25D
313DP
44C
58G
69S11의 자리 수
73B
810S210의 자리 수
911S3100의 자리 수
107F
112A
1212S41000의 자리 수

sketch#

// Segment_X - Arduino Pin // FND Pin
#define SEG_A 2 // 11
#define SEG_B 3 // 7
#define SEG_C 4 // 4
#define SEG_D 5 // 2
#define SEG_E 6 // 1
#define SEG_F 7 // 10
#define SEG_G 8 // 5

// FND_num - Arduino Pin // FND Pin
#define FND1 9  // 6
#define FND2 10 // 8
#define FND3 11 // 9
#define FND4 12 // 12

void seglight(byte number);
byte numbers[] = {
  B0111111,  // MSB   --  LSB
  B0000110,
  B1011011,
  B1001111,
  B1100110,
  B1101101,
  B1111101,
  B0000111,
  B1111111,
  B1101111
};

int FND[] = {SEG_A, SEG_B, SEG_C, SEG_D, SEG_E, SEG_F, SEG_G };
int FND_NO[] = {FND1, FND2, FND3, FND4};

void setup() {
  for (int i = 0 ; i < 7; i++) {
    pinMode(FND[i], OUTPUT);
  }
  for (int i = 0 ; i < 4; i++) {
    pinMode(FND_NO[i], OUTPUT);
    digitalWrite(FND_NO[i], HIGH);
  }
}

int ON = OUTPUT;
int intCnt = 0 ;

void loop() {

  if(intCnt < 10000) {
    intCnt++;
  } else {
    intCnt = 0;
  }
    
  unsigned long start = millis();
  for (unsigned long j = 0 ; j < 10 ; j = millis() - start) { // 600 밀리초 마다 실행

    // Dynamic 구동
    digitalWrite(FND1, LOW);                 // 1의 자리 켜기
    seglight(numbers[intCnt % 10]);
    delay(5);                                // 5ms 유지 후
    digitalWrite(FND1, HIGH);                // 끄기
    
    digitalWrite(FND2, LOW);                 // 10의 자리 켜기
    seglight(numbers[(intCnt / 10) % 10]);
    delay(5);                                // 5ms 유지 후
    digitalWrite(FND2, HIGH);                // 끄기
 
    digitalWrite(FND3, LOW);                 // 100의 자리 켜기
    seglight(numbers[(intCnt / 100) % 10]);
    delay(5);                                // 5ms 유지 후 
    digitalWrite(FND3, HIGH);                // 끄기

    digitalWrite(FND4, LOW);                 // 1000의 자리 켜기
    seglight(numbers[(intCnt / 1000) % 10]);
    delay(5);                                // 5ms 유지 후
    digitalWrite(FND4, HIGH);                // 끄기
  }
}

// Bit값으로 FND 각 LED 점등
void seglight(byte number) {
  for (int i = 0 ; i < 7 ; i++) {
    int bit = bitRead(number, i) ;
    digitalWrite(FND[i], bit);
  }
}