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();
}