티스토리 뷰
[IoT-MODLINK] 1. 주제 및 기획
(http://cafe.naver.com/arduinoguide/3601)
[IoT-MODLINK] 2. 도어락 제어하기
(http://cafe.naver.com/arduinoguide/3602)
[IoT-MODLINK] 3. 열림/닫힘 상태 확인하기
(http://cafe.naver.com/arduinoguide/3603)
[IoT-MODLINK] 4. 조명 효과 & 외부 전원 공급하기
(http://cafe.naver.com/arduinoguide/3604)
[IoT-MODLINK] 5. 출입 로그 관리 & 케이스 제작
(http://cafe.naver.com/arduinoguide/3732)
드디어 마무리 지었습니다!
음... 일단!
원래 계획했던 내용 중에 하나가 모터를 제어해서 금고 기능을 하는 것을 만드는 것이었는데
이 부분이 주제와 맞지 않다고 생각되어 이 부분을 제외하고, RTC모듈로 출입 로그를 넣는 것으로 방향을 바꿨습니다.
다행히 잘 구현되어서 이렇게 완성할 수 있게 됐습니다!
코드 리뷰 > 설치 사진 > 작동 영상 > 후기 순으로 진행하겠습니다.
(1) 코드 리뷰
아무래도 이런 프로젝트 경험이 없을 뿐더러 학생의 코드라
이해하시기 곤란하실 것 같네요.
그래서 대략적인 코드 진행 방향만 설명 해보도록 하겠습니다!
일단 전체 코드와 UI입니다.
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 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 | // 헤더 & 네임스페이스 #include <VitconBrokerComm.h> #include <Adafruit_NeoPixel.h> #include <Wire.h> #include <TimeLib.h> #include <DS1307RTC.h> using namespace vitcon; // // 매크로 & 구조체 #define ITEM_COUNT 12 #define DELAY_COUNT 2 // Delay를 사용하는 모듈의 수 #define HOW_MANY_DATA 100 // 초음파 센서의 표본 데이터의 수 #define doorRelay 3 #define trig 4 #define echo 5 #define LEDPIN 8 typedef struct { bool sts = LOW; unsigned long prev = 0; }TIMER; /* millis()함수를 이용하게 되면 보통 위 구조체에 선언된 2개의 변수가 필요하기 때문에, 아예 묶어서 구조체로 관리한다. */ // // 전역 변수 bool ison; // LED의 점등 여부 확인 char msg[50]="X"; // 출입 로그를 저장하는 문자열 int dataCounter; // 초음파 센서의 표본 데이터의 수를 카운팅 int ledValueR,ledValueG,ledValueB; float distanceData; // 표본 데이터의 값을 저장하는 변수 char *monthName[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; tmElements_t tm; // RTC 모듈에 사용되는 객체 TIMER check[DELAY_COUNT]; // delay가 필요한 모듈의 수 만큼 선언 후 배열로 관리 Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, LEDPIN, NEO_GRB + NEO_KHZ800); // 60pin LEDstrip을 사용하기 위한 객체 // // 함수 원형 void myDelay(bool, int, int); void isOpen(); void rainbowCycle(bool); void timeSetting(); uint32_t Wheel(byte); // // Funtions(from server to device) void relaySignal(bool val) { /* 문 열림 버튼이 눌렸을 때 작동하는 함수 */ digitalWrite(doorRelay, val); if( val == HIGH ) rainbowCycle(val); } void lightSignal(bool val){ /* LED 토글 버튼이 눌렸을 때 작동하는 함수 */ if(val == HIGH && ison == LOW){ uint32_t ledValue = strip.Color(ledValueR,ledValueG,ledValueB); for(int i =0 ; i<strip.numPixels();i++) strip.setPixelColor(i,ledValue); ison = HIGH; strip.show(); } if( val == LOW && ison == HIGH){ for(int i=0; i<strip.numPixels(); i++) strip.setPixelColor(i,0); ison = LOW; strip.show(); } } void ledValueSignalR(int32_t val){ /* RGB 트랙바의 값이 변경될 때 작동하는 함수 */ if( ((int)val) != ledValueR ) ison = LOW; ledValueR = (int)val; } void ledValueSignalG(int32_t val){ if( ((int)val) != ledValueG ) ison = LOW; ledValueG = (int)val; } void ledValueSignalB(int32_t val){ if( ((int)val) != ledValueB ) ison = LOW; ledValueB = (int)val; } // //IOTITEM IOTItemBin relay(relaySignal); IOTItemBin light(lightSignal); IOTItemBin doorStatus; IOTItemBin ledStatus; IOTItemInt ledValueWriterR(ledValueSignalR); IOTItemInt ledValueWriterG(ledValueSignalG); IOTItemInt ledValueWriterB(ledValueSignalB); IOTItemInt ledValueReaderG; IOTItemInt ledValueReaderR; IOTItemInt ledValueReaderB; IOTItemInt distance; IOTItemStr str; IOTItem *items[ITEM_COUNT] = { &relay, &doorStatus, &distance, &ledStatus, &light, &ledValueReaderR, &ledValueWriterR, &ledValueReaderG, &ledValueWriterG, &ledValueReaderB, &ledValueWriterB, &str}; const char device_id[] = "3f1e9d56897c741ae09c95f001f5c100"; BrokerComm comm(&Serial, device_id, items, ITEM_COUNT); // void setup() { pinMode(doorRelay, OUTPUT); pinMode(trig,OUTPUT); pinMode(echo, INPUT); strip.begin(); strip.show(); comm.SetInterval(100); Serial.begin(250000); } void loop() { isOpen(); /* 초음파 센서를 이용해 열림 확인 */ ledValueReaderR.Set(ledValueR); ledValueReaderG.Set(ledValueG); ledValueReaderB.Set(ledValueB); /* 트랙바 값 Setting */ str.Set(msg); /* 출입 로그 */ comm.Run(); } void myDelay(bool value, int idx, int interval){ /* millis를 이용한 delay기능을 수행하는 함수 */ if ( value ){ check[idx].prev = millis(); check[idx].sts = HIGH; } if( millis() - check[idx].prev >= interval) check[idx].sts = LOW; } void isOpen(){ /* 초음파 센서 값을 이용해 문 열림 확인하는 함수 */ float duration, dist; if( check[1].sts == LOW ){ check[1].sts == HIGH; digitalWrite(trig,HIGH); myDelay(check[1].sts, 1, 1); } if( check[1].sts == HIGH ) return; // 아직 딜레이 중 digitalWrite(trig,LOW); duration = pulseIn(echo,HIGH); dist = ( (float)(340*duration)/10000 ) / 2; if( dist > 1000 || dist < 1 ) return; // 무의미한 센서 값 distanceData += dist; dataCounter++; if( dataCounter >= HOW_MANY_DATA){ distanceData /= HOW_MANY_DATA; if( dist >= 10 ){ // 문 열림 감지 doorStatus.Set(HIGH); timeSetting(); } else {// 문 닫혀 있음 doorStatus.Set(LOW); } distance.Set(distanceData); dataCounter = distanceData = 0; } } void timeSetting(){ /* 문이 열렸을 경우 출입 로그 업데이트하는 함수 */ char tmp[50] = {0}; msg[0] = 0; if (RTC.read(tm)) { itoa(tm.Day,tmp,10); // 날짜 strcat(msg,tmp); strcat(msg," "); strcat(msg,monthName[tm.Month-1]); // 달 이름 변환 strcat(msg,", "); if(tm.Hour < 10 ) strcat(msg,"0"); itoa(tm.Hour,tmp,10); // 시간 strcat(msg,tmp); strcat(msg,":"); if(tm.Minute < 10 ) strcat(msg,"0"); itoa(tm.Minute,tmp,10); // 분 strcat(msg,tmp); strcat(msg,":"); if(tm.Second < 10 ) strcat(msg,"0"); itoa(tm.Second,tmp,10); // 초 strcat(msg,tmp); } } void rainbowCycle(bool val) { /* 웹/앱을 이용해 문이 열렸을 경우 LED를 밝히는 함수 */ uint16_t i, j; uint32_t ledValue = 0; for(j=0; j<256; j++) { for(i=0; i< strip.numPixels(); i++) { strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255)); } strip.show(); } if( val == HIGH ) digitalWrite(doorRelay, !val); if( ison == HIGH ) ledValue = strip.Color(ledValueR,ledValueG,ledValueB); for(i=0; i< strip.numPixels(); i++) strip.setPixelColor(i, ledValue); strip.show(); } uint32_t Wheel(byte WheelPos) { /* LED의 색상을 조정하는 함수 */ WheelPos = 255 - WheelPos; if(WheelPos < 85) { return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3); } if(WheelPos < 170) { WheelPos -= 85; return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3); } WheelPos -= 170; return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0); } | cs |
< UI >
일단 배선을 위해 도어락을 분해합니다.
긴장되는 순간... 버튼과 점퍼선을 납땜으로 고정시켜 줍시다!
+,- 전선도 알맞게 납땜한 후 사진!
납땜이 마무리되고 다시 조립합니다.
strip LED를 어떻게 꾸밀까 하다가,
급한대로 빛컨에 대한 저의 사랑을 표현...했습니다
설치 후 자꾸 문제가 발생하여 분해 후 설치를 약 3번 정도 반복하다보니 너무 시간이 많이 흘러
어쩔 수 없이 밤이 되서 완성하게 됐습니다.
(3) 작동 영상
문의 열림/닫힘 동작 시 원래 따르릉 따르릉~ 이 음이 아닌 다른 음이 나오는 것이 정상입니다.
따르릉 음이 나오는 이유는 도어락에 공급되는 전압이 일정 수치보다 낮아졌음을 의미하는데, 이 작동 영상을 촬영할 때
5V 어댑터를 이용해서 그렇습니다.
(집에 남는 어댑터가 19V와 5V밖에 없다보니..)
19V 어댑터로 진행할 경우 정상적인 음이 연주되며 작동하는데, 상대적으로 고전압이라 불안해서 5V로 진행했습니다.
어차피 건전지가 아닌 콘센트를 통해 전기가 공급되므로 큰 상관은 없다고 판단했습니다.
아직 전기에 대한 개념이 약해서 이런 부분에서는 너무 어렵습니다...
4. 후기
MODLINK의 장점은 무엇일까?
많고 많은 하드웨어 보드 중 이 보드가 부각될 수 있는 부분이 어떤 점일까?
이 고민으로부터 프로젝트를 시작했습니다.
MODLINK의 장점은 누구나 손 쉽게 IoT를 구현할 수 있다는 점입니다.
WIFI모듈의 사용 및 서버 구성에 대한 어려움을 덜어주고, 웹/앱에서의 UI를 드래그 앤 드롭으로 간편하게 구성할 수 있습니다.
그래서 생활에 쓰일 수 있는 물건에 적용하자는 생각에서 출발했습니다.
자취를 하는 저는 평소 택배를 시킬 때마다 정말 많이 고민합니다.
옆 집에서 받아줄 리 만무하고 경비실도 없기 때문이죠!
그리고 가끔 도어락 비밀번호를 모르는 부모님 또는 손님이 방문할 때에는 문을 열어주기 위해 집에서 기다려야 했습니다.
이 어려움을 잘 알고있던 지인의 추천으로 프로젝트를 시작했고, MODLINK 덕분에 성공할 수 있었습니다.
사실 컴퓨터 과학을 전공하면서 알고리즘 공부에 매진 해온 저는
하드웨어 쪽에 대한 지식이 많이 없었고, 이런 임베디드 프로그래밍을 해본 적이 많이 없다보니 어려운 점도 많았습니다.
( 모듈 간의 간섭, 당연시 여기던 Delay의 부재, 전류 공급 문제, 잘 되다가 안되는 정!말 이유 모를 문제 등등 )
그래서 그런지 완성에 가까워지니 그 동안 공부했던 내용들 중 예제가 존재하지 않는 주제에 대해
게시판에 글을 올리고 내가 경험한 내용을 적다보니 정~말 뿌듯했습니다...
댓글! 댓글! 달아주세요! 너무 좋아요....
( UI꾸미기, MODLINK X RTC module)
운 좋게 선물 받은 MODLINK!
앞으로 꾸준히 사용해서 직접 좋은 결과물 많이 알릴 수 있으면 좋겠습니다.
좋은 추억 만들어주신 VITCON
2차 체험단 여러분 모두
수고하셨습니다.
그리고
감사합니다!
(따뜻한 연말 보내쎄요~)
'IOT-MODLINK' 카테고리의 다른 글
[Project – 스마트 도어락] 4. 출입 로그 관리 & 케이스 제작 (0) | 2017.12.19 |
---|---|
[IoT-MODLINK] RTC모듈을 이용한 실시간 시간확인! (0) | 2017.12.19 |
[IoT-MODLINK] 웹/앱 UI를 더 이쁘게 꾸미자! (0) | 2017.12.19 |
[Project – 스마트 도어락] 4. 조명 효과 & 외부 전원 공급하기 (0) | 2017.12.17 |
[Project – 스마트 도어락] 3. 열림/닫힘 상태 확인하기 (0) | 2017.12.17 |