Arduino Uno 7-Segment Counter with Timer Interrupt
7세그먼트는 7개의 획으로 숫자나 문자를 표시 할 수 있는 장치입니다. 본 예제에서는
타이머 인터럽트를 사용하여 1초마다 증가하는 숫자를 7세그먼트에 출력
하는 예제를 소개합니다.아두이노 디지털핀 기본적인 사용법, MsTimer2 라이브러리를 사용하여 Timer Interrupt 를 사용하는 방법은 하단의 관련 포스트를 참조해주세요.
7-Segment
7-Segment 는 8개의 LED로 구성된 표시 장치입니다. 일반적인 7-Segment는 아래 그림과 같이 7개의 획과 1개의 dp 포인트 LED로 구성되어 있습니다. 보통 3,8핀은 7-Segment 가 공통-애노드(Anode)인 경우 전원, 공통-캐소드(Cathode)인 경우 그라운드에 연결 됩니다.
Common-Anode
- 3,8 핀 : 전원 연결
- 3,8 외 핀 : LED On시 LOW 전압, LED Off 시 HIGH 전압
Common-Cathode
- 3,8 핀 : 그라운드 연결
- 3,8 외 핀 : LED On시 HIGH 전압, LED Off 시 LOW 전압
7-세그먼트 종류와 내부 회로
Hardware
준비물
본 예제의 구성품은 아래와 같습니다.
- Arduino Uno x 1EA
- 7-Segment x 1EA (본 예제에서는 5611AH : Common-Cathode)
- DIP Type Resistor x 8EA (200Ω ~ 1kΩ 권장)
- Jumper Wires
회로도 및 연결
아두이노 우노 7-Segment 연결 회로도
- 본 예제에서 사용한 7-Segment 는 Cathode 타입으로 3번 또는 8번 핀을 GND로 연결 합니다.
- 7-Segment 를 제어하기 위해 D2 ~ D9 핀을 사용하고, 핀 모드는 출력 포트로 설정합니다.
코드
타이머 인터럽트로 1초마다 7-Segment 의 숫자를 증가하는 코드입니다. 타이머 인터럽트를 사용하기 위해 MsTimer2 라이브러리를 참조하였습니다.
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 | #include <MsTimer2.h> #define segA 3 // 'a' 세그먼트 연결 핀 번호 #define segB 2 // 'b' 세그먼트 연결 핀 번호 #define segC 5 // 'c' 세그먼트 연결 핀 번호 #define segD 6 // 'd' 세그먼트 연결 핀 번호 #define segE 7 // 'e' 세그먼트 연결 핀 번호 #define segF 8 // 'f' 세그먼트 연결 핀 번호 #define segG 9 // 'g' 세그먼트 연결 핀 번호 #define segDP 4 // 'dp' 세그먼트 연결 핀 번호 // main 함수에서 처리 편하게 하기 위해 핀번호 배열을 생성 int fndPort[8] = {segA, segB, segC, segD, segE, segF, segG, segDP}; // index 0-9 -> 숫자 1~9 // index 10 -> Blank int fndData[11][8] = { { 1, 1, 1, 1, 1, 1, 0, 0 }, // 0 { 0, 1, 1, 0, 0, 0, 0, 0 }, // 1 { 1, 1, 0, 1, 1, 0, 1, 0 }, // 2 { 1, 1, 1, 1, 0, 0, 1, 0 }, // 3 { 0, 1, 1, 0, 0, 1, 1, 0 }, // 4 { 1, 0, 1, 1, 0, 1, 1, 0 }, // 5 { 1, 0, 1, 1, 1, 1, 1, 0 }, // 6 { 1, 1, 1, 0, 0, 1, 0, 0 }, // 7 { 1, 1, 1, 1, 1, 1, 1, 0 }, // 8 { 1, 1, 1, 1, 0, 1, 1, 0 }, // 9 { 0, 0, 0, 0, 0, 0, 0, 0 }, // 10 - Blank }; // 초기값 10 -> Blank int iflag = 0; void setup(){ // 1000ms 간격으로 myTimer() 함수를 호출합니다. MsTimer2::set(1000, myTimer); MsTimer2::start(); // 7 Segment 연결된 포트 모두 출력으로 설정 for(int i = 0 ; i < 8 ; i++) { pinMode(fndPort[i],OUTPUT); } } void loop(){ static int iCount = 0; if (iflag == 1) { if (iCount == 9) { iCount = 0; } else { iCount++; } for(int i = 0 ; i < 8 ; i++) digitalWrite(fndPort[i], fndData[iCount][i]); iflag = 0; } } void myTimer(){ iflag = 1; } | cs |
코드 설명
- 3~10번 줄 : 회로도 연결이 다른 경우 선언부에서 수정 가능하도록 작성하였습니다.
- 16~28번 줄
fndData[]배열 : 배열의 인덱스값과 7-Segment 출력 값을 일치하는 배열을 구성하였습니다. - 45~69번 줄
loop(): 타이머 인터럽트가 발생하면 iCount 변수를 증가시키고, iCount 의 값을 FND 로 출력 합니다. - 49~50번 줄 : iCount가 9일 경우 0으로 초기화, 9가 아닐 경우 iCount를 증가합니다.
- 56번 줄
digitalWrite(fndPort[i], fndData[iCount][i]): iCount 의 값을 FND로 출력하기 위한 코드입니다. - 61~63번 줄
myTimer(): 1초마다 호출 되는 인터럽트 서비스 루틴입니다.
실행 결과
아래 결과 영상은 코드 실행 결과를 빠르게 확인하기 위해 200ms 간격으로 카운트 하도록 코드를 수정한 결과입니다. 36번 줄 타이머 인터럽트 설정을 200ms 로 수정하였습니다.
마무리
본 포스트에서
FND를 사용하기 위해 포트 번호와 FND 출력할 데이터를 배열로 선언하여 FND 출력 코드를 쉽게 작성
하는 방법에 대해 소개하였습니다.끝까지 읽어 주셔서 감사합니다.^^
'Embedded > Arduino' 카테고리의 다른 글
아두이노 코딩 : DS1302 RTC 시간 기록하고 불러오기 (4) | 2020.08.07 |
---|---|
아두이노 코딩 : 4자리 FND(7세그먼트)로 0.01초 간격 카운트 - HS410561K-32 (20) | 2020.08.06 |
아두이노 코딩 : I2C Character LCD 한 줄 고정, 한 줄 스크롤 하기 JHD-162A (0) | 2020.08.05 |
아두이노 강좌 #18 I2C Character LCD 기본 함수 사용 방법 (JHD 162A LiquidCrystal_I2C) (0) | 2020.07.30 |
아두이노 강좌 #17 I2C 통신으로 아두이노 우노와 ESP32 통신 하기 (0) | 2020.07.29 |