[아두이노] 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의 소개한 소스를 실제 코딩에도 그대로 적용됩니다. 사전학습 종합소스와 아래 수정 할 부분을 같이 보고 어느 부분을 수정되었는지 같이 보시면서 읽어주세요. 아니면 아래 수정한 종합소스를 보면서 수정한 부분의 위치가 어느 위치이고 수정됐는지 같이 보면서 이해하시기 바랍니다. 그 이유는 그냥 아래 수정 할 부분에 이부분을 수정합니다라고 이야기 하기 때문에 말하는 부분이 정확이 어느 부분인지 혼동할 수 있기 때문에 꼭 종합소스를 같이 봐주세요.
수정 할 부분은 리모콘 키값부분입니다.
사용할 버턴은 위 사진에서 보는 버턴들을 이용 합니다. 이 부분의 키값을 알려면 리모콘 키값 조회 공개회로도 보시고 맞게 코딩을 수정한 뒤에 키 값을 알아내고 그 키값을 아래와 같이 수정하변 됩니다.
1 2 3 4 | #define STATE 16736925 // ch버턴 #define SELECT_TIME 16748655 // EQ버턴 #define TIME_UP 16754775 // +버턴 #define TIME_DOWN 16769055 // -버턴 |
다음으로 4-Digit 7-Segment Display 핀 번호에 대해서 변수 수정을 해야 합니다.
1 2 | 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 위치 핀 |
다음 수정부분은
1 2 3 4 5 | if (output== true ){ if (results.value==SELECT_TIME){ selectVal++; if (selectVal== 3 )selectVal= 0 ; } |
이 부분으로 원래는 시/분/초 3개의 시간위치가 기존 소스에 있었지만 두개를 분/초를 이용하기 때문에 분/초 위치만 왔다 갔다 하여야 하기 때문에 다음과 같이 수정이 됩니다.
1 | if (selectVal== 2 )selectVal= 0 ; |
만약, 시/분만 왔다 갔다 해야 한다면
1 | if (selectVal== 3 )selectVal= 1 ; |
어떻게 변경해야 할지 아시겠지요.
나머지도 수정해야 하는데 그대로 뒀습니다. 그냥 둬도 동작에는 영향이 없습니다.
출력부분에서 4개의 숫자만 출력되기 때문에 다음 부분을 수정해야 합니다.
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 | 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} 순서로대로 위치값을 갖기 때문에 출력 시간값의 위치는 정확히 지정해주시고 코딩해주세요.
수정한 부분을 종합 완성하면,
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 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | #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 |