2015/11/02
Arduino時計をESP-WROOM-02でNTP同期させる
前記事の「Arduino+7Seg LED+RTCでデジタル時計」にESP-WROOM-02を接続して、NTP時刻同期します。
WROOMはWi-Fiアクセスポイント経由で60秒毎(正常動作が確認できたら間隔は長くする)にタイムサーバに接続し、標準時刻を受信します。受信した時刻情報はUART経由でArduino UNOに送出し時刻を同期させます。
Arduino UNO側のスケッチはそのままです。
Arduino+ESP-WROOM-02デジタルクロック全体写真
ESP-WROOM-02ドータ写真
ESP-WROOM-02回路図
NTPGet.ino
*2015/12/23 WiFi接続処理を追加しました(行番号76-83)
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 |
#include <ESP8266WiFi.h> #include <WiFiUdp.h> char ssid[] = "YourNetworkSSID"; char pass[] = "YourNetworkPassword"; #define DEBUGP(x) // Serial.print(x) #define LED1 13 #define NTP_SERVER_NAME "time.nist.gov" #define LOCAL_PORT 8888 WiFiUDP udp; IPAddress timeServerIP; #define NTP_PACKET_SIZE 48 // NTP time stamp is in the first 48 bytes of the message byte ntpPacketBuff[NTP_PACKET_SIZE]; // buffer to hold incoming and outgoing packets #define TIME_ZONE (9 * 60 * 60) void sendNTPpacket() { WiFi.hostByName(NTP_SERVER_NAME, timeServerIP); memset(ntpPacketBuff, 0, NTP_PACKET_SIZE); ntpPacketBuff[ 0] = 0b11100011; // LI, Version, Mode ntpPacketBuff[ 1] = 0; // Stratum, or type of clock ntpPacketBuff[ 2] = 6; // Polling Interval ntpPacketBuff[ 3] = 0xEC; // Peer Clock Precision ntpPacketBuff[12] = 49; ntpPacketBuff[13] = 0x4E; ntpPacketBuff[14] = 49; ntpPacketBuff[15] = 52; udp.beginPacket(timeServerIP, 123); udp.write(ntpPacketBuff, NTP_PACKET_SIZE); udp.endPacket(); } uint32_t recvNTPpacket() { if (udp.parsePacket() >= NTP_PACKET_SIZE) { udp.read(ntpPacketBuff, NTP_PACKET_SIZE); uint32_t timess = (word(ntpPacketBuff[40], ntpPacketBuff[41]) << 16 | word(ntpPacketBuff[42], ntpPacketBuff[43])) - 2208988800UL + (TIME_ZONE); return (timess); } return 0; } byte monthDays[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; void breakTime(unsigned long times, byte *tm) { tm[5] = times % 60; times /= 60; tm[4] = times % 60; times /= 60; tm[3] = times % 24; times /= 24; tm[6] = ((times + 4) % 7) + 1; times = (times + 366 + 365) * 100; // offset from 1968/ 1/ 1 tm[0] = (times / 36525) - 2; times = (times % 36525) / 100 ; times++; monthDays[1] = ((((tm[0] + 1970) % 4) == 0) ? 29 : 28); // 151121 for (tm[1] = 0; tm[1] < 12; tm[1]++) { if (times <= monthDays[tm[1]]) break; times -= monthDays[tm[1]]; } tm[1]++; tm[2] = times; } void setup() { pinMode(LED1, OUTPUT); Serial.begin(115200); // 151223 >> DEBUGP("\n\nConnecting to "); DEBUGP(ssid); DEBUGP(" "); WiFi.begin(ssid, pass); while (WiFi.status() != WL_CONNECTED) { DEBUGP("."); delay(500); } DEBUGP("\nWiFi connected\n"); DEBUGP("IP address: "); DEBUGP(WiFi.localIP()); DEBUGP("\n"); // << DEBUGP("Starting UDP"); udp.begin(LOCAL_PORT); DEBUGP("Local port: "); DEBUGP(udp.localPort()); DEBUGP("\n"); } void loop() { unsigned long times, pre_ms; byte tm[7]; while (1) { pre_ms = millis(); digitalWrite(LED1, LOW); sendNTPpacket(); for (int loop = 0; loop < 200; loop++) { if (times = recvNTPpacket()) { breakTime(times, tm); tm[0] -= (2000 - 1970); for (int j = 0; j < 6; j++) { if (tm[j] < 10) Serial.print("0"); Serial.print(tm[j]); } Serial.print("\r"); digitalWrite(LED1, HIGH); break; } delay(10); } delay(1000); delay((1000 * 58) + 2000 - (millis() - pre_ms)); } } |
この記事へのトラックバック URL :
Leave a comment