From 9c9fb4f6e7b03cff5e654d27455f12a5ac857956 Mon Sep 17 00:00:00 2001 From: n0m1s Date: Sat, 11 Jan 2020 23:40:18 +0100 Subject: [PATCH] NTP & RTC clock handling --- clock.cpp | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ clock.h | 34 +++++++++++++++++++++ lamp.ino | 9 ++++-- 3 files changed, 130 insertions(+), 2 deletions(-) create mode 100644 clock.cpp create mode 100644 clock.h diff --git a/clock.cpp b/clock.cpp new file mode 100644 index 0000000..f80536e --- /dev/null +++ b/clock.cpp @@ -0,0 +1,89 @@ +#include "clock.h" + +#include +#include + +Clock::Clock(ClockSettings const& settings): + m_settings(settings), + m_last_NTP_check(0), + m_NTP_waiting_for_response(false), + m_UDP(), + m_NTP_ip() +{ + setSyncProvider(RTC.get); + m_UDP.begin(NTP_PORT); +} + +void Clock::internet_update() +{ + ntp_update(); +} + +void Clock::ntp_update() +{ + bool need_to_ask = false; + if(timeStatus() != timeSet) + need_to_ask = !m_NTP_waiting_for_response; + else if(m_NTP_waiting_for_response) + { + //5 minutes timeout for the NTP response + if((now() - m_last_NTP_check) > 5*60) + m_NTP_waiting_for_response = false; + } + else + need_to_ask = (now() - m_last_NTP_check) > m_settings.cooldown(); + + if(need_to_ask) ntp_ask(); + ntp_checkResponse(); +} + +void Clock::ntp_ask() +{ + if(!WiFi.hostByName(m_settings.server(), m_NTP_ip)) + { + Serial.print("DNS lookup for \""); + Serial.print(m_settings.server()); + Serial.println("\" failed"); + return; + } + + Serial.print("time server IP: \""); + Serial.print(m_NTP_ip); + Serial.println("\""); + + Serial.println("Sending NTP request..."); + //creating the NTP packet + memset(m_NTP_buffer, 0, NTP_BUFFER_SIZE); + m_NTP_buffer[0] = 0b11100011; //LI, version, mode + m_UDP.beginPacket(m_NTP_ip, NTP_PORT); + m_UDP.write(m_NTP_buffer, NTP_BUFFER_SIZE); + m_UDP.endPacket(); + + m_last_NTP_check = now(); + m_NTP_waiting_for_response = true; +} + +void Clock::ntp_checkResponse() +{ + //no packet available + if(m_UDP.parsePacket() == 0) + return; + + m_NTP_waiting_for_response = false; + + m_UDP.read(m_NTP_buffer, NTP_BUFFER_SIZE); + + time_t NTP_time = (m_NTP_buffer[40] << 24) | + (m_NTP_buffer[41] << 16) | + (m_NTP_buffer[42] << 8) | + (m_NTP_buffer[43]); + + time_t UNIX_time = NTP_time - 2208988800UL; + + m_last_NTP_check = UNIX_time; + RTC.set(UNIX_time); + setTime(UNIX_time); + + Serial.print("Time: "); + Serial.println(UNIX_time); +} diff --git a/clock.h b/clock.h new file mode 100644 index 0000000..e4a08aa --- /dev/null +++ b/clock.h @@ -0,0 +1,34 @@ +#ifndef CLOCK_H +#define CLOCK_H + +#include + +#include "clock_settings.h" + +unsigned int const NTP_BUFFER_SIZE = 48; +unsigned int const NTP_PORT = 123; + +class Clock +{ + public: + Clock(ClockSettings const& settings); + + void internet_update(); + + protected: + void ntp_update(); + void ntp_ask(); + void ntp_checkResponse(); + + protected: + ClockSettings const& m_settings; + + time_t m_last_NTP_check; + bool m_NTP_waiting_for_response; + + WiFiUDP m_UDP; + IPAddress m_NTP_ip; + uint8_t m_NTP_buffer[NTP_BUFFER_SIZE]; +}; + +#endif //CLOCK_H diff --git a/lamp.ino b/lamp.ino index 1ca6994..ae5d21b 100644 --- a/lamp.ino +++ b/lamp.ino @@ -1,8 +1,10 @@ #include "settings.h" #include "wifi.h" +#include "clock.h" Settings const* settings = nullptr; -Wifi * wifi = nullptr; +Wifi * wifi = nullptr; +Clock * clk = nullptr; bool ok = true; @@ -21,11 +23,14 @@ void setup() { else Serial.println(" OK"); - wifi = new Wifi(settings->wifi); + wifi = new Wifi(settings->wifi); + clk = new Clock(settings->clock); } void loop() { if(!ok) {delay(3600000); return;} wifi->keep_alive_connection(); + if(wifi->is_connected()) + clk->internet_update(); }