[아두이노] 4-Digit 7-Segment Display 시계 리모콘 제어
[아두이노] 4-Digit 7-Segment Display 시계 리모콘 제어
- 온라인 가상시뮬레이터 : https://www.tinkercad.com
- 참조 :
[아두이노] 리모콘(IRremote) 제어
[아두이노] 4-Digit 7-Segment Display 가상시뮬레이터 실험
[아두이노] 6-Digit 7-Segment Display 시계 리모콘 제어
지난 시간에 6-Digit 7-Segment Display 아두이노 시계에서 리모콘 시간 입력을 가상시뮬레이터로 실험을 하였습니다. 오늘은 다행히 IR Sensor(수신부) 부품을 찾아서 실제 리모콘으로 제어하는 실험을 할 수 있게 되었네요. 참고로 4-Digit 7-Segment Display 부품이라서 4개의 숫자 밖에 출력을 못합니다. 그래서 시/분을 리모콘으로 제어할 것인지 분/초를 제어할지 고민하다가 분/초를 리모콘으로 제어하고 제어된 결과가 정상적으로 동작하는지 살펴보는게 나을 것 같아서 분/초 시계를 만들어 보았습니다.
1. 4-Digit 7-Segment Display 회로도
- 준비물 : 4-Digit 7-Segment Display 1개, IR Sensor 1개, IR remote 1개, 아두이노우노
- 내용 : 7-Segment Display 부품의 핀 번호 순서에 맞게 아두이노우노에 연결하고, IR Sensor 핀을 2번핀에 연결하시오.
IR Sensor(수신부)는 핀 위치가 다를 수 있습니다. fritzing에 제공되는 핀위치에 따라 연결했기 때문에 연결하실 때 해당 수신부 부품이 어떤 부품이냐에 따라 주의해서 연결해 주세요.
아래 IR Sensor(수신부) 부품이면 핀 번호를 보시고 연결하시면 됩니다.
2. 코딩
- 사전학습 : [6-Digit 7-Segment Display 시계 리모콘 제어(아두이노)]https://steemit.com/kr-arduino/@codingman/6-digit-7-segment-display)
- 리모콘 키값 조회 공개회로도 :https://www.tinkercad.com/things/3FjkW4Qftm4
사전학습 post의 소개한 소스를 실제 코딩에도 그대로 적용됩니다. 사전학습 종합소스와 아래 수정 할 부분을 같이 보고 어느 부분을 수정되었는지 같이 보시면서 읽어주세요. 아니면 아래 수정한 종합소스를 보면서 수정한 부분의 위치가 어느 위치이고 수정됐는지 같이 보면서 이해하시기 바랍니다. 그 이유는 그냥 아래 수정 할 부분에 이부분을 수정합니다라고 이야기 하기 때문에 말하는 부분이 정확이 어느 부분인지 혼동할 수 있기 때문에 꼭 종합소스를 같이 봐주세요.
수정 할 부분은 리모콘 키값부분입니다.
사용할 버턴은 위 사진에서 보는 버턴들을 이용 합니다. 이 부분의 키값을 알려면 리모콘 키값 조회 공개회로도 보시고 맞게 코딩을 수정한 뒤에 키 값을 알아내고 그 키값을 아래와 같이 수정하변 됩니다.
#define STATE 16736925 // ch버턴 #define SELECT_TIME 16748655 // EQ버턴 #define TIME_UP 16754775 // +버턴 #define TIME_DOWN 16769055 // -버턴
다음으로 4-Digit 7-Segment Display 핀 번호에 대해서 변수 수정을 해야 합니다.
const byte segPin[8]={7,3,A3,A1,A0,6,A4,A2}; //사용핀{a,b,c,d,e,f,g,dp} 순서대로임 const byte digitPin[4] = {8,5,4,A5}; //segment 위치 핀
다음 수정부분은
if(output==true){ if(results.value==SELECT_TIME){ selectVal++; if(selectVal==3)selectVal=0; }
이 부분으로 원래는 시/분/초 3개의 시간위치가 기존 소스에 있었지만 두개를 분/초를 이용하기 때문에 분/초 위치만 왔다 갔다 하여야 하기 때문에 다음과 같이 수정이 됩니다.
if(selectVal==2)selectVal=0;
만약, 시/분만 왔다 갔다 해야 한다면
if(selectVal==3)selectVal=1;
어떻게 변경해야 할지 아시겠지요.
나머지도 수정해야 하는데 그대로 뒀습니다. 그냥 둬도 동작에는 영향이 없습니다.
출력부분에서 4개의 숫자만 출력되기 때문에 다음 부분을 수정해야 합니다.
void loop() { IRremoteRead(); //리모콘 읽기 if(output==false){ //시간 출력 readTime = millis()/1000; if(millis()>=86400000){ timer0_millis=0; } sec = readTime%60; min = (readTime/60)%60; hour = (readTime/(60*60))%24; segOutput(3,sec%10,0); //sec 1의 자리 segOutput(2,sec/10,0); //sec 10의 자리 segOutput(1,min%10,1); //min 1의 자리 segOutput(0,min/10,0); //min 10의 자리 // segOutput(1,hour%10,1); //hour 1의 자리 // segOutput(0,hour/10,0); //hour 10의 자리 } else{ //시간 조정 segOutput(3,clockVal[0]%10,0); //sec 1의 자리 segOutput(2,clockVal[0]/10,0); //sec 10의 자리 segOutput(1,clockVal[1]%10,1); //min 1의 자리 segOutput(0,clockVal[1]/10,0); //min 10의 자리 // segOutput(1,clockVal[2]%10,1); //hour 1의 자리 // segOutput(0,clockVal[2]/10,0); //hour 10의 자리 } }
분/초를 출력하기 때문에 시 부분을 주석 처리하시면 됩니다. 만약에 시/분을 출력하고 싶다면 초 부분을 주석처리하면 됩니다.
참고로,
** segOutput(segment display 위치,시간값,dp핀값)**
4개의 segment display으로 {0,1,2,3} 순서로대로 위치값을 갖기 때문에 출력 시간값의 위치는 정확히 지정해주시고 코딩해주세요.
수정한 부분을 종합 완성하면,
#include <IRremote.h> #define STATE 16736925 // ch버턴 #define SELECT_TIME 16748655 // EQ버턴 #define TIME_UP 16754775 // +버턴 #define TIME_DOWN 16769055 // -버턴 const byte IRpin = 2; IRrecv irrecv(IRpin); decode_results results; //a,b,c,d,e,f,g 상태값 const byte segValue[10][7] = { {1,1,1,1,1,1,0}, //0 {0,1,1,0,0,0,0}, //1 {1,1,0,1,1,0,1}, //2 {1,1,1,1,0,0,1}, //3 {0,1,1,0,0,1,1}, //4 {1,0,1,1,0,1,1}, //5 {1,0,1,1,1,1,1}, //6 {1,1,1,0,0,0,0}, //7 {1,1,1,1,1,1,1}, //8 {1,1,1,1,0,1,1} //9 }; const byte segPin[8]={7,3,A3,A1,A0,6,A4,A2}; //사용핀{a,b,c,d,e,f,g,dp} 순서대로임 const byte digitPin[4] = {8,5,4,A5}; //segment 위치 핀 boolean output = false;//시간 출력형식 지정 byte selectVal = 0; int clockVal[3]={0,0,0}; extern volatile unsigned long timer0_millis; //타이머변수 unsigned long readTime; //현재타이머시간 int hour, min, sec; void setup() { Serial.begin(9600); irrecv.enableIRIn(); // 리모콘 시작 for(int i=0;i<10;i++){ pinMode(segPin[i], OUTPUT); } for(int j=0;j<6;j++){ pinMode(digitPin[j], OUTPUT); digitalWrite(digitPin[j], HIGH); } } void loop() { IRremoteRead(); //리모콘 읽기 if(output==false){ //시간 출력 readTime = millis()/1000; if(millis()>=86400000){ timer0_millis=0; } sec = readTime%60; min = (readTime/60)%60; hour = (readTime/(60*60))%24; segOutput(3,sec%10,0); //sec 1의 자리 segOutput(2,sec/10,0); //sec 10의 자리 segOutput(1,min%10,1); //min 1의 자리 segOutput(0,min/10,0); //min 10의 자리 // segOutput(1,hour%10,1); //hour 1의 자리 // segOutput(0,hour/10,0); //hour 10의 자리 } else{ //시간 조정 segOutput(3,clockVal[0]%10,0); //sec 1의 자리 segOutput(2,clockVal[0]/10,0); //sec 10의 자리 segOutput(1,clockVal[1]%10,1); //min 1의 자리 segOutput(0,clockVal[1]/10,0); //min 10의 자리 // segOutput(1,clockVal[2]%10,1); //hour 1의 자리 // segOutput(0,clockVal[2]/10,0); //hour 10의 자리 } } void IRremoteRead(){ if (irrecv.decode(&results)) //리모콘 누른값이 없다면 패스 { if(results.value==STATE){ output=!output; if(output==false){ hour = clockVal[2]; min = clockVal[1]; sec = clockVal[0]; timer0_millis = ((long)hour*3600+min*60+sec)*1000; } else{ selectVal=0; for(int i=0;i<3;i++){ clockVal[i]=0; } } } if(output==true){ if(results.value==SELECT_TIME){ selectVal++; if(selectVal==2)selectVal=0; } if(results.value==TIME_UP)clockVal[selectVal]++; else if(results.value==TIME_DOWN) clockVal[selectVal]--; if(selectVal==2){ if(clockVal[selectVal]==24)clockVal[selectVal]=0; else if(clockVal[selectVal]==-1)clockVal[selectVal]=23; } else{ if(clockVal[selectVal]==60)clockVal[selectVal]=0; else if(clockVal[selectVal]==-1)clockVal[selectVal]=59; } } //Serial.println(results.value); //key value irrecv.resume(); // 다음값 } } //LED 초기화 void segClear(){ for(int i=0;i<8;i++){ digitalWrite(segPin[i], LOW); } } //LED 출력 void segOutput(int d, int Number, int dp){ segClear(); digitalWrite(digitPin[d], LOW); for(int i=0;i<7;i++){ digitalWrite(segPin[i], segValue[Number][i]); } digitalWrite(segPin[7], dp); delayMicroseconds(1000); digitalWrite(digitPin[d], HIGH); }
3. 결과
- CH => 시간입력 ON/OFF
- EQ => 시간 입력 제어 위치
- +/-=> 숫자 증감/감소
CH 버턴을 누르면 시간을 입력 할 준비 상태가 됩니다. +/- 바로 누르면 sec가 움직입니다. EQ를 누르면 min 위치로 이동하고 다시 +/-를 누르면 min이 움직입니다. 입력 할 시간 세팅이 끝나면 CH 버턴을 누르면 입력된 시간이 타이머변수에 세팅이 되고 그때부터 시간이 흘러가고 4-Digit 7-Segment Display에 현재 분/초를 출력하게 됩니다.
마무리
오늘은 Digit 7-Segment Display 부품에 분/초가 출력되는데 여기에 리모콘을 누르면 분/초를 조정할 수 있게 됩니다. 참고로 실험에서는 시 부분은 0시로 무조건 초기 세팅이 되고 분/초가 제어가 이루어지기 때문에 위 소스로만 제작한다면 약간 아두이노 시계라고 보기 어렵습니다. 수정하셔서 시/분으로 제작하시고 60초를 버리고 시/분을 입력하여 초는 무조건 0초부터 시작하게 수정하시면 진자 아두이노 시계 느낌으로 제작이 완료 됩니다. 이 부분은 위 코딩 수정부분을 보시면 어디를 수정하면 원하는 결과가 나올지는 찾을 수 있을거라 생각됩니다. 한번 수정해 보세요.
여기서 직접 리모콘까지 아두이노로 만들어 보았으면 좋은데 송신부 부품이 없어서 아깝게 아두이노 리모콘 제작은 못 보여드리네요. 혹시 관심이 있으시면 아두이노 리모콘 만들기를 구글 검색하시면 간단한 에제 소스를 보실 수 있으니깐 만들어 보실분들은 한번 도전해 보세요. 아두이노 리모콘을 만드시면 나중에 가정 전자제품의 리모콘의 키값을 아두이노로 IR Sensor(수신부)로 읽을 수 있으면 아두이노 리모콘에 그 키값을 저장했다가 실제 가정 전자제품을 직접 만든 아두이노 리모콘으로 제어할 수 있습니다. 여러개의 리모콘 값을 아두이노 리모콘으로 통합시키면 하나의 리모콘으로 모든 가전제품을 제어할 수 있게 되니깐 호기심이 있는 분들은 꼭 실험해 보세요.
'IOT > 아두이노' 카테고리의 다른 글
[아두이노] 아두이노 키보드 제어 (0) | 2019.06.24 |
---|---|
[아두이노] 아두이노 마이크로 보드 제어 (0) | 2019.06.21 |
[아두이노] 6-Digit 7-Segment Display 시계 리모콘 제어 (0) | 2019.06.19 |
[아두이노] 4-Digit 7-Segment Display 가상시뮬레이터 실험 (1) | 2019.06.18 |
[아두이노] 4-Digit 7-Segment Display 시계 만들기 (0) | 2019.06.15 |