인터넷 시간을 통해서 주기적으로 실제 시간을 업데이트해주는 시계입니다. 시간을 맞출 필요가 없이 스스로 알아서 해결합니다 ^^*
동작 사진
옆면
테스트 과정
3D 모델링 파일
부품 설치
우선 NodeMCU 보드를 400 tie 빵판 맨 위에 끼어넣습니다. 이후 부품들은 아래와 같이 연결합니다.
Jumper 10mm: Vcc - a1
Jumper 8mm: Gnd - a2
Jumper 10mm: j2 - Gnd
Jumper 8mm: j5 - Vcc
Jumper FM: RTC.Vcc - Vcc
Jumper FM: RTC.Gnd - Gnd
Jumper FM: RTC.CLK - a6
Jumper FM: RTC.DAT - a7
Jumper FM: RTC.RST - a8
Jumper FM: TM1637.Vcc - Vcc
Jumper FM: TM1637.Gnd - Gnd
Jumper FM: TM1637.CLK - a11
Jumper FM: TM1637.DIO - a13
RTC: Real-time Clock
TM1637: 4 digit LED tube
보드 준비 및 라이브러리 설치
라이브러리 설치
Real-time clock: https://github.com/msparks/arduino-ds1302
RyuLib for Arduino를 설치하면 위의 두 개의 라이브러리도 함께 설치됩니다. 다양한 예제 소스도 함께 설치 됩니다.
소스 코드
#include#include #include #include const int MAX_CONNECT_TIME = 300; const int QUERY_INTERVAL = 3000; const char* ssid = "공유기 ID"; const char* password = "공유기 비번"; const char* host = "www.timeapi.org"; const int httpsPort = 80; const String url = "/utc/now"; // TM1637 LED tube pin const int led_clk_pin = 2; const int led_io_pin = 4; // Realtime Clock pin const int rt_ce_pin = 14; const int rt_io_pin = 12; const int rt_clk_pin = 13; TM1637Display display(led_clk_pin, led_io_pin); DS1302 rtc(rt_ce_pin, rt_io_pin, rt_clk_pin); void setup() { Serial.begin(9600); display.setBrightness(0x0f); rtc.writeProtect(false); rtc.halt(false); Serial.print("connecting to "); Serial.println(ssid); WiFi.begin(ssid, password); } int tick_count = 0; bool display_dots = false; void displayTime() { uint8_t data[] = { 0b00000000, 0b00000000, 0b00000000, 0b00000000 }; Time t = rtc.time(); int hr_lo = t.hr % 10; int hr_hi = (t.hr - hr_lo) / 10; if (hr_hi < 1) data[0] = display.encodeDigit(0); else data[0] = display.encodeDigit(hr_hi); if (hr_lo < 1) data[1] = display.encodeDigit(0); else data[1] = display.encodeDigit(hr_lo); int min_lo = t.min % 10; int min_hi = (t.min - min_lo) / 10; if (min_hi < 1) data[2] = display.encodeDigit(0); else data[2] = display.encodeDigit(min_hi); if (min_lo < 1) data[3] = display.encodeDigit(0); else data[3] = display.encodeDigit(min_lo); tick_count++; if (tick_count >= 5) { tick_count = 0; display_dots = ! display_dots; if (display_dots) data[1] = data[1] | 0b10000000; } display.setSegments(data); } int time_out = 0; int query_count = 9999; void loop() { displayTime(); time_out++; if (WiFi.status() != WL_CONNECTED) { if (time_out > MAX_CONNECT_TIME) { time_out = 0; // Serial.print("connecting to "); // Serial.println(ssid); // WiFi.begin(ssid, password); } Serial.println("WiFi is not ready."); delay(100); return; } time_out = 0; query_count++; delay(100); if (query_count < QUERY_INTERVAL) return; query_count = 0; // Serial.println(""); // Serial.println("WiFi connected."); // Serial.println("IP address: "); // Serial.println(WiFi.localIP()); WiFiClient client; // Serial.print("connecting to "); Serial.println(host); if (!client.connect(host, httpsPort)) { Serial.println("connection failed."); delay(1000); return; } client.print(String("GET ") + url + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "User-Agent: BuildFailureDetectorESP8266\r\n" + "Connection: close\r\n\r\n"); // Read Header while (client.connected()) { String line = client.readStringUntil('\n'); if (line == "\r") break; } // Read Body if (client.connected()) { String line = client.readStringUntil('\n'); // Korean local time need to add 9 hours. String hour = line.substring(11,13); String minute = line.substring(14,16); String second = line.substring(17,19); Time t(2016, 1, 1, (hour.toInt() + 9) % 24, minute.toInt(), second.toInt(), Time::kSunday); rtc.time(t); } }
NodeMCU의 경우 함수 실행에 시간이 오래 걸리면 리부팅이 계속 진행되는 현상이 있었습니다. 그 때문에 코드가 조금 복잡해졌습니다.
Orange Pi Zero 사용 후기 (0) | 2016.12.01 |
---|---|
미아 방지기 만들기 (0) | 2016.10.06 |
중국산 Arduino YUN shield 테스트 실패 (0) | 2016.10.02 |
NodeMCU 프로그래밍 (0) | 2016.09.23 |
자전거 안전등 #2 (0) | 2016.09.22 |