아두이노 코딩 : 74HC595로 7-Segment (FND) 제어하기 with 키보드
Lucy Archive
Lucy / Facilitate4U
2020. 8. 9. 18:45

아두이노 키보드로 FND 출력아두이노 키보드로 FND 출력

Arduino Uno : 7-SEGMENT FND with 74HC595

아두이노에서 FND 를 직접 제어하기 위해 9개의 핀이 필요하지만, 시프트 레지스터를 사용하면 최소 3-4개의 핀으로 FND 제어가 가능합니다. 본 포스트에서는

시프트 레지스터를 사용하여 FND를 제어

하는 예제를 소개합니다.

시프트레지스터 사용 방법과 7-Segment 관련된 기초적인 내용이 필요하신 분은 하단의 관련포스트를 참조해주세요.


Hardware

준비물

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

  • Arduino Uno x 1EA
  • 74HC595 x 1EA
  • 7-Segment x 1EA ( 본 예제에서는 5611AH)
  • DIP Type Resistor x 8 EA ( 200Ω ~ 1kΩ 의 값을 권장)
  • Jumper WIres

회로도 및 연결

Arduino Uno 와 시프트 레지스터 74HC595 의 연결 핀은 아래와 같습니다. 

  • Arduino Uno D10 핀은 74HC595의 11번핀 SRCLK 로 연결 (CLK)
  • Arduino Uno D11 핀은 74HC595의 12번핀 RCLK 로 연결 (LATCH)
  • Arduino Uno D12 핀은 74HC595의 13번핀 OE 로 연결
  • Arduino Uno D13 핀은 74HC595의 14번핀 SER 로 연결 (DATA)

참고로, Arduino Uno 와 74HC595 연결 핀은 따로 지정 되어 있지 않고, 연결이 편하신대로 하셔도 무방합니다. 


예제1 : FND 카운트

1초 간격으로 FND 의 숫자가 올라가는 예제 입니다. 

코드

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
#define sckPin 13 // 74HC595의 SRCLK핀
#define latchPin 12 // 74HC595의 RCLK핀
#define oePin 11 // 74HC595의 OE핀
#define dataPin 10 // 74HC595의 SER핀
 
int fndData[11= { 0b11111100// 0
                    0b01100000// 1
                    0b11011010// 2
                    0b11110010// 3
                    0b01100110// 4
                    0b10110110// 5
                    0b10111110// 6
                    0b11100100// 7
                    0b11111110// 8
                    0b11110110// 9
                    0b00000000// Blank
                  };   
 
void setup(){
    // CLK, DATA, OE, DATA 핀 모두 출력 포트로 설정
    pinMode(latchPin, OUTPUT);
    pinMode(oePin, OUTPUT);
    pinMode(dataPin, OUTPUT);
    pinMode(sckPin, OUTPUT);
    digitalWrite(oePin, HIGH); //초기설정시 출력이 안나오도록
}
 
void loop(){
    for(int i = 0 ; i < 10 ; i++)
    {
        digitalWrite(oePin, HIGH); //데이터가 저장될동안 출력을 출력 비활성화
        digitalWrite(latchPin, LOW); 
        shiftOut(dataPin, sckPin, LSBFIRST, fndData[i]); // 0 ~ 9의 데이터를 순차적으로 송신
        digitalWrite(latchPin, HIGH); // LATH핀 LOW -> HIGH 일떄 D래치 동작
        digitalWrite(oePin, LOW); // 8bit 데이터 출력 저장 후 Output 활성화
        delay(1000);
    }
}
cs

코드 설명

  • 1~4줄 : Arduino Uno 와 Shift Register 의 연결이 다른 경우 해당 핀 이름에 맞는 핀 번호를 설정하는 선언문 입니다.
  • 6줄 : fndData 배열은 0~9 인덱스 까지는 0~9의 FND 출력 데이터을 가지고, 10번째 인덱스에는 아무것도 없는 Blank 데이터를 저장하였습니다. 
  • 19줄 : 74HC595에 사용되는 핀은 모두 출력 포트로 설정하고, OE핀은 Default LOW 로 설정합니다.
  • 33줄 : shiftOut(dataPin, sckPin, LSBFIRST, fndData[i]) 에서 for문의 i값이 변화함에 따라 fndData 배열의 i 인덱스 값을 시프트 레지스터에 기록합니다.


실행 결과


예제2 : 시리얼 수신 값으로 FND 출력

PC로 부터 Serial 통신으로 데이터를 수신한 값을 FND 로 출력하는 예제입니다.

코드

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
#define sckPin 13 // 74HC595의 SRCLK핀
#define latchPin 12 // 74HC595의 RCLK핀
#define oePin 11 // 74HC595의 OE핀
#define dataPin 10 // 74HC595의 SER핀
 
volatile int flag = 0;
 
int fndData[11= { 0b11111100// 0
                    0b01100000// 1
                    0b11011010// 2
                    0b11110010// 3
                    0b01100110// 4
                    0b10110110// 5
                    0b10111110// 6
                    0b11100100// 7
                    0b11111110// 8
                    0b11110110// 9
                    0b00000000// Blank
                  };   
 
void setup(){
    // CLK, DATA, OE, DATA 핀 모두 출력 포트로 설정
    pinMode(latchPin, OUTPUT);
    pinMode(oePin, OUTPUT);
    pinMode(dataPin, OUTPUT);
    pinMode(sckPin, OUTPUT);
    digitalWrite(oePin, HIGH); //초기설정시 출력이 안나오도록
 
    Serial.begin(9600);
    while(!Serial){;}
    delay(5000);
    Serial.println("Input Number Range 0 ~ 9 : ");
}
 
void loop(){
    if(flag == 1){
 
        flag = 0;
 
        int value; // 시리얼 데이터로 수신된 데이터를 저장
 
        byte recData = Serial.read();
        if((recData >= '0'& (recData <= '9')) 
            value = int(recData) - 48// 시리얼 통신 수신시 byte 형의 데이터를 int 로 변환
        else
            value = 10;
        
        digitalWrite(oePin, HIGH); //데이터가 저장될동안 출력을 출력 비활성화
        digitalWrite(latchPin, LOW); 
        shiftOut(dataPin, sckPin, LSBFIRST, fndData[value]); // 0 ~ 9의 데이터를 순차적으로 송신
        digitalWrite(latchPin, HIGH); // LATH핀 LOW -> HIGH 일떄 D래치 동작
        digitalWrite(oePin, LOW); // 8bit 데이터 출력 저장 후 Output 활성화
    }
}
 
void serialEvent(){ // 시리얼 수신 버퍼에 데이터가 있는 경우 호출되는 인터럽트 핸들러
    flag = 1;
}
cs

코드 설명

예제1의 코드에 PC와 시리얼 통신을 추가하였습니다. 시리얼 인터럽트 관련된 내용이 필요하신 분은 하단의 관련 포스트를 참고해주세요. loop() 문 안의 if() 문은 시리얼 통신이 수신할 때만 동작하는 함수로, 다른 기능을 추가시 if() 문 외부에서 코드를 추가하시면 됩니다.

  • 43~46줄 : 시리얼 통신으로 수신된 데이터가 '0'~'9' 사이의 값이 아닌 경우 BLANK (fndDATA 배열의 10번쨰 인덱스 데이터) 를 호출하도록 설정하기 위한 if문입니다.
  • 44줄 : value = int(RecData) - 48 -> Serial.read() 의 값은 char 형을 반환하기 때문에 int 형으로 변환 하기 위한 연산입니다.


실행 결과


마무리

본 포스트에서는

아두이노 우노 보드에서 74HC595 를 사용하여 7Segment 를 출력하는 예제

를 소개하였습니다. 참고로, 7-Segment 를 제어하기 위해 시프트 레지스터를 쓰는 경우 필요한 포트가 8개 -> 4개로 줄어드는 장점이 있습니다. 

설명이 더 필요하신 부분이 있으시면 댓글로 남겨주세요. 끝까지 읽어 주셔서 감사합니다.^^

관련포스트

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

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

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

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