WeMOS: D1 R1 mini LCD I2C RTC NTP Sync
Jump to navigation
Jump to search
Sumber: https://github.com/doleynikov/esp-01-ds1307-ntp-clock/blob/master/working_clock_b_8266.ino
// This is for compatibility with both arduino 1.0 and previous versions //#include <Arduino.h> #include <Wire.h> #include <LiquidCrystal_I2C.h> #define printByte(args) write(args); #include "RTClib.h" #include <ESP8266WiFi.h> #include <WiFiUdp.h> //char ssid[] = "mao"; // your network SSID (name) //char pass[] = "maomaomao"; // your network password char ssid[] = "yuterra.main"; // your network SSID (name) char pass[] = "apwh46fds"; // your network password unsigned int localPort = 2390; // local port to listen for UDP packets IPAddress timeServerIP; //const char* ntpServerName = "time.nist.gov"; const char* ntpServerName = "ntp.yuterra.ru"; int TZ = 3; const int NTP_PACKET_SIZE = 48; byte packetBuffer[ NTP_PACKET_SIZE]; WiFiUDP udp; LiquidCrystal_I2C lcd(0x27, 16, 2); RTC_DS1307 rtc; char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; int eval1 = 0; int bl = 0; int Hour = 0; int Minute = 0; int Second = 0; int Year = 0; int Month = 0; int Day = 0; byte degree[8] = { B01000, B10100, B01000, B00111, B01000, B01000, B01000, B00111, }; byte moon[8][8] = { { B10001, B00111, B00111, B01111, B01111, B00111, B00111, B10001, }, { B10001, B11100, B11100, B11110, B11110, B11100, B11100, B10001, }, { B10001, B00011, B00011, B00011, B00011, B00011, B00011, B10001, }, { B10001, B11000, B11000, B11000, B11000, B11000, B11000, B10001, }, { B10000, B00000, B00000, B00000, B00000, B00000, B00000, B10000, }, { B00001, B00000, B00000, B00000, B00000, B00000, B00000, B00001, }, { B10001, B00110, B00100, B01100, B01100, B00100, B00110, B10001, }, { B10001, B01100, B00100, B00110, B00110, B00100, B01100, B10001, } }; void setup() { Wire.begin(0, 2); lcd.init(); // initialize the lcd lcd.backlight(); bl = 1; lcd.clear(); lcd.createChar(0, degree); lcd.print("Starting..."); Serial.begin(9600); if (! rtc.begin()) { Serial.println("Couldn't find RTC"); lcd.setCursor(0, 0); // устанавливаем позицию курсора на экране (на один символ правее левого верхнего угла) lcd.print("Couldn't find RTC"); while (1); } use(); WiFi.begin(ssid, pass); int i = 0; while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); if (i++ > 20) { break; // no wifi } } Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); Serial.println("Starting UDP"); udp.begin(localPort); Serial.print("Local port: "); Serial.println(udp.localPort()); delay(100); getNtpTime(); } void loop() { if (Serial.available()) { write_RTC(); } DataRead (); DataDisplay(); delay (10); } char getPhase(int Y, int M, int D) { double AG, IP; char phase; long YY, MM, K1, K2, K3, JD; YY = Y - floor((12 - M) / 10); MM = M + 9; if (MM >= 12) MM = MM - 12; K1 = floor(365.25 * (YY + 4712)); K2 = floor(30.6 * MM + 0.5); K3 = floor(floor((YY / 100) + 49) * 0.75) - 38; JD = K1 + K2 + D + 59; if (JD > 2299160) JD = JD - K3; IP = normalize((JD - 2451550.1) / 29.530588853); AG = IP * 29.53; if (AG < 1.84566) { lcd.createChar(1, moon[4]); lcd.createChar(2, moon[5]); } else if (AG < 5.53699) { lcd.createChar(1, moon[4]); lcd.createChar(2, moon[7]); } else if (AG < 9.22831) { lcd.createChar(1, moon[4]); lcd.createChar(2, moon[1]); } else if (AG < 12.91963) { lcd.createChar(1, moon[2]); lcd.createChar(2, moon[1]); } else if (AG < 16.61096) { lcd.createChar(1, moon[0]); lcd.createChar(2, moon[1]); } else if (AG < 20.30228) { lcd.createChar(1, moon[0]); lcd.createChar(2, moon[3]); } else if (AG < 23.99361) { lcd.createChar(1, moon[0]); lcd.createChar(2, moon[5]); } else if (AG < 27.68493) { lcd.createChar(1, moon[6]); lcd.createChar(2, moon[5]); } else { lcd.createChar(1, moon[4]); lcd.createChar(2, moon[5]); } phase = AG; return phase; } double normalize(double v) { // normalize moon calculation between 0-1 v = v - floor(v); if (v < 0) v = v + 1; return v; } // use explanation message void use() { Serial.println("\nUSE : u U h[00-23]m[00-59]s[00-59]D[01-31]M[01-12]Y[00-49]"); Serial.println("\nEXEMPLE : h09m35d03 set time to 09h35 "); Serial.println("\nCommands : h** : hour, m** : minutes, s** : seconds "); Serial.println(" M** : month, Y** : year, D** : day of month."); Serial.println("u or U shows this message, b - backlight, all other caracter shows time."); } // DS1307 time read function void read_RTC() { DateTime now = rtc.now(); Serial.print("\nActual time : "); Serial.print(now.hour(), DEC); //read the hour Serial.print(":"); Serial.print(now.minute(), DEC); //read minutes without update (false) Serial.print(":"); Serial.print(now.second(), DEC); //read seconds Serial.print(" "); // some space for a more happy life Serial.print(daysOfTheWeek[now.dayOfTheWeek()]); Serial.print(" "); Serial.print(now.day(), DEC); //read date Serial.print("/"); Serial.print(now.month(), DEC); //read month Serial.print("/"); Serial.println(now.year(), DEC); //read year } String addZero(int val) { if (val < 10) return "0" + String(val); else return String(val); } // set clock values void write_RTC() { char value = 0; char command = 0; command = Serial.read(); delay(50); //delay to allow good serial port reading value = byte((Serial.read() - 48) * 10); //-48 becaus ASCII value for 0 is 48, 1 is 49, etc and *10 because we read tens first delay(50); value += byte((Serial.read() - 48)); //and then we read units switch (command) { case 'h' : Hour = value; Serial.print("hours set to "); Serial.println(value, DEC); break; case 'm' : Minute = value; Serial.print("minutes set to "); Serial.println(value, DEC); break; case 's' : Second = value; Serial.print("seconds set to "); Serial.println(value, DEC); break; case 'D' : Day = value; Serial.print("day of month set to "); Serial.println(value, DEC); break; case 'M' : Month = value; Serial.print("month set to "); Serial.println(value, DEC); break; case 'Y' : Year = value; Serial.print("year set to "); Serial.println(value, DEC); break; case 'u' : case 'U' : use(); break; case 'r' : // RTC.stop(); Serial.println("Clock stopped"); break; case 'R' : // RTC.start(); Serial.println("Clock running"); lcd.init(); // initialize the lcd lcd.backlight(); lcd.clear(); break; case 'b' : if ( bl == 1) { lcd.noBacklight(); bl = 0; } else { lcd.backlight(); bl = 1; } break; default : break; } // This line sets the RTC with an explicit date & time, for example to set // January 21, 2014 at 3am you would call: // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0)); // int Hour = 0; int Minute = 0; int Second = 0; int Year = 0; int Month = 0; int Day = 0; rtc.adjust(DateTime(Year, Month, Day, Hour, Minute, Second)); delay(100); read_RTC(); } void DataRead () { int i; DateTime now = rtc.now(); Hour = now.hour(); // Получаем значение текущего часа Minute = now.minute(); Second = now.second(); Year = now.year(); Month = now.month(); Day = now.day(); getPhase(Year, Month, Day); } void DataDisplay () { lcd.setCursor(0, 0); // устанавливаем позицию курсора на экране (на один символ правее левого верхнего угла) lcd.print(addZero(Hour)); lcd.print(":"); lcd.print(addZero(Minute)); lcd.print(":"); lcd.print(addZero(Second)); // Выводим время lcd.setCursor(0, 1); lcd.print(addZero(Day)); lcd.print("/"); lcd.print(addZero(Month)); lcd.print("/"); lcd.print(addZero(Year)); lcd.setCursor(14, 1); lcd.printByte(1); lcd.printByte(2); //delay(100); } void getNtpTime() { //get a random server from the pool WiFi.hostByName(ntpServerName, timeServerIP); sendNTPpacket(timeServerIP); // send an NTP packet to a time server // wait to see if a reply is available delay(1000); int cb = udp.parsePacket(); if (!cb) { Serial.println("no tnp response yet"); } else { Serial.print("ntp response received, length="); Serial.println(cb); // We've received a packet, read the data from it udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer //the timestamp starts at byte 40 of the received packet and is four bytes, // or two words, long. First, esxtract the two words: unsigned long highWord = word(packetBuffer[40], packetBuffer[41]); unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]); // combine the four bytes (two words) into a long integer // this is NTP time (seconds since Jan 1 1900): unsigned long secsSince1900 = highWord << 16 | lowWord; Serial.print("Seconds since Jan 1 1900 = " ); Serial.println(secsSince1900); // now convert NTP time into everyday time: Serial.print("Unix time = "); // Unix time starts on Jan 1 1970. In seconds, that's 2208988800: const unsigned long seventyYears = 2208988800UL; // subtract seventy years: unsigned long epoch = secsSince1900 - seventyYears; // print Unix time: Serial.println(epoch); // print the hour, minute and second: Serial.print("The UTC time is "); // UTC is the time at Greenwich Meridian (GMT) Hour = (epoch % 86400L) / 3600; Serial.print(Hour); // print the hour (86400 equals secs per day) Serial.print(':'); Minute = (epoch % 3600) / 60; Serial.print(Minute); // print the minute (3600 equals secs per minute) Serial.print(':'); Second = epoch % 60; Serial.println(epoch % 60); // print the second DateTime now = rtc.now(); // Hour = now.hour(); // Получаем значение текущего часа // Minute = now.minute(); // Second = now.second(); Year = now.year(); Month = now.month(); Day = now.day(); Serial.println("Ajust RTC!"); // print the second rtc.adjust(DateTime(Year, Month, Day, Hour + TZ, Minute, Second)); } } // send an NTP request to the time server at the given address unsigned long sendNTPpacket(IPAddress& address) { Serial.println("sending NTP packet..."); // set all bytes in the buffer to 0 memset(packetBuffer, 0, NTP_PACKET_SIZE); // Initialize values needed to form NTP request // (see URL above for details on the packets) packetBuffer[0] = 0b11100011; // LI, Version, Mode packetBuffer[1] = 0; // Stratum, or type of clock packetBuffer[2] = 6; // Polling Interval packetBuffer[3] = 0xEC; // Peer Clock Precision // 8 bytes of zero for Root Delay & Root Dispersion packetBuffer[12] = 49; packetBuffer[13] = 0x4E; packetBuffer[14] = 49; packetBuffer[15] = 52; // all NTP fields have been given values, now // you can send a packet requesting a timestamp: udp.beginPacket(address, 123); //NTP requests are to port 123 udp.write(packetBuffer, NTP_PACKET_SIZE); udp.endPacket(); }