아두이노 코딩 : 4자리 FND(7세그먼트)로 0.01초 간격 카운트 - HS410561K-32
Lucy Archive
Lucy 2023
2020. 8. 6. 02:48

Arduino 4-Digit FND CountArduino 4-Digit FND Count

Arduino Uno 4-Digit 7-Segment Timer Counter

지난 포스트에서 1자리 7세그먼트 사용법에 대해 소개하였습니다. 이번 포스트에서는

4자리 FND를 소개하고, 0.01초 간격으로 시간을 카운트

하는 예제를 소개합니다.

1자리 FND의 동작 예제는 하단의 관련포스트를 참조해주세요.


4Digit 7Segment

본 예제에서 사용하는 4자리 7세그먼트는 공통 캐소드 타입으로, 내부의 회로는 아래 그림과 같이 구성되어있습니다. 총 12개의 핀으로 구성되며 4개의 자리 수 선택 핀(Digit 1 ~ 4) 와 8개의 세그먼트 핀(A~G, DP)으로 구성됩니다. 

4자리 7세그먼트 공통 캐소드 타입4자리 7세그먼트 공통 캐소드 타입

4자리 FND는 아래 그림과 같이 Digit1~4 를 빠른 속도로 순차적으로 켜서 4자리 모두 불이 들어와 있는 것처럼 보이도록 코드가 작성되어야 합니다. 

4-DIgit FND 동작 방법4-DIgit FND 동작 방법

Hardware

준비물

본 예제의 구성품은 아래와 같습니다.

  • Arduino Uno x 1EA
  • 4-Digit 7-Segment x 1EA (본 예제에서는 HS410561K-32)
  • DIP Type Resistor x 12EA (2.2kΩ)
  • Bread Board x 1EA
  • Jumper WIres


회로도 및 연결

아두이노 4자리 FND 연결아두이노 4자리 FND 연결

예제에 사용된 회로는 4자리 FND를 테스트하기 위한 회로로 세그먼트마다 2.2kΩ 의 저항을 직렬로 연결 하였습니다. 회로도의 핀맵은 실제 구성에 편리한대로 수정이 가능합니다. 본 회로도와 연결이 다를 경우 아래 코드의 헤더 부분에서 수정하여 적용이 가능합니다.

코드 : 0.00s ~ 99.99s 카운트

타이머 인터럽트로 10ms 마다 인터럽트 서비스 루틴 호출하여 카운트한 값을 4-Digit 7-Segment 에 출력 하는 코드 입니다.

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
74
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
100
101
102
103
#include <MsTimer2.h>
 
#define segA 12  // 'a' 세그먼트 연결 핀 번호
#define segB 2  // 'b' 세그먼트 연결 핀 번호
#define segC 7  // 'c' 세그먼트 연결 핀 번호
#define segD 9  // 'd' 세그먼트 연결 핀 번호
#define segE 10  // 'e' 세그먼트 연결 핀 번호
#define segF 11  // 'f' 세그먼트 연결 핀 번호
#define segG 6  // 'g' 세그먼트 연결 핀 번호
#define segDP 8 // 'dp' 세그먼트 연결 핀 번호
#define digit1 13 // 1st digit 연결 핀번호
#define digit2 4 // 2nd digit 연결 핀번호
#define digit3 3 // 3rd digit 연결 핀번호
#define digit4 5 // 4th digit 연결 핀번호3r
 
// main 함수에서 처리 편하게 하기 위해 핀번호 배열을 생성
int fndDigit[4= {digit1, digit2, digit3, digit4};
int fndPort[8= {segA, segB, segC, segD, segE, segF, segG, segDP};
// index 0-9 -> 숫자 1~9
// index 10 -> Blank
int fndData[11][8= {
                    { 00000011 }, // 0
                    { 10011111 }, // 1
                    { 00100101 }, // 2
                    { 00001101 }, // 3
                    { 10011001 }, // 4
                    { 01001001 }, // 5
                    { 01000001 }, // 6
                    { 00011011 }, // 7
                    { 00000001 }, // 8
                    { 00001001 }, // 9
                    { 11111111 }, // 10 - blank
                };   
// 초기값 10 -> Blank
int iflag = 0;
 
void setup(){
    // 1000ms 간격으로 myTimer() 함수를 호출합니다.
    MsTimer2::set(10, myTimer);
    MsTimer2::start();
    // 7 Segment 연결된 포트 모두 출력으로 설정
    for(int i = 0 ; i < 4 ; i++)
    {
        pinMode(fndDigit[i], OUTPUT);
        digitalWrite(fndDigit[i], LOW);
    }
    for(int i = 0 ; i < 8 ; i++)
    {
        pinMode(fndPort[i],OUTPUT);
        digitalWrite(fndPort[i],HIGH);
    }
}
 
void loop(){
    static int iCount = 0;
 
    // 타이머 인터럽트가 발생 (iflag=1) 되면 iCount 를 1씩 증가, iCount 값이 10000일 경우 0으로 전환
    if (iflag == 1)
    {
        if (iCount == 10000) {
            iCount = 0;
        }
        else {
            iCount++;
        }
        iflag = 0;
    }
 
    // 4자리수에 각각 입력 될 숫자 입력
    int digit1st = iCount / 1000;
    int digit2nd = iCount % 1000 / 100;
    int digit3rd = iCount % 100 / 10;
    int digit4th = iCount % 10;
    // for 문을 돌리기 위해 배열을 사용
    int digitData[4= {digit1st, digit2nd, digit3rd, digit4th};
 
    for(int i = 0 ; i < 4 ; i++)
    {
        // 모든 Digit 1~4 핀 Off
        digitalWrite(digit1,LOW);
        digitalWrite(digit2,LOW);
        digitalWrite(digit3,LOW);
        digitalWrite(digit4,LOW);
 
        // 각 Digit 에 맞는 fnd 숫자의 값 입력
        for(int j= 0 ;j<8;j++)
        {
            digitalWrite(fndPort[j], fndData[digitData[i]][j]); 
            // 소수점 구분 점 찍기
            if(i==1digitalWrite(fndPort[7], 0);
        }
 
        // 해당 Digit On
        digitalWrite(fndDigit[i],HIGH);
        // 밝기 조절을 위해 2ms LED ON 시간 조절
        delay(2);
    }
}
 
// 10ms 간격 타이머 인터럽트
void myTimer(){
    iflag = 1;
}
cs

코드 설명

  • 3~14줄 : 회로도 연결이 다른 경우 선언부에서 수정이 가능합니다.
  • 17~18 줄 : FND 처리를 편하게 하기 위해 핀 번호를 배열로 처리합니다.
  • 21줄 : FND숫자 데이터 입니다. 인덱스와 표시되는 데이터가 일치되도록 배열을 구성하였습니다.
  • 37~52줄 void setup()
    • 39~40줄 : 10ms 간격으로 타이머 인터럽트를 호출 하도록 설정합니다.
    • 42~51줄 : FND에 사용되는 모든 핀은 출력포트로 설정하고, Digit 핀은 LOW, Seg 핀은 HIGH로 초기화합니다.
  • 54~98줄 void loop()
    • 58~67줄 if문 : 10ms 간격으로 iCount 변수를 1씩 증가하고, iCount 가 10000이 되면 0으로 초기화 합니다.
    • 70~73줄 : 4Digit 의 자리수에 출력할 데이터를 결정합니다. 
      • Digit.1 : 10ms 단위
      • Digit.2 : 100ms 단위
      • Digit.3 : 1s 단위
      • Digit.4 : 10s 단위
    • 77~97줄 for문 : iCount의 데이터를 FND 에 실제 출력하는 코드입니다.
  • 101~103줄 : 10ms 간격으로 호출되는 인터럽트 서비스 루틴 함수입니다.

실행 결과

코드의 실행 결과는 아래 영상과 같습니다. 


마무리

본 포스트에서 아두이노에서 제공되는

타이머 인터럽트 라이브러리를 사용하여 FND에 타이머 카운트를 출력하는 예제

를 소개하였습니다. 문의 사항이 있으시면 댓글로 부탁드립니다.

끝까지 읽어 주셔서 감사합니다.^^

관련포스트

👉 아두이노 FND 관련글 목록 보기

👉 아두이노 디스플레이 장치 관련글 목록 보기

👉 아두이노 인터럽트 관련글 목록 보기

👉 아두이노 관련글 전체 목록 보기