본문 바로가기

아두이노로 장난하기

아두이노로 FND 4Digit 7세그먼트 표시하기


안녕하세요 고군입니다.


이번시간에는 앞전의 1자리 FND에 이어서 4자리 FND 7세그먼트를 제어하는 방법을 알아보겠습니다. FND는 한자리를 비롯해 2자리, 3자리, 4자리 등 다양하게 판매되고 있습니다. 1개일 때 8개의 포트를 사용해서 제어 했는데, 4자리는 몇개의 포트로 어떻게 제어하게 되는지 한번 알아 보겠습니다. 이론 부분이 좀 어려울 수 있으나 천천히 알아가면 이해 할 수 있을거라 생각이 듭니다.


그림1. 4Digit 7세그먼트 구조와 외형


위 그림은 숫자 4자리를 표시할 수 있는 7세그먼트의 외형 및 핀 구조를 보이고 있습니다. 2개의 공통 핀을 사용하는 1자리 표시용 7세그먼트와 달리 공통 단자가 각 자리별로 1개씩 있습니다. 위 그림에서 공통 단자를 COMn으로 표기하고 있으며, COM1 ~ COM4까지 사용하고 있습니다, 또한 a~g, 그리고 dp등 총 8개의 세그먼트 핀이 존재합니다. 따라서 12핀으로 구성됩니다.


(a) 4-digit 규격의 공통 음극(Common Cathod)방식


그림 (a)는 4-digit 규격의 공통 음극 방식 7세그먼트의 핀 번호와 핀 이름을 나타내고 있습니다. 공통 단자인 COM1,2,3,4에 모두 마이너스(-) 신호를 가하고, 데이터 신호인 a~g, dp에 모두 플러스(+) 신호를 가하면 모든 7세그먼트는 켜지게 됩니다. 이때 데이터 신호(a~g,dp)중에 하나라도 마이너스(-) 신호로 바뀌면 해당 세그먼트(공통으로 묶인 4개)는 꺼집니다.


(b) 4-digit 규격의 공통 양극(Common Anode)방식


그림 (b)는 4-digit 규격의 공통 양극 방식 7세그먼트의 핀 번호와 핀 이름을 나타내고 있습니다. 공통 단자인 COM1,2,3,4에 모두 플러스(+) 신호를 가하고, 데이터 신호인 a~g, dp에 모두 마이너스(-) 신호를 가하면 모든 7세그먼트는 켜지게 됩니다. 이때 데이터 신호(a~g,dp)중에 하나라도 플러스(+) 신호로 바뀌면 해당 세그먼트(공통으로 묶인 4개)는 꺼집니다.


그림 (a),(b)와 같이 데이터 신호선이 공통으로 연결된 7세그먼트에 각각 다른 숫자를 표시하기 위해서는 동적 디스플레이 제어방식을 사용해야 합니다. 이 방식은 데이터 신호선인 a-b,dp에 자신이 원하는 신호를 인가하고, 공통 단자인 COM1~4중 한 핀만 마이너스(-) 신호를 인가하고 나머지는 공통 단자 핀에(+) 신호를 인가하는 것입니다.


  예를  들어 숫자 '1234'를 4개의 7세그먼트에 표시할 때는 그림(C)와 같은 방식으로 신호를 제어해야 합니다. 그림(C)에서는 7세그먼트에 동적 디스플레이 제어를 하기 위한 타이밍 차트를 보이고 있는데, 각 자리별로 시분할하여 자리별로ON/OFF 하는 신호 파형을 보이고 있습니다. COM1 ~ COM4까지는 동일한 분할 시간동안 하나의 핀만(-)신호를 출력한다. 또한 T1에서 T2로 다른 시분할 시간 이동시 COMn신호와 데이터 신호(a~g,dp)는 모두 (-)신호를 출력하는데 이것은 동적디스플레이 제어에 잔상효과를 없애기 위한 방법이다. 잔상효과란 T1 시간에서 출력한 신호가 T2 시간에 영향을 미쳐 원하지 않는 조각이 흐릿하게 디스플레이 되는 현상을 말한다. 또한 잔상효과를 없애기 위해서는 충분한 OFF시간이 필요한데 너무 짧은 경우 잔상효과가 나타날 수 있고, 너무 길면 시분할 디스플레이가 눈에 보이게 되어 원하는 동적 디스플레이 제어를 할 수 없게 된다. 동적 디스플레이 제어 방식은 착시현상을 이용한 제어방식이며, 잔상효과가 나타날 경우 ON/OFF시간을 충분히 조절해야 하므로 정적 디스플레이(static display)제어 방식에 비해 다소 제어가 어려운 단점이 있으나 전력소모가 적다는 장점이 있습니다.


(C) 동적 디스플레이 제어를 위한 각 핀들의 타이밍 차트


위 표는 주로 사용되는 FND 7세그먼트의 디스플레이 폰트를 나타내고 있다. FND 7세그먼트의 핀 이름이 알파벳에 연속된 조건에서 a핀을 MSB(최상의 비트)로 하고, dp 핀을 LSB(최하위 비트)로 설정하여 폰트를 2진수로 나타내면 0=0B11111100, 1=0B01100000, ....이 됩니다.


▶ 아두이노


[전자부품목록]




  ▶ 아두이노 보드: 1개 

  ▶ 브레드보드: 1개

  ▶ 점프선 : 다량

  ▶ 저항 220옴: 8개

  ▶ 4자리 FND 7세그먼트: 1개






4Digit FND 7세그먼트 아두이노 연결도


위에 사용된 4자리 7세그먼트는 공통 음극 방식으로 12번 핀에 L를 가하고, 8개 세그먼트 제어핀에 OxFC(11111100)를 가하면 첫 번째 자리에 0이 표시된다. 이때 9번과 8번핀에 L를 가하면 동일한 숫작가 두 버째와 세 버째 자리에도 표시됩니다. 각각의 제어핀에는 220옴 저항을 연결하여 LED를 보호합니다


4Digit FND 7세그먼트 제어를 위한 핀 연결


▶ 아두이노 소스 예제


※ 얘제 1. 네 자리 7세그먼트에 1234가 나타나도록 표시하기




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
30
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
//7세그먼트 선택 핀
int digit_select_pin[] = {1,2,3,4};
//7세그먼트 제어 핀
int segment_pin[] = {5,6,7,8,9,10,11,12};
//자릿수 표현 사이의 지연 시간, ms 단위
int time_delay = 5;
//0~9까지의 숫자 표시를 위한 세그먼트 a~dp의 점멸 패턴
//켜지는 부분이 1로 표현됨
byte digits_data[10]={0xFC0x600xDA0xF2
0x660xB60xBE0xE4, 0xFE0xE6};
 
void setup()
{
  //자릿수 선택 핀을 출력으로 설정
  for(int i = 0; i < 4; i++)
  {
    pinMode(digit_select_pin[i], OUTPUT);
  }
  // 세그먼트 제어 핀을 풀력으로 설정
  for(int i = 0; i < 8; i++)
  {
    pinMode(segment_pin[i], OUTPUT);
  }
}
//해당 자릿수에 숫자 하나를 표시하는 함수
//(위치, 출력할 숫자)
void show_digit(int pos, int number)
{
  for(int i = 0; i < 4; i++)
  {
    if(i+1 ==pos)
      //해당 자릿수의 선택 핀만 LOW로 설정
      digitalWrite(digit_select_pin[i], LOW);
    else
      //나머지 자리는 HIGH로 설정
      digitalWrite(digit_select_pin[i], HIGH);
  }
  // 8개 세그먼트 제어
  for(int i = 0; i < 8; i++)
  {
    byte segment_data = (digits_data[number] 
    & (0x01 << i)) >> i;
    if(segment_data == 1)
      digitalWrite(segment_pin[7-i], HIGH);
    else
      digitalWrite(segment_pin[7-i], LOW);
  }
}
void loop()
{
  show_digit(11);
  delay(time_delay);
  show_digit(22);
  delay(time_delay);
  show_digit(33);
  delay(time_delay);
  show_digit(44);
  delay(time_delay);
}
cs




※ 예제 2. FND 7세그먼트에 0000 ~ 9999 까지 숫자를 카운터하여 화면에 표시하기




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
30
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
62
63
64
65
66
67
68
69
70
71
72
73
//7세그먼트 선택 핀
int digit_select_pin[] = {1,2,3,4};
//7세그먼트 제어 핀
int segment_pin[] = {5,6,7,8,9,10,11,12};
//자릿수 표현 사이의 지연 시간, ms 단위
int time_delay = 5;
//0~9까지의 숫자 표시를 위한 세그먼트 a~dp의 점멸 패턴
//켜지는 부분이 1로 표현됨
byte digits_data[10]={0xFC0x600xDA0xF2,  0x66
                      0xB60xBE0xE40xFE0xE6};
int d1000, d100, d10, d1;
 
void setup()
{
  //자릿수 선택 핀을 출력으로 설정
  for(int i = 0; i < 4; i++)
  {
    pinMode(digit_select_pin[i], OUTPUT);
  }
  // 세그먼트 제어 핀을 풀력으로 설정
  for(int i = 0; i < 8; i++)
  {
    pinMode(segment_pin[i], OUTPUT);
  }
}
//해당 자릿수에 숫자 하나를 표시하는 함수
//(위치, 출력할 숫자)
void show_digit(int pos, int number)
{
  for(int i = 0; i < 4; i++)
  {
    if(i+1 ==pos)
      //해당 자릿수의 선택 핀만 LOW로 설정
      digitalWrite(digit_select_pin[i], LOW);
    else
      //나머지 자리는 HIGH로 설정
      digitalWrite(digit_select_pin[i], HIGH);
  }
  // 8개 세그먼트 제어
  for(int i = 0; i < 8; i++)
  {
    byte segment_data = (digits_data[number] 
         & (0x01 << i)) >> i;
    if(segment_data == 1)
      digitalWrite(segment_pin[7-i], HIGH);
    else
      digitalWrite(segment_pin[7-i], LOW);
  }
}
void loop()
{
  forint i = 0; i < 10000; i++)
  {
 
    d1000 = i /1000;
    d100 = i % 1000/100;
    d10 = i % 100/10;
    d1 = i % 10;
    for(int j = 0 ; j < 10 ; j++)
    {
 
     show_digit(1, d1000);
     delay(time_delay);
     show_digit(2, d100);
     delay(time_delay);
     show_digit(3, d10);
     delay(time_delay);
     show_digit(4, d1);
     delay(time_delay);
    }
  }
}
 
cs