From 84040d76c6e76651c51ff84639368c1e0c3fdd23 Mon Sep 17 00:00:00 2001 From: hidaba Date: Sat, 22 Apr 2023 16:23:30 +0200 Subject: [PATCH] change ntp library --- PylontechMonitoring.ino | 77 +++--- libraries/NTPClient/CHANGELOG | 15 ++ libraries/NTPClient/NTPClient.cpp | 212 +++++++++++++++ libraries/NTPClient/NTPClient.h | 114 ++++++++ libraries/NTPClient/README.md | 52 ++++ .../NTPClient/examples/Advanced/Advanced.ino | 37 +++ libraries/NTPClient/examples/Basic/Basic.ino | 33 +++ .../examples/IsTimeSet/IsTimeSet.ino | 53 ++++ libraries/NTPClient/keywords.txt | 24 ++ libraries/NTPClient/library.properties | 9 + libraries/NtpTime/ntp_time.h | 81 ------ libraries/SimpleTimer/README | 2 - libraries/SimpleTimer/SimpleTimer.cpp | 250 ------------------ libraries/SimpleTimer/SimpleTimer.h | 126 --------- 14 files changed, 589 insertions(+), 496 deletions(-) create mode 100644 libraries/NTPClient/CHANGELOG create mode 100644 libraries/NTPClient/NTPClient.cpp create mode 100644 libraries/NTPClient/NTPClient.h create mode 100644 libraries/NTPClient/README.md create mode 100644 libraries/NTPClient/examples/Advanced/Advanced.ino create mode 100644 libraries/NTPClient/examples/Basic/Basic.ino create mode 100644 libraries/NTPClient/examples/IsTimeSet/IsTimeSet.ino create mode 100644 libraries/NTPClient/keywords.txt create mode 100644 libraries/NTPClient/library.properties delete mode 100644 libraries/NtpTime/ntp_time.h delete mode 100644 libraries/SimpleTimer/README delete mode 100644 libraries/SimpleTimer/SimpleTimer.cpp delete mode 100644 libraries/SimpleTimer/SimpleTimer.h diff --git a/PylontechMonitoring.ino b/PylontechMonitoring.ino index 48f086e..933175f 100644 --- a/PylontechMonitoring.ino +++ b/PylontechMonitoring.ino @@ -2,15 +2,14 @@ #include #include #include -#include -#include //https://github.com/PaulStoffregen/Time -#include #include +#include +#include //IMPORTANT: Specify your WIFI settings: -#define WIFI_SSID "--YOUR SSID HERE --" -#define WIFI_PASS "-- YOUR PASSWORD HERE --" +#define WIFI_SSID "---SID HERE!---" +#define WIFI_PASS "---PASSWORD!---" //IMPORTANT: Uncomment this line if you want to enable MQTT (and fill correct MQTT_ values below): //#define ENABLE_MQTT @@ -20,9 +19,9 @@ //NOTE 2: MQTT_TOPIC_ROOT is where battery will push MQTT topics. For example "soc" will be pushed to: "home/grid_battery/soc" #define MQTT_SERVER "192.168.1.2" #define MQTT_PORT 1883 -#define MQTT_USER "" -#define MQTT_PASSWORD "" -#define MQTT_TOPIC_ROOT "home/grid_battery/" //this is where mqtt data will be pushed +#define MQTT_USER "---username---" +#define MQTT_PASSWORD "---password---" +#define MQTT_TOPIC_ROOT "homeassistant/sensor/grid_battery/" //this is where mqtt data will be pushed #define MQTT_PUSH_FREQ_SEC 2 //maximum mqtt update frequency in seconds #include @@ -30,10 +29,18 @@ WiFiClient espClient; PubSubClient mqttClient(espClient); #endif //ENABLE_MQTT +//risposta in testo char g_szRecvBuff[7000]; + +const long utcOffsetInSeconds = 3600; +char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; +// Define NTP Client to get time +WiFiUDP ntpUDP; +NTPClient timeClient(ntpUDP, "pool.ntp.org", utcOffsetInSeconds); + + ESP8266WebServer server(80); -SimpleTimer timer; circular_log<7000> g_log; bool ntpTimeReceived = false; int g_baudRate = 0; @@ -43,7 +50,11 @@ void Log(const char* msg) g_log.Log(msg); } + void setup() { + + memset(g_szRecvBuff, 0, sizeof(g_szRecvBuff)); //clean variable + pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, HIGH);//high is off @@ -75,7 +86,7 @@ void setup() { server.begin(); - syncTime(); + timeClient.begin(); #ifdef ENABLE_MQTT mqttClient.setServer(MQTT_SERVER, MQTT_PORT); @@ -230,6 +241,8 @@ void handleReq() handleRoot(); } + + void handleJsonOut() { if(sendCommandAndReadSerialResponse("pwr") == false) @@ -246,29 +259,35 @@ void handleJsonOut() void handleRoot() { unsigned long days = 0, hours = 0, minutes = 0; unsigned long val = os_getCurrentTimeSec(); - days = val / (3600*24); val -= days * (3600*24); - hours = val / 3600; val -= hours * 3600; - minutes = val / 60; val -= minutes*60; - - static char szTmp[2500] = ""; - snprintf(szTmp, sizeof(szTmp)-1, "Garage Battery
Time GMT: %d/%02d/%02d %02d:%02d:%02d (%s)
Uptime: %02d:%02d:%02d.%02d

free heap: %u
Wifi RSSI: %d
Wifi SSID: %s", - year(), month(), day(), hour(), minute(), second(), "GMT", + + + timeClient.update(); + time_t epochTime = timeClient.getEpochTime(); + String formattedTime = timeClient.getFormattedTime(); + //Get a time structure + struct tm *ptm = gmtime ((time_t *)&epochTime); + int currentMonth = ptm->tm_mon+1; + + static char szTmp[9500] = ""; + + snprintf(szTmp, sizeof(szTmp)-1, "Pylontech Battery
Time GMT: %s (%s)
Uptime: %02d:%02d:%02d.%02d

free heap: %u
Wifi RSSI: %d
Wifi SSID: %s", + formattedTime, "GMT", (int)days, (int)hours, (int)minutes, (int)val, ESP.getFreeHeap(), WiFi.RSSI(), WiFi.SSID().c_str()); - strncat(szTmp, "
Runtime log
", sizeof(szTmp)-1); strncat(szTmp, "
Command:Power | Help | Event Log | Time
", sizeof(szTmp)-1); strncat(szTmp, "
", sizeof(szTmp)-1); strncat(szTmp, "", sizeof(szTmp)-1); - + strncat(szTmp, "", sizeof(szTmp)-1); + strncat(szTmp, "", sizeof(szTmp)-1); + server.send(200, "text/html", szTmp); } @@ -290,21 +309,6 @@ unsigned long os_getCurrentTimeSec() return (wrapCnt*4294967) + seconds; } -void syncTime() -{ - //get time from NTP - time_t currentTimeGMT = getNtpTime(); - if(currentTimeGMT) - { - ntpTimeReceived = true; - setTime(currentTimeGMT); - } - else - { - timer.setTimeout(5000, syncTime); //try again in 5 seconds - } -} - void wakeUpConsole() { switchBaud(1200); @@ -645,7 +649,6 @@ void loop() { ArduinoOTA.handle(); server.handleClient(); - timer.run(); //if there are bytes availbe on serial here - it's unexpected //when we send a command to battery, we read whole response @@ -718,7 +721,7 @@ void mqttLoop() //first: let's make sure we are connected to mqtt const char* topicLastWill = MQTT_TOPIC_ROOT "availability"; if (!mqttClient.connected() && (g_lastConnectionAttempt == 0 || os_getCurrentTimeSec() - g_lastConnectionAttempt > 60)) { - if(mqttClient.connect("GarageBattery", MQTT_USER, MQTT_PASSWORD, topicLastWill, 1, true, "offline")) + if(mqttClient.connect("PylontechBattery", MQTT_USER, MQTT_PASSWORD, topicLastWill, 1, true, "offline")) { Log("Connected to MQTT server: " MQTT_SERVER); mqttClient.publish(topicLastWill, "online", true); diff --git a/libraries/NTPClient/CHANGELOG b/libraries/NTPClient/CHANGELOG new file mode 100644 index 0000000..6a082d5 --- /dev/null +++ b/libraries/NTPClient/CHANGELOG @@ -0,0 +1,15 @@ +NTPClient 3.1.0 - 2016.05.31 + +* Added functions for changing the timeOffset and updateInterval later. Thanks @SirUli + +NTPClient 3.0.0 - 2016.04.19 + +* Constructors now require UDP instance argument, to add support for non-ESP8266 boards +* Added optional begin API to override default local port +* Added end API to close UDP socket +* Changed return type of update and forceUpdate APIs to bool, and return success or failure +* Change return type of getDay, getHours, getMinutes, and getSeconds to int + +Older + +* Changes not recorded diff --git a/libraries/NTPClient/NTPClient.cpp b/libraries/NTPClient/NTPClient.cpp new file mode 100644 index 0000000..b435855 --- /dev/null +++ b/libraries/NTPClient/NTPClient.cpp @@ -0,0 +1,212 @@ +/** + * The MIT License (MIT) + * Copyright (c) 2015 by Fabrice Weinberg + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "NTPClient.h" + +NTPClient::NTPClient(UDP& udp) { + this->_udp = &udp; +} + +NTPClient::NTPClient(UDP& udp, long timeOffset) { + this->_udp = &udp; + this->_timeOffset = timeOffset; +} + +NTPClient::NTPClient(UDP& udp, const char* poolServerName) { + this->_udp = &udp; + this->_poolServerName = poolServerName; +} + +NTPClient::NTPClient(UDP& udp, IPAddress poolServerIP) { + this->_udp = &udp; + this->_poolServerIP = poolServerIP; + this->_poolServerName = NULL; +} + +NTPClient::NTPClient(UDP& udp, const char* poolServerName, long timeOffset) { + this->_udp = &udp; + this->_timeOffset = timeOffset; + this->_poolServerName = poolServerName; +} + +NTPClient::NTPClient(UDP& udp, IPAddress poolServerIP, long timeOffset){ + this->_udp = &udp; + this->_timeOffset = timeOffset; + this->_poolServerIP = poolServerIP; + this->_poolServerName = NULL; +} + +NTPClient::NTPClient(UDP& udp, const char* poolServerName, long timeOffset, unsigned long updateInterval) { + this->_udp = &udp; + this->_timeOffset = timeOffset; + this->_poolServerName = poolServerName; + this->_updateInterval = updateInterval; +} + +NTPClient::NTPClient(UDP& udp, IPAddress poolServerIP, long timeOffset, unsigned long updateInterval) { + this->_udp = &udp; + this->_timeOffset = timeOffset; + this->_poolServerIP = poolServerIP; + this->_poolServerName = NULL; + this->_updateInterval = updateInterval; +} + +void NTPClient::begin() { + this->begin(NTP_DEFAULT_LOCAL_PORT); +} + +void NTPClient::begin(unsigned int port) { + this->_port = port; + + this->_udp->begin(this->_port); + + this->_udpSetup = true; +} + +bool NTPClient::forceUpdate() { + #ifdef DEBUG_NTPClient + Serial.println("Update from NTP Server"); + #endif + + // flush any existing packets + while(this->_udp->parsePacket() != 0) + this->_udp->flush(); + + this->sendNTPPacket(); + + // Wait till data is there or timeout... + byte timeout = 0; + int cb = 0; + do { + delay ( 10 ); + cb = this->_udp->parsePacket(); + if (timeout > 100) return false; // timeout after 1000 ms + timeout++; + } while (cb == 0); + + this->_lastUpdate = millis() - (10 * (timeout + 1)); // Account for delay in reading the time + + this->_udp->read(this->_packetBuffer, NTP_PACKET_SIZE); + + unsigned long highWord = word(this->_packetBuffer[40], this->_packetBuffer[41]); + unsigned long lowWord = word(this->_packetBuffer[42], this->_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; + + this->_currentEpoc = secsSince1900 - SEVENZYYEARS; + + return true; // return true after successful update +} + +bool NTPClient::update() { + if ((millis() - this->_lastUpdate >= this->_updateInterval) // Update after _updateInterval + || this->_lastUpdate == 0) { // Update if there was no update yet. + if (!this->_udpSetup || this->_port != NTP_DEFAULT_LOCAL_PORT) this->begin(this->_port); // setup the UDP client if needed + return this->forceUpdate(); + } + return false; // return false if update does not occur +} + +bool NTPClient::isTimeSet() const { + return (this->_lastUpdate != 0); // returns true if the time has been set, else false +} + +unsigned long NTPClient::getEpochTime() const { + return this->_timeOffset + // User offset + this->_currentEpoc + // Epoch returned by the NTP server + ((millis() - this->_lastUpdate) / 1000); // Time since last update +} + +int NTPClient::getDay() const { + return (((this->getEpochTime() / 86400L) + 4 ) % 7); //0 is Sunday +} +int NTPClient::getHours() const { + return ((this->getEpochTime() % 86400L) / 3600); +} +int NTPClient::getMinutes() const { + return ((this->getEpochTime() % 3600) / 60); +} +int NTPClient::getSeconds() const { + return (this->getEpochTime() % 60); +} + +String NTPClient::getFormattedTime() const { + unsigned long rawTime = this->getEpochTime(); + unsigned long hours = (rawTime % 86400L) / 3600; + String hoursStr = hours < 10 ? "0" + String(hours) : String(hours); + + unsigned long minutes = (rawTime % 3600) / 60; + String minuteStr = minutes < 10 ? "0" + String(minutes) : String(minutes); + + unsigned long seconds = rawTime % 60; + String secondStr = seconds < 10 ? "0" + String(seconds) : String(seconds); + + return hoursStr + ":" + minuteStr + ":" + secondStr; +} + +void NTPClient::end() { + this->_udp->stop(); + + this->_udpSetup = false; +} + +void NTPClient::setTimeOffset(int timeOffset) { + this->_timeOffset = timeOffset; +} + +void NTPClient::setUpdateInterval(unsigned long updateInterval) { + this->_updateInterval = updateInterval; +} + +void NTPClient::setPoolServerName(const char* poolServerName) { + this->_poolServerName = poolServerName; +} + +void NTPClient::sendNTPPacket() { + // set all bytes in the buffer to 0 + memset(this->_packetBuffer, 0, NTP_PACKET_SIZE); + // Initialize values needed to form NTP request + this->_packetBuffer[0] = 0b11100011; // LI, Version, Mode + this->_packetBuffer[1] = 0; // Stratum, or type of clock + this->_packetBuffer[2] = 6; // Polling Interval + this->_packetBuffer[3] = 0xEC; // Peer Clock Precision + // 8 bytes of zero for Root Delay & Root Dispersion + this->_packetBuffer[12] = 49; + this->_packetBuffer[13] = 0x4E; + this->_packetBuffer[14] = 49; + this->_packetBuffer[15] = 52; + + // all NTP fields have been given values, now + // you can send a packet requesting a timestamp: + if (this->_poolServerName) { + this->_udp->beginPacket(this->_poolServerName, 123); + } else { + this->_udp->beginPacket(this->_poolServerIP, 123); + } + this->_udp->write(this->_packetBuffer, NTP_PACKET_SIZE); + this->_udp->endPacket(); +} + +void NTPClient::setRandomPort(unsigned int minValue, unsigned int maxValue) { + randomSeed(analogRead(0)); + this->_port = random(minValue, maxValue); +} diff --git a/libraries/NTPClient/NTPClient.h b/libraries/NTPClient/NTPClient.h new file mode 100644 index 0000000..a31d32f --- /dev/null +++ b/libraries/NTPClient/NTPClient.h @@ -0,0 +1,114 @@ +#pragma once + +#include "Arduino.h" + +#include + +#define SEVENZYYEARS 2208988800UL +#define NTP_PACKET_SIZE 48 +#define NTP_DEFAULT_LOCAL_PORT 1337 + +class NTPClient { + private: + UDP* _udp; + bool _udpSetup = false; + + const char* _poolServerName = "pool.ntp.org"; // Default time server + IPAddress _poolServerIP; + unsigned int _port = NTP_DEFAULT_LOCAL_PORT; + long _timeOffset = 0; + + unsigned long _updateInterval = 60000; // In ms + + unsigned long _currentEpoc = 0; // In s + unsigned long _lastUpdate = 0; // In ms + + byte _packetBuffer[NTP_PACKET_SIZE]; + + void sendNTPPacket(); + + public: + NTPClient(UDP& udp); + NTPClient(UDP& udp, long timeOffset); + NTPClient(UDP& udp, const char* poolServerName); + NTPClient(UDP& udp, const char* poolServerName, long timeOffset); + NTPClient(UDP& udp, const char* poolServerName, long timeOffset, unsigned long updateInterval); + NTPClient(UDP& udp, IPAddress poolServerIP); + NTPClient(UDP& udp, IPAddress poolServerIP, long timeOffset); + NTPClient(UDP& udp, IPAddress poolServerIP, long timeOffset, unsigned long updateInterval); + + /** + * Set time server name + * + * @param poolServerName + */ + void setPoolServerName(const char* poolServerName); + + /** + * Set random local port + */ + void setRandomPort(unsigned int minValue = 49152, unsigned int maxValue = 65535); + + /** + * Starts the underlying UDP client with the default local port + */ + void begin(); + + /** + * Starts the underlying UDP client with the specified local port + */ + void begin(unsigned int port); + + /** + * This should be called in the main loop of your application. By default an update from the NTP Server is only + * made every 60 seconds. This can be configured in the NTPClient constructor. + * + * @return true on success, false on failure + */ + bool update(); + + /** + * This will force the update from the NTP Server. + * + * @return true on success, false on failure + */ + bool forceUpdate(); + + /** + * This allows to check if the NTPClient successfully received a NTP packet and set the time. + * + * @return true if time has been set, else false + */ + bool isTimeSet() const; + + int getDay() const; + int getHours() const; + int getMinutes() const; + int getSeconds() const; + + /** + * Changes the time offset. Useful for changing timezones dynamically + */ + void setTimeOffset(int timeOffset); + + /** + * Set the update interval to another frequency. E.g. useful when the + * timeOffset should not be set in the constructor + */ + void setUpdateInterval(unsigned long updateInterval); + + /** + * @return time formatted like `hh:mm:ss` + */ + String getFormattedTime() const; + + /** + * @return time in seconds since Jan. 1, 1970 + */ + unsigned long getEpochTime() const; + + /** + * Stops the underlying UDP client + */ + void end(); +}; diff --git a/libraries/NTPClient/README.md b/libraries/NTPClient/README.md new file mode 100644 index 0000000..f83882c --- /dev/null +++ b/libraries/NTPClient/README.md @@ -0,0 +1,52 @@ +# NTPClient + +[![Check Arduino status](https://github.com/arduino-libraries/NTPClient/actions/workflows/check-arduino.yml/badge.svg)](https://github.com/arduino-libraries/NTPClient/actions/workflows/check-arduino.yml) +[![Compile Examples status](https://github.com/arduino-libraries/NTPClient/actions/workflows/compile-examples.yml/badge.svg)](https://github.com/arduino-libraries/NTPClient/actions/workflows/compile-examples.yml) +[![Spell Check status](https://github.com/arduino-libraries/NTPClient/actions/workflows/spell-check.yml/badge.svg)](https://github.com/arduino-libraries/NTPClient/actions/workflows/spell-check.yml) + +Connect to a NTP server, here is how: + +```cpp +#include +// change next line to use with another board/shield +#include +//#include // for WiFi shield +//#include // for WiFi 101 shield or MKR1000 +#include + +const char *ssid = ""; +const char *password = ""; + +WiFiUDP ntpUDP; + +// By default 'pool.ntp.org' is used with 60 seconds update interval and +// no offset +NTPClient timeClient(ntpUDP); + +// You can specify the time server pool and the offset, (in seconds) +// additionally you can specify the update interval (in milliseconds). +// NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 3600, 60000); + +void setup(){ + Serial.begin(115200); + WiFi.begin(ssid, password); + + while ( WiFi.status() != WL_CONNECTED ) { + delay ( 500 ); + Serial.print ( "." ); + } + + timeClient.begin(); +} + +void loop() { + timeClient.update(); + + Serial.println(timeClient.getFormattedTime()); + + delay(1000); +} +``` + +## Function documentation +`getEpochTime` returns the Unix epoch, which are the seconds elapsed since 00:00:00 UTC on 1 January 1970 (leap seconds are ignored, every day is treated as having 86400 seconds). **Attention**: If you have set a time offset this time offset will be added to your epoch timestamp. diff --git a/libraries/NTPClient/examples/Advanced/Advanced.ino b/libraries/NTPClient/examples/Advanced/Advanced.ino new file mode 100644 index 0000000..18a6a97 --- /dev/null +++ b/libraries/NTPClient/examples/Advanced/Advanced.ino @@ -0,0 +1,37 @@ +#include +// change next line to use with another board/shield +#include +//#include // for WiFi shield +//#include // for WiFi 101 shield or MKR1000 +#include + +const char *ssid = ""; +const char *password = ""; + +WiFiUDP ntpUDP; + +// You can specify the time server pool and the offset (in seconds, can be +// changed later with setTimeOffset() ). Additionally you can specify the +// update interval (in milliseconds, can be changed using setUpdateInterval() ). +NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 3600, 60000); + +void setup(){ + Serial.begin(115200); + + WiFi.begin(ssid, password); + + while ( WiFi.status() != WL_CONNECTED ) { + delay ( 500 ); + Serial.print ( "." ); + } + + timeClient.begin(); +} + +void loop() { + timeClient.update(); + + Serial.println(timeClient.getFormattedTime()); + + delay(1000); +} diff --git a/libraries/NTPClient/examples/Basic/Basic.ino b/libraries/NTPClient/examples/Basic/Basic.ino new file mode 100644 index 0000000..f0a2a7c --- /dev/null +++ b/libraries/NTPClient/examples/Basic/Basic.ino @@ -0,0 +1,33 @@ +#include +// change next line to use with another board/shield +#include +//#include // for WiFi shield +//#include // for WiFi 101 shield or MKR1000 +#include + +const char *ssid = ""; +const char *password = ""; + +WiFiUDP ntpUDP; +NTPClient timeClient(ntpUDP); + +void setup(){ + Serial.begin(115200); + + WiFi.begin(ssid, password); + + while ( WiFi.status() != WL_CONNECTED ) { + delay ( 500 ); + Serial.print ( "." ); + } + + timeClient.begin(); +} + +void loop() { + timeClient.update(); + + Serial.println(timeClient.getFormattedTime()); + + delay(1000); +} diff --git a/libraries/NTPClient/examples/IsTimeSet/IsTimeSet.ino b/libraries/NTPClient/examples/IsTimeSet/IsTimeSet.ino new file mode 100644 index 0000000..619bfde --- /dev/null +++ b/libraries/NTPClient/examples/IsTimeSet/IsTimeSet.ino @@ -0,0 +1,53 @@ +#include +// change next line to use with another board/shield +#include +//#include // for WiFi shield +//#include // for WiFi 101 shield or MKR1000 +#include + +const char *ssid = ""; +const char *password = ""; + +WiFiUDP ntpUDP; +// initialized to a time offset of 10 hours +NTPClient timeClient(ntpUDP,"pool.ntp.org", 36000, 60000); +// HH:MM:SS +// timeClient initializes to 10:00:00 if it does not receive an NTP packet +// before the 100ms timeout. +// without isTimeSet() the LED would be switched on, although the time +// was not yet set correctly. + +// blue LED on ESP-12F +const int led = 2; +const int hour = 10; +const int minute = 0; + +void setup(){ + Serial.begin(115200); + + pinMode(led, OUTPUT); + // led is off when pin is high + digitalWrite(led, 1); + + WiFi.begin(ssid, password); + + while (WiFi.status() != WL_CONNECTED) { + delay (500); + Serial.print ("."); + } + + timeClient.begin(); +} + +void loop() { + timeClient.update(); + + Serial.println(timeClient.getFormattedTime()); + if(timeClient.isTimeSet()) { + if (hour == timeClient.getHours() && minute == timeClient.getMinutes()) { + digitalWrite(led, 0); + } + } + + delay(1000); +} diff --git a/libraries/NTPClient/keywords.txt b/libraries/NTPClient/keywords.txt new file mode 100644 index 0000000..4df40a7 --- /dev/null +++ b/libraries/NTPClient/keywords.txt @@ -0,0 +1,24 @@ +####################################### +# Datatypes (KEYWORD1) +####################################### + +NTPClient KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +begin KEYWORD2 +end KEYWORD2 +update KEYWORD2 +forceUpdate KEYWORD2 +isTimeSet KEYWORD2 +getDay KEYWORD2 +getHours KEYWORD2 +getMinutes KEYWORD2 +getSeconds KEYWORD2 +getFormattedTime KEYWORD2 +getEpochTime KEYWORD2 +setTimeOffset KEYWORD2 +setUpdateInterval KEYWORD2 +setPoolServerName KEYWORD2 diff --git a/libraries/NTPClient/library.properties b/libraries/NTPClient/library.properties new file mode 100644 index 0000000..abdd80d --- /dev/null +++ b/libraries/NTPClient/library.properties @@ -0,0 +1,9 @@ +name=NTPClient +version=3.2.1 +author=Fabrice Weinberg +maintainer=Fabrice Weinberg +sentence=An NTPClient to connect to a time server +paragraph=Get time from a NTP server and keep it in sync. +category=Timing +url=https://github.com/arduino-libraries/NTPClient +architectures=* diff --git a/libraries/NtpTime/ntp_time.h b/libraries/NtpTime/ntp_time.h deleted file mode 100644 index 5d01fed..0000000 --- a/libraries/NtpTime/ntp_time.h +++ /dev/null @@ -1,81 +0,0 @@ -#ifndef ntp_time_h -#define ntp_time_h - -#include - -// NTP Servers: -static const char ntpServerName[] = "0.uk.pool.ntp.org"; -const int timeZone = 0; -unsigned int localPort = 8888; // local port to listen for UDP packets - -/*-------- NTP code ----------*/ - -const int NTP_PACKET_SIZE = 48; // NTP time is in the first 48 bytes of message -byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming & outgoing packets -WiFiUDP udpNtp; - -// send an NTP request to the time server at the given address -void sendNTPpacket(IPAddress &address) -{ - // 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: - udpNtp.beginPacket(address, 123); //NTP requests are to port 123 - udpNtp.write(packetBuffer, NTP_PACKET_SIZE); - udpNtp.endPacket(); -} - - -time_t getNtpTime() -{ - if(WiFi.status() != WL_CONNECTED) - { - return 0; - } - - static bool udpStarted = false; - if(udpStarted == false) - { - udpStarted = true; - udpNtp.begin(localPort); - } - - IPAddress ntpServerIP; // NTP server's ip address - - while (udpNtp.parsePacket() > 0) ; // discard any previously received packets - // get a random server from the pool - WiFi.hostByName(ntpServerName, ntpServerIP); - sendNTPpacket(ntpServerIP); - delay(100); - - uint32_t beginWait = millis(); - while (millis() - beginWait < 1500) { - int size = udpNtp.parsePacket(); - if (size >= NTP_PACKET_SIZE) { - udpNtp.read(packetBuffer, NTP_PACKET_SIZE); // read packet into the buffer - unsigned long secsSince1900; - // convert four bytes starting at location 40 to a long integer - secsSince1900 = (unsigned long)packetBuffer[40] << 24; - secsSince1900 |= (unsigned long)packetBuffer[41] << 16; - secsSince1900 |= (unsigned long)packetBuffer[42] << 8; - secsSince1900 |= (unsigned long)packetBuffer[43]; - return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR; - } - - delay(10); - } - return 0; // return 0 if unable to get the time -} -#endif //ntp_time_h \ No newline at end of file diff --git a/libraries/SimpleTimer/README b/libraries/SimpleTimer/README deleted file mode 100644 index c224b02..0000000 --- a/libraries/SimpleTimer/README +++ /dev/null @@ -1,2 +0,0 @@ -Visit this page for more information: -http://playground.arduino.cc/Code/SimpleTimer \ No newline at end of file diff --git a/libraries/SimpleTimer/SimpleTimer.cpp b/libraries/SimpleTimer/SimpleTimer.cpp deleted file mode 100644 index 274606c..0000000 --- a/libraries/SimpleTimer/SimpleTimer.cpp +++ /dev/null @@ -1,250 +0,0 @@ -/* - * SimpleTimer.cpp - * - * SimpleTimer - A timer library for Arduino. - * Author: mromani@ottotecnica.com - * Copyright (c) 2010 OTTOTECNICA Italy - * - * This library is free software; you can redistribute it - * and/or modify it under the terms of the GNU Lesser - * General Public License as published by the Free Software - * Foundation; either version 2.1 of the License, or (at - * your option) any later version. - * - * This library is distributed in the hope that it will - * be useful, but WITHOUT ANY WARRANTY; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A - * PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser - * General Public License along with this library; if not, - * write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - -#include "SimpleTimer.h" - - -// Select time function: -//static inline unsigned long elapsed() { return micros(); } -static inline unsigned long elapsed() { return millis(); } - - -SimpleTimer::SimpleTimer() - : numTimers (-1) -{ -} - -void SimpleTimer::init() { - unsigned long current_millis = elapsed(); - - for (int i = 0; i < MAX_TIMERS; i++) { - enabled[i] = false; - callbacks[i] = 0; // if the callback pointer is zero, the slot is free, i.e. doesn't "contain" any timer - prev_millis[i] = current_millis; - numRuns[i] = 0; - } - - numTimers = 0; -} - - -void SimpleTimer::run() { - int i; - unsigned long current_millis; - - // get current time - current_millis = elapsed(); - - for (i = 0; i < MAX_TIMERS; i++) { - - toBeCalled[i] = DEFCALL_DONTRUN; - - // no callback == no timer, i.e. jump over empty slots - if (callbacks[i]) { - - // is it time to process this timer ? - // see http://arduino.cc/forum/index.php/topic,124048.msg932592.html#msg932592 - - if (current_millis - prev_millis[i] >= delays[i]) { - - // update time - //prev_millis[i] = current_millis; - prev_millis[i] += delays[i]; - - // check if the timer callback has to be executed - if (enabled[i]) { - - // "run forever" timers must always be executed - if (maxNumRuns[i] == RUN_FOREVER) { - toBeCalled[i] = DEFCALL_RUNONLY; - } - // other timers get executed the specified number of times - else if (numRuns[i] < maxNumRuns[i]) { - toBeCalled[i] = DEFCALL_RUNONLY; - numRuns[i]++; - - // after the last run, delete the timer - if (numRuns[i] >= maxNumRuns[i]) { - toBeCalled[i] = DEFCALL_RUNANDDEL; - } - } - } - } - } - } - - for (i = 0; i < MAX_TIMERS; i++) { - switch(toBeCalled[i]) { - case DEFCALL_DONTRUN: - break; - - case DEFCALL_RUNONLY: - (*callbacks[i])(); - break; - - case DEFCALL_RUNANDDEL: - (*callbacks[i])(); - deleteTimer(i); - break; - } - } -} - - -// find the first available slot -// return -1 if none found -int SimpleTimer::findFirstFreeSlot() { - int i; - - // all slots are used - if (numTimers >= MAX_TIMERS) { - return -1; - } - - // return the first slot with no callback (i.e. free) - for (i = 0; i < MAX_TIMERS; i++) { - if (callbacks[i] == 0) { - return i; - } - } - - // no free slots found - return -1; -} - - -int SimpleTimer::setTimer(long d, timer_callback f, int n) { - int freeTimer; - - if (numTimers < 0) { - init(); - } - - freeTimer = findFirstFreeSlot(); - if (freeTimer < 0) { - return -1; - } - - if (f == NULL) { - return -1; - } - - delays[freeTimer] = d; - callbacks[freeTimer] = f; - maxNumRuns[freeTimer] = n; - enabled[freeTimer] = true; - prev_millis[freeTimer] = elapsed(); - - numTimers++; - - return freeTimer; -} - - -int SimpleTimer::setInterval(long d, timer_callback f) { - return setTimer(d, f, RUN_FOREVER); -} - - -int SimpleTimer::setTimeout(long d, timer_callback f) { - return setTimer(d, f, RUN_ONCE); -} - - -void SimpleTimer::deleteTimer(int timerId) { - if (timerId >= MAX_TIMERS) { - return; - } - - // nothing to delete if no timers are in use - if (numTimers == 0) { - return; - } - - // don't decrease the number of timers if the - // specified slot is already empty - if (callbacks[timerId] != NULL) { - callbacks[timerId] = 0; - enabled[timerId] = false; - toBeCalled[timerId] = DEFCALL_DONTRUN; - delays[timerId] = 0; - numRuns[timerId] = 0; - - // update number of timers - numTimers--; - } -} - - -// function contributed by code@rowansimms.com -void SimpleTimer::restartTimer(int numTimer) { - if (numTimer >= MAX_TIMERS) { - return; - } - - prev_millis[numTimer] = elapsed(); -} - - -boolean SimpleTimer::isEnabled(int numTimer) { - if (numTimer >= MAX_TIMERS) { - return false; - } - - return enabled[numTimer]; -} - - -void SimpleTimer::enable(int numTimer) { - if (numTimer >= MAX_TIMERS) { - return; - } - - enabled[numTimer] = true; -} - - -void SimpleTimer::disable(int numTimer) { - if (numTimer >= MAX_TIMERS) { - return; - } - - enabled[numTimer] = false; -} - - -void SimpleTimer::toggle(int numTimer) { - if (numTimer >= MAX_TIMERS) { - return; - } - - enabled[numTimer] = !enabled[numTimer]; -} - - -int SimpleTimer::getNumTimers() { - return numTimers; -} diff --git a/libraries/SimpleTimer/SimpleTimer.h b/libraries/SimpleTimer/SimpleTimer.h deleted file mode 100644 index 9cdb395..0000000 --- a/libraries/SimpleTimer/SimpleTimer.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * SimpleTimer.h - * - * SimpleTimer - A timer library for Arduino. - * Author: mromani@ottotecnica.com - * Copyright (c) 2010 OTTOTECNICA Italy - * - * This library is free software; you can redistribute it - * and/or modify it under the terms of the GNU Lesser - * General Public License as published by the Free Software - * Foundation; either version 2.1 of the License, or (at - * your option) any later version. - * - * This library is distributed in the hope that it will - * be useful, but WITHOUT ANY WARRANTY; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A - * PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser - * General Public License along with this library; if not, - * write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - - -#ifndef SIMPLETIMER_H -#define SIMPLETIMER_H - -#if defined(ARDUINO) && ARDUINO >= 100 -#include -#else -#include -#endif - -typedef void (*timer_callback)(void); - -class SimpleTimer { - -public: - // maximum number of timers - const static int MAX_TIMERS = 10; - - // setTimer() constants - const static int RUN_FOREVER = 0; - const static int RUN_ONCE = 1; - - // constructor - SimpleTimer(); - - void init(); - - // this function must be called inside loop() - void run(); - - // call function f every d milliseconds - int setInterval(long d, timer_callback f); - - // call function f once after d milliseconds - int setTimeout(long d, timer_callback f); - - // call function f every d milliseconds for n times - int setTimer(long d, timer_callback f, int n); - - // destroy the specified timer - void deleteTimer(int numTimer); - - // restart the specified timer - void restartTimer(int numTimer); - - // returns true if the specified timer is enabled - boolean isEnabled(int numTimer); - - // enables the specified timer - void enable(int numTimer); - - // disables the specified timer - void disable(int numTimer); - - // enables the specified timer if it's currently disabled, - // and vice-versa - void toggle(int numTimer); - - // returns the number of used timers - int getNumTimers(); - - // returns the number of available timers - int getNumAvailableTimers() { return MAX_TIMERS - numTimers; }; - -private: - // deferred call constants - const static int DEFCALL_DONTRUN = 0; // don't call the callback function - const static int DEFCALL_RUNONLY = 1; // call the callback function but don't delete the timer - const static int DEFCALL_RUNANDDEL = 2; // call the callback function and delete the timer - - // find the first available slot - int findFirstFreeSlot(); - - // value returned by the millis() function - // in the previous run() call - unsigned long prev_millis[MAX_TIMERS]; - - // pointers to the callback functions - timer_callback callbacks[MAX_TIMERS]; - - // delay values - long delays[MAX_TIMERS]; - - // number of runs to be executed for each timer - int maxNumRuns[MAX_TIMERS]; - - // number of executed runs for each timer - int numRuns[MAX_TIMERS]; - - // which timers are enabled - boolean enabled[MAX_TIMERS]; - - // deferred function call (sort of) - N.B.: this array is only used in run() - int toBeCalled[MAX_TIMERS]; - - // actual number of timers in use - int numTimers; -}; - -#endif \ No newline at end of file