mirror of
https://github.com/balkian/ESP8266_Clock_NTP.git
synced 2024-12-22 09:18:13 +00:00
First commit
This commit is contained in:
commit
1c35014641
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
passwords.h
|
||||||
|
.*
|
37
README.md
Normal file
37
README.md
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
ESP8266-based clock that uses NTP to stay in sync, and a DHT11/22 to also display the temperature and humidity.
|
||||||
|
|
||||||
|
WORK IN PROGRESS.
|
||||||
|
|
||||||
|
# Connections
|
||||||
|
|
||||||
|
| ILI9341 SPI TFT | NodeMCU |
|
||||||
|
|-----------------|---------|
|
||||||
|
| VCC | 3.3V |
|
||||||
|
| GND | GND |
|
||||||
|
| CS | D2 |
|
||||||
|
| REST | RST |
|
||||||
|
| DC | D1 |
|
||||||
|
| SDI/MOSI | D7 |
|
||||||
|
| SCK | D5 |
|
||||||
|
| LED | 3.3V |
|
||||||
|
| SDO/MISO | D6 |
|
||||||
|
|
||||||
|
|
||||||
|
| DHT11 | NodeMCU |
|
||||||
|
|-------|---------|
|
||||||
|
| VCC | 3.3V |
|
||||||
|
| Data | D0 |
|
||||||
|
| GND | GND |
|
||||||
|
|
||||||
|
# Arduino ESP8266 support
|
||||||
|
|
||||||
|
Boards manager link: http://arduino.esp8266.com/stable/package_esp8266com_index.json
|
||||||
|
|
||||||
|
# Libraries
|
||||||
|
|
||||||
|
Some of them are available via the Arduino library manager
|
||||||
|
|
||||||
|
* https://github.com/PaulStoffregen/Time
|
||||||
|
* https://github.com/JChristensen/Timezone
|
||||||
|
* https://github.com/Bodmer/TFT_eSPI
|
||||||
|
* https://github.com/beegee-tokyo/DHTesp
|
360
TFT_Clock_Digital_NTP.ino
Normal file
360
TFT_Clock_Digital_NTP.ino
Normal file
@ -0,0 +1,360 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
ESP8266-based clock that uses NTP to stay in sync, and a DHT11/22
|
||||||
|
to also display the temperature and humidity.
|
||||||
|
|
||||||
|
| ILI9341 SPI TFT | NodeMCU |
|
||||||
|
|-----------------|---------|
|
||||||
|
| VCC | 3.3V |
|
||||||
|
| GND | GND |
|
||||||
|
| CS | D2 |
|
||||||
|
| REST | RST |
|
||||||
|
| DC | D1 |
|
||||||
|
| SDI/MOSI | D7 |
|
||||||
|
| SCK | D5 |
|
||||||
|
| LED | 3.3V |
|
||||||
|
| SDO/MISO | D6 |
|
||||||
|
|
||||||
|
|
||||||
|
| DHT11 | NodeMCU |
|
||||||
|
|-------|---------|
|
||||||
|
| VCC | 3.3V |
|
||||||
|
| Data | D0 |
|
||||||
|
| GND | GND |
|
||||||
|
|
||||||
|
|
||||||
|
Based on clock sketch by Gilchrist 6/2/2014 1.0
|
||||||
|
|
||||||
|
A few colour codes:
|
||||||
|
|
||||||
|
code color
|
||||||
|
0x0000 Black
|
||||||
|
0xFFFF White
|
||||||
|
0xBDF7 Light Gray
|
||||||
|
0x7BEF Dark Gray
|
||||||
|
0xF800 Red
|
||||||
|
0xFFE0 Yellow
|
||||||
|
0xFBE0 Orange
|
||||||
|
0x79E0 Brown
|
||||||
|
0x7E0 Green
|
||||||
|
0x7FF Cyan
|
||||||
|
0x1F Blue
|
||||||
|
0xF81F Pink
|
||||||
|
|
||||||
|
*/
|
||||||
|
#include <DHTesp.h>
|
||||||
|
|
||||||
|
#include "passwords.h" // Define WIFI_PASS and WIFI_SSID here
|
||||||
|
|
||||||
|
#define DHT11_PIN D0
|
||||||
|
|
||||||
|
DHTesp dht;
|
||||||
|
|
||||||
|
const int INTERVAL_DHT = 30;
|
||||||
|
|
||||||
|
#include <TFT_eSPI.h> // Hardware-specific library https://github.com/Bodmer/TFT_eSPI
|
||||||
|
#include <SPI.h>
|
||||||
|
|
||||||
|
#include <ESP8266WiFi.h>
|
||||||
|
#include <ESP8266WiFiMulti.h>
|
||||||
|
#include <WiFiUdp.h>
|
||||||
|
|
||||||
|
#include <Timezone.h> // https://github.com/JChristensen/Timezone
|
||||||
|
|
||||||
|
|
||||||
|
// Time variables
|
||||||
|
|
||||||
|
// Central European Time (Frankfurt, Paris)
|
||||||
|
TimeChangeRule CEST = {"CEST", Last, Sun, Mar, 2, 120}; // Central European Summer Time
|
||||||
|
TimeChangeRule CET = {"CET ", Last, Sun, Oct, 3, 60}; // Central European Standard Time
|
||||||
|
Timezone CE(CEST, CET);
|
||||||
|
|
||||||
|
TimeChangeRule *tcr;
|
||||||
|
|
||||||
|
|
||||||
|
// Wifi variables
|
||||||
|
|
||||||
|
bool connectionWasAlive = false;
|
||||||
|
|
||||||
|
ESP8266WiFiMulti wifiMulti; // Create an instance of the ESP8266WiFiMulti class, called 'wifiMulti'
|
||||||
|
|
||||||
|
WiFiUDP UDP; // Create an instance of the WiFiUDP class to send and receive
|
||||||
|
|
||||||
|
IPAddress timeServerIP; // time.nist.gov NTP server address
|
||||||
|
const char* NTPServerName = "hora.roa.es";
|
||||||
|
|
||||||
|
const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
|
||||||
|
|
||||||
|
byte NTPBuffer[NTP_PACKET_SIZE]; // buffer to hold incoming and outgoing packets
|
||||||
|
|
||||||
|
|
||||||
|
unsigned long intervalNTP = 60000; // Request NTP time every minute
|
||||||
|
unsigned long prevNTP = 0;
|
||||||
|
unsigned long lastNTPResponse = millis();
|
||||||
|
uint32_t timeUNIX = 0;
|
||||||
|
|
||||||
|
|
||||||
|
// TFT variables
|
||||||
|
|
||||||
|
#define TFT_GREY 0x5AEB
|
||||||
|
#define TFT_DARK_GREY 0x7BEF
|
||||||
|
|
||||||
|
TFT_eSPI tft = TFT_eSPI(); // Invoke custom library
|
||||||
|
|
||||||
|
#define FONT_SIZE 7
|
||||||
|
|
||||||
|
// Clock variables
|
||||||
|
|
||||||
|
uint8_t hh = 0, mm = 0, ss = 0;
|
||||||
|
|
||||||
|
byte omm = 99, oss = 99;
|
||||||
|
byte xcolon = 0, xsecs = 0;
|
||||||
|
unsigned int colour = 0;
|
||||||
|
|
||||||
|
uint32_t targetTime = 0; // for next 1 second timeout
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Other variables
|
||||||
|
|
||||||
|
int counter = 0;
|
||||||
|
|
||||||
|
void updateTime() {
|
||||||
|
unsigned long currentMillis = millis();
|
||||||
|
|
||||||
|
if (currentMillis - prevNTP > intervalNTP) { // If a minute has passed since last NTP request
|
||||||
|
prevNTP = currentMillis;
|
||||||
|
Serial.println("\r\nSending NTP request ...");
|
||||||
|
sendNTPpacket(timeServerIP); // Send an NTP request
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t time = getTime(); // Check if an NTP response has arrived and get the (UNIX) time
|
||||||
|
if (time) { // If a new timestamp has been received
|
||||||
|
timeUNIX = time;
|
||||||
|
Serial.print("NTP response:\t");
|
||||||
|
Serial.println(timeUNIX);
|
||||||
|
lastNTPResponse = currentMillis;
|
||||||
|
} else if ((currentMillis - lastNTPResponse) > 3600000) {
|
||||||
|
Serial.println("More than 1 hour since last NTP response. Rebooting.");
|
||||||
|
Serial.flush();
|
||||||
|
ESP.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
time_t t = CE.toLocal(now(), &tcr);
|
||||||
|
|
||||||
|
mm = minute(t);
|
||||||
|
ss = second(t);
|
||||||
|
hh = hour(t);
|
||||||
|
|
||||||
|
if ( ss != oss ) { // If a second has passed since last print
|
||||||
|
Serial.printf("\rLocal time:\t%d:%d:%d ", hh, omm, oss);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void drawTime(){
|
||||||
|
int xpos = 20;
|
||||||
|
int ypos = 65; // Top left corner ot clock text, about half way down
|
||||||
|
int ysecs = ypos + 24;
|
||||||
|
|
||||||
|
if (omm != mm) { // Redraw hours and minutes time every minute
|
||||||
|
omm = mm;
|
||||||
|
// Draw hours and minutes
|
||||||
|
if (hh < 10) xpos += tft.drawChar('0', xpos, ypos, FONT_SIZE); // Add hours leading zero for 24 hr clock
|
||||||
|
xpos += tft.drawNumber(hh, xpos, ypos, FONT_SIZE); // Draw hours
|
||||||
|
xcolon = xpos; // Save colon coord for later to flash on/off later
|
||||||
|
xpos += tft.drawChar(':', xpos, ypos - 8, FONT_SIZE);
|
||||||
|
if (mm < 10) xpos += tft.drawChar('0', xpos, ypos, FONT_SIZE); // Add minutes leading zero
|
||||||
|
xpos += tft.drawNumber(mm, xpos, ypos, FONT_SIZE); // Draw minutes
|
||||||
|
xsecs = xpos; // Sae seconds 'x' position for later display updates
|
||||||
|
}
|
||||||
|
if (oss != ss) { // Redraw seconds time every second
|
||||||
|
oss = ss;
|
||||||
|
xpos = xsecs;
|
||||||
|
|
||||||
|
if (ss % 2) { // Flash the colons on/off
|
||||||
|
tft.setTextColor(0x39C4, TFT_BLACK); // Set colour to grey to dim colon
|
||||||
|
tft.drawChar(':', xcolon, ypos - 8, FONT_SIZE); // Hour:minute colon
|
||||||
|
tft.setTextColor(TFT_YELLOW, TFT_BLACK); // Set colour back to yellow
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tft.drawChar(':', xcolon, ypos - FONT_SIZE, FONT_SIZE); // Hour:minute colon
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t getTime() {
|
||||||
|
if (UDP.parsePacket() == 0) { // If there's no response (yet)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
UDP.read(NTPBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
|
||||||
|
// Combine the 4 timestamp bytes into one 32-bit number
|
||||||
|
uint32_t NTPTime = (NTPBuffer[40] << 24) | (NTPBuffer[41] << 16) | (NTPBuffer[42] << 8) | NTPBuffer[43];
|
||||||
|
// Convert NTP time to a UNIX timestamp:
|
||||||
|
// Unix time starts on Jan 1 1970. That's 2208988800 seconds in NTP time:
|
||||||
|
const uint32_t seventyYears = 2208988800UL;
|
||||||
|
// subtract seventy years:
|
||||||
|
uint32_t UNIXTime = NTPTime - seventyYears;
|
||||||
|
setTime(UNIXTime);
|
||||||
|
return UNIXTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendNTPpacket(IPAddress& address) {
|
||||||
|
memset(NTPBuffer, 0, NTP_PACKET_SIZE); // set all bytes in the buffer to 0
|
||||||
|
// Initialize values needed to form NTP request
|
||||||
|
NTPBuffer[0] = 0b11100011; // LI, Version, Mode
|
||||||
|
// send a packet requesting a timestamp:
|
||||||
|
UDP.beginPacket(address, 123); // NTP requests are to port 123
|
||||||
|
UDP.write(NTPBuffer, NTP_PACKET_SIZE);
|
||||||
|
UDP.endPacket();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int getSeconds(uint32_t UNIXTime) {
|
||||||
|
return UNIXTime % 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int getMinutes(uint32_t UNIXTime) {
|
||||||
|
return UNIXTime / 60 % 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int getHours(uint32_t UNIXTime) {
|
||||||
|
return UNIXTime / 3600 % 24;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void monitorWiFi() {
|
||||||
|
if (wifiMulti.run() != WL_CONNECTED)
|
||||||
|
{
|
||||||
|
if (connectionWasAlive)
|
||||||
|
{
|
||||||
|
connectionWasAlive = false;
|
||||||
|
Serial.print("Looking for WiFi ");
|
||||||
|
}
|
||||||
|
Serial.print(".");
|
||||||
|
}
|
||||||
|
else if (connectionWasAlive == false)
|
||||||
|
{
|
||||||
|
connectionWasAlive = true;
|
||||||
|
Serial.print("Connected to ");
|
||||||
|
Serial.println(WiFi.SSID()); // Tell us what network we're connected to
|
||||||
|
Serial.print("IP address:\t");
|
||||||
|
Serial.print(WiFi.localIP()); // Send the IP address of the ESP8266 to the computer
|
||||||
|
Serial.println("\r\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void startWiFi() { // Try to connect to some given access points. Then wait for a connection
|
||||||
|
wifiMulti.addAP(WIFI_SSID, WIFI_PASS); // add Wi-Fi networks you want to connect to
|
||||||
|
|
||||||
|
while (wifiMulti.run() != WL_CONNECTED) { // Wait for the Wi-Fi to connect
|
||||||
|
delay(250);
|
||||||
|
monitorWiFi();
|
||||||
|
}
|
||||||
|
Serial.println("\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void startUDP() {
|
||||||
|
Serial.println("Starting UDP");
|
||||||
|
UDP.begin(123); // Start listening for UDP messages on port 123
|
||||||
|
Serial.print("Local port:\t");
|
||||||
|
Serial.println(UDP.localPort());
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void printTemperature()
|
||||||
|
{
|
||||||
|
|
||||||
|
float humidity = dht.getHumidity();
|
||||||
|
float temperature = dht.getTemperature();
|
||||||
|
|
||||||
|
Serial.print(dht.getStatusString());
|
||||||
|
Serial.print("\t");
|
||||||
|
Serial.print(humidity, 1);
|
||||||
|
Serial.print("\t\t");
|
||||||
|
Serial.print(temperature, 1);
|
||||||
|
Serial.print("\t\t");
|
||||||
|
Serial.print(dht.computeHeatIndex(temperature, humidity, false), 1);
|
||||||
|
Serial.print("\t\t");
|
||||||
|
Serial.println(dht.computeHeatIndex(dht.toFahrenheit(temperature), humidity, true), 1);
|
||||||
|
|
||||||
|
int space = 16;
|
||||||
|
int pos = 24;
|
||||||
|
int font = 4;
|
||||||
|
int posy = 180;
|
||||||
|
tft.setTextSize(1);
|
||||||
|
tft.setTextColor(TFT_DARK_GREY, TFT_BLACK);
|
||||||
|
|
||||||
|
pos += tft.drawString("T: ", pos, posy+20, font);
|
||||||
|
|
||||||
|
pos += tft.drawNumber(temperature, pos+space, posy, 7) + 2*space;
|
||||||
|
|
||||||
|
pos += tft.drawString("C", pos, posy, font) + space;
|
||||||
|
|
||||||
|
pos += tft.drawString("H: ", pos, posy+20, font);
|
||||||
|
|
||||||
|
pos += tft.drawNumber(humidity, pos + space, posy, 7);
|
||||||
|
pos += tft.drawChar('%', pos + space, posy, font);
|
||||||
|
tft.setTextColor(TFT_YELLOW, TFT_BLACK);
|
||||||
|
tft.setTextSize(2);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void setup(void) {
|
||||||
|
dht.setup(DHT11_PIN, DHTesp::DHT11); // Connect DHT sensor to GPIO 17
|
||||||
|
|
||||||
|
tft.init();
|
||||||
|
tft.setRotation(1);
|
||||||
|
tft.fillScreen(TFT_BLACK);
|
||||||
|
|
||||||
|
tft.setTextSize(2);
|
||||||
|
tft.setTextColor(TFT_YELLOW, TFT_BLACK);
|
||||||
|
|
||||||
|
targetTime = millis() + 1000;
|
||||||
|
|
||||||
|
Serial.begin(115200); // Start the Serial communication to send messages to the computer
|
||||||
|
delay(10);
|
||||||
|
Serial.println("\r\n");
|
||||||
|
|
||||||
|
startWiFi(); // Try to connect to some given access points. Then wait for a connection
|
||||||
|
|
||||||
|
startUDP();
|
||||||
|
|
||||||
|
if(!WiFi.hostByName(NTPServerName, timeServerIP)) { // Get the IP address of the NTP server
|
||||||
|
Serial.println("DNS lookup failed. Rebooting.");
|
||||||
|
Serial.flush();
|
||||||
|
ESP.reset();
|
||||||
|
}
|
||||||
|
Serial.print("Time server IP:\t");
|
||||||
|
Serial.println(timeServerIP);
|
||||||
|
|
||||||
|
Serial.println("\r\nSending NTP request ...");
|
||||||
|
sendNTPpacket(timeServerIP);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
|
||||||
|
if (targetTime < millis()) {
|
||||||
|
targetTime = millis() + 1000;
|
||||||
|
|
||||||
|
monitorWiFi();
|
||||||
|
|
||||||
|
if ( (counter % INTERVAL_DHT) == 0){
|
||||||
|
counter = 0;
|
||||||
|
printTemperature();
|
||||||
|
}
|
||||||
|
counter = counter+1;
|
||||||
|
|
||||||
|
updateTime();
|
||||||
|
|
||||||
|
|
||||||
|
// Update digital time
|
||||||
|
drawTime();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user