본문 바로가기
Arduino&RasberryPi/Arduino Uno

17. Arduino - 1digit 7세그먼트 LED 사용법

by Rosmary 2019. 11. 16.
728x90
반응형

 

일상 생활 중에 흔히 마주치는 엘레베이터나 전자 시계에서, 위의 사진처럼 각진 숫자를 볼 수 있다. 이런 형태의 숫자를 표시하는 전자 부품이 존재하는데, 7 세그먼트 LED라고 불린다. 7 세그먼트 LED는 "7 부분으로 나뉘어진 LED"라고 생각하면 되는데, 아래의 사진처럼, 부품 내에 한 자리 숫자를 표현하는 LED가 7개가 존재하고 있기 때문이다.

 

이번 포스팅에서는, 한 자릿수를 표시하는 7 세그먼트 LED의 사용법에 대해 작성하려고 한다. 사실, 일반 LED를 사용하는 방법을 알고 있다면, 7세그먼트의 사용법도 크게 어렵지는 않을 것이다.  7개의 LED를 동시에 작동시켜야하기 때문에, 회로와 동작 코드가 일반 LED에 비해 조금 더 복잡할 뿐이다. 다만, 7 세그먼트 LED의 종류에 따라, 회로 결선 방법이 조금씩 다르기 때문에, 7 세그먼트 사용 전에, 자신이 가지고 있는 부품이 어떤 종류의 7 세그먼트 LED인지 확인하는 과정이 필요하다.

 

 

 

1. 1digit 7 세그먼트 LED의 구조 및 종류

 

한 자리 숫자를 표시하는 7 세그먼트 LED(이하 7 세그먼트)는, 회로와 연결할 수 있는 단자가 아래위로 5개씩 총 10개가 존재한다. 세그먼트의 10개 단자는, 공통적으로 아래 좌측부터 우측으로 1번에서 5번을 부여하며, 상단 우측부터 좌측으로 6번에서 10번을 부여한다.

 

 이 중, 3번과 8번은 모든 LED와 연결되는 회로를 하나로 묶어주는 회로다. 그림으로 나타내면, 아래와 같다. 3번과 8번 단자는 7 세그먼트 종류에 따라, VCC나 GND로 연결하여 사용한다.

 

 

3번과 8번을 제외한 단자는 세그먼트 내의 각 LED와 1대 1로 연결되는 회로이며, 단자 번호에 따른 LED는 다음과 같다.

 

LED 단자 번호 (#)
a 7
b 6
c 4
d 2
e 1
f 9
g 10

dp

(숫자 옆에 소숫점 표시를 위한 LED가 존재하는 제품이 있음)

5

 

 

시중에 판매되는 7 세그먼트는, 공통 단자인 3번과 8번의 성격에 따라 그 종류가 2 가지로 나뉘게 된다. 공통 단자가 전원 공급을 위한 단자으로 사용되는 경우, 공통양극(Common-Cathod) 세그먼트라고 부르며, 반대로 공통 단자가 GND를 위한 단자로 사용되는 경우, 공통음극(Common-Anode) 세그먼트라고 부른다.

 

부품의 외양만으로 자신이 가진 세그먼트의 종류를 확인하는 방법은 아직 찾지 못했다. 7 세그먼트의 종류를 확인하기 위해서는, 직접 회로를 구성하여 LED에 점등되는지 여부를 확인해보는 방법밖에 없는 것 같다. 만약 3번이나 8번 단자를 5V에 연결한 뒤, 하나의 LED 단자을 GND에 연결하여 점등되는 것이 확인되었다면, 해당 7 세그먼트는 공통양극이다. 반대로 공통 단자를 GND와 연결하고, 하나의 LED 단자에 전원 공급을 하여 점등되는 것이 확인된다면, 해당 7 세그먼트는 공통 음극이다. 공통 양극 7 세그먼트를 공통 음극 방식으로 회로를 구성하거나, 반대로 공통 음극 7 세그먼트를 공통 양극 방식으로 회로를 구성한다면, 불은 점등되지 않는다.

 

7 세그먼트 내의 각 LED 회로는 220 옴 저항을 포함하고 있다고 하지만, 각종 메뉴얼을 참조해보면, 각 LED 마다 220 옴 저항을 추가로 포함해 줄 것을 권고하고 있다. 따라서 필자의 경우, 공통 양극 모델에서는 공통 단자 회로 앞에 1K 옴 저항을 추가해주고, 공통 음극 모델에서는 각 LED 회로 진입 전에 220 옴 저항을 추가해주는 작업을 진행한다.

 

< 좌: 공통 양극 7세그먼트 회로, 우: 공통 음극 7 세그먼트 회로 >

 

공통 양극 모델의 경우, 각 LED 회로와 Arduino의 GND 핀을 연결해주어야 하는데, Arduino의 GND 핀이 단 3개 뿐이라, 약간 다른 방식을 써야 한다. 위의 좌측 사진 회로를 보면, 각 LED 핀은 모두 digital 핀과 연결되어 있는데, digitalWrite() 함수의 두 번째 인자 값을, LOW로 설정하면, 해당 핀이 GND와 동일한 효과를 내기 때문이다. 정리하자면, 전원 소스인 12번이 void setup () 함수에서 digitalWrite(12, HIGH)로 설정되면, 12번 핀은 공통 단자를 거쳐, 7 세그먼트에 항상 5V의 전압을 출력하게 되며, 각 GND 핀 역할을 하는 다른 digital 핀들이 digitalWrite(#, HIGH)로 설정되면, 해당 핀과 연결된 LED는 불이 들어오지 않고, digitalWrite(, LOW)로 설정되면 해당 핀과 연결된 LED가 점등된다. 물이 높은 곳에서 낮은 곳으로 흐르는 것을 생각하면 된다. 전원 소스가 5V, LED 핀이 5V(HIGH)이면, 높이가 동일하므로 전기가 흐르지 않고, 전원 소스가 5V, LED 핀이 0V(LOW)라면, LED로 지정된 digital 핀의 높이가 상대적으로 낮기 때문에, 전기가 흐르게 된다.

 

공통 음극 모델의 경우, 각 LED 회로로 직접 전기 신호를 전달하기 때문에, 공통 양극 모델처럼, 동작 코드를 구성함에 있어서 큰 어려움은 없다. 단, LED 회로마다 각각 220 옴 저항을 추가해야하기 때문에, 회로의 구성이 조금 복잡하다는 단점이 있다.

 

 

 

2.  7 세그먼트의 작동 코드

 

필자가 가지고 있는 7 세그먼트 모델은 공통 양극 모델이며, 이 부품이 1부터 9까지 1초마다 숫자를 출력하도록 코드를 작성하려고 한다. 이 코드를 작성하기 위해서는, 이전 실습 내용과 달리, 각 숫자를 표현할 수 있는 코드를 함수로 나타내는 작업이 선행되어야 한다(물론, void setup과 void loop 함수만 써서도 나타낼 수는 있지만, 코드를 읽기가 어려워진다)

 

우선, 공통 양극 모델에서 모든 LED 불이 점등되는지 확인하는 코드를 작성해보자. 코드는 다음과 같다.

 

======================

int a = 5;
int b = 4;
int c = 9;
int d = 10;
int e = 11;
int f = 6;
int g = 7;
int dp = 8;    //decimal point
int sourcePin = 12;

void setup()
{
  pinMode(sourcePin, OUTPUT);
  digitalWrite(sourcePin,HIGH);
  
  for(int i=4; i<=11;i++)
  {
    pinMode(i, OUTPUT);
    digitalWrite(i, LOW);
  }
  delay(2000);   //모든 LED 불이 2초간 점등되도록 함.

 

  digitalWrite(sourcePin, LOW);}   // 전원 핀에서 전원 공급 차단.

void loop()
{
}

========================

 

모든 핀이 이상없이 잘 작동함을 확인할 수 있을 것이다.

 

 

이제,  특정 숫자를 출력하는 함수를 작성해보려고 한다. 만약 숫자 1을 출력한다고 하면, LED b와 c가 점등이 되도록 코드를 작성해야하고, 숫자 9를 출력한다고 하면, LED e를 제외한 모든 LED가 점등되어야 한다.

 

숫자 5가 출력되는 함수 코드만 작성하여 동작시키고자 한다면, 다음과 같이 코드를 작성하면 된다.

 

======================

int a = 5; 
int b = 4; 
int c = 9; 
int d = 10; 
int e = 11; 
int f = 6; 
int g = 7; 
int dp = 8;    //decimal point 
int sourcePin = 12; 

 

void setup()
{
  for (int i = 4 ; i <=12 ; i++)
  {
    pinMode(i, OUTPUT);
    digitalWrite(i, HIGH); // 모든 핀에서 5V 전원 공급 실행 , 모든 LED에 불이 들어오지 않음
  }
}

void number5 ()
{

  setup();  // 7세그먼트 LED 초기화
  int led_On[] = {a, f, g, c, d};
  for(int num = 0; num < 5; num++)
  {
    digitalWrite(led_On[num], LOW);
  }
}

void loop()
{
  number5();    //숫자 5를 출력하는 함수 실행
}

========================

 

해당 코드를 Arduino에 밀어넣고 작동시키면, 아래와 같은 결과가 출력된다.

 

 

 

 

이제, 위의 내용을 활용하여, 1부터 0까지 1초 간격으로 순차적으로 숫자를 출력하려 한다. 코드는 다음과 같다.

 

==========================

int a = 5; 
int b = 4; 
int c = 9; 
int d = 10; 
int e = 11; 
int f = 6; 
int g = 7; 
int dp = 8;    //decimal point 
int sourcePin = 12; 

void setup() 

  for (int i = 4 ; i <=12 ; i++) 
  { 
    pinMode(i, OUTPUT); 
    digitalWrite(i, HIGH); // 모든 핀에서 5V 전원 공급 실행 , 모든 LED에 불이 들어오지 않음
  } 


void number1 () 
{

  int led_On[] = {b, c}; 
  for(int num = 0; num < 2; num++) 
  { 
    digitalWrite(led_On[num], LOW); 
  } 
  delay(1000);
  setup();


void number2 () 
{

  int led_On[] = {a, b, g, e, d}; 
  for(int num = 0; num < 5; num++) 
  { 
    digitalWrite(led_On[num], LOW); 
  } 
  delay(1000);
  setup();


void number3 () 
{

  int led_On[] = {a, b, c, d, g}; 
  for(int num = 0; num < 5; num++) 
  { 
    digitalWrite(led_On[num], LOW); 
  } 
  delay(1000);
  setup();


void number4 () 
{

  int led_On[] = {f, g, b, c}; 
  for(int num = 0; num < 4; num++) 
  { 
    digitalWrite(led_On[num], LOW); 
  } 
  delay(1000);
  setup();


void number5 () 
{

  int led_On[] = {a, f, g, c, d}; 
  for(int num = 0; num < 5; num++) 
  { 
    digitalWrite(led_On[num], LOW); 
  } 
  delay(1000);
  setup();


void number6 () 
{

  int led_On[] = {a, c, d, e, f, g}; 
  for(int num = 0; num < 6; num++) 
  { 
    digitalWrite(led_On[num], LOW); 
  } 
  delay(1000);
  setup();


void number7 () 
{

  int led_On[] = {a, b, c}; 
  for(int num = 0; num < 3; num++) 
  { 
    digitalWrite(led_On[num], LOW); 
  } 
  delay(1000);
  setup();


void number8 () 
{

  int led_On[] = {a, b, c, d, e, f, g}; 
  for(int num = 0; num < 7; num++) 
  { 
    digitalWrite(led_On[num], LOW); 
  } 
  delay(1000);
  setup();


void number9 () 
{

  int led_On[] = {a, b, c, d, f, g}; 
  for(int num = 0; num < 6; num++) 
  { 
    digitalWrite(led_On[num], LOW); 
  } 
  delay(1000);
  setup();


void number0 () 
{

  int led_On[] = {a, b, c, d, e, f}; 
  for(int num = 0; num < 6; num++) 
  { 
    digitalWrite(led_On[num], LOW); 
  } 
  delay(1000);
  setup();


void loop() 

  number1();
  number2();
  number3();
  number4();
  number5();
  number6();
  number7();
  number8();
  number9();
  number0();
}

=================================

 

코드가 심각할 정도로 길다. Arduino는 메모리 용량이 크지 않아서, 코드도 간결하게 만들어주는 것이 좋기 때문에, 해당 코드를 조금 더 최적화 할 수 있는 방법을 찾아봐야할 듯 하다. 다행히 지금은 이 프로그램 하나만 동작하는 것이라, 결과는 아래처럼 잘 나온다.

 

 


 

7 세그먼트는, 단순히 코드를 통한 출력뿐만 아니라, Serial Monitor를 이용하여 입력받은 숫자 하나를 출력하는 용도로 사용할 수도 있고, 센서를 이용해 읽어들인 값을 특정 레벨로 나누어 표시하도록 하는 기능도 가능하다(예를 들면, 온도가 20도 이상, 25도 미만일 경우, 레벨 3을 표시하고, 온도가 25도 이상, 30도 미만인 경우 레벨 4를 표시하는 등...). 

 

 

FIN.

반응형

댓글