@scimmia24 , your topic has been moved to a more suitable location on the forum. Installation and Troubleshooting is not for problems with (nor for advise on) your project
See About the Installation & Troubleshooting category.
Below a short demo code (adjust to your needs); would this also spam the NTP server?
/*
Based on NTP example and OLED example
History
0.1 initial version
0.2 remove delay and use millis() to update between NTP requests
added statemachine for NTP requests
0.3 add serial print of MAC
*/
#define DEBUG
#ifdef DEBUG
#define DEBUG_PRINTLN(x) Serial.println(x)
#define DEBUG_PRINT(x) Serial.print(x)
#else
#define DEBUG_PRINTLN(x)
#define DEBUG_PRINT(x)
#endif
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <TimeLib.h>
const int timeOffset = 7200;
uint32_t ntpTime;
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// SCL GPIO5
// SDA GPIO4
#define OLED_RESET 0 // GPIO0
Adafruit_SSD1306 display(OLED_RESET);
#ifndef STASSID
#include "credentials.h"
#endif
#include "constants.h"
const char * ssid = STASSID; // your network SSID (name)
const char * pass = STAPSK; // your network password
unsigned int localPort = 2390; // local port to listen for UDP packets
/* Don't hardwire the IP address or we won't get the benefits of the pool.
Lookup the IP address for the host name instead */
//IPAddress timeServer(129, 6, 15, 28); // time.nist.gov NTP server
IPAddress timeServerIP; // time.nist.gov NTP server address
const char* ntpServerName = "time.nist.gov";
const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets
// A UDP instance to let us send and receive packets over UDP
WiFiUDP udp;
void setup()
{
// setup serial
Serial.begin(57600);
// this seems to be needed befor printing
delay(500);
DEBUG_PRINTLN();
DEBUG_PRINTLN();
DEBUG_PRINT("MAC: ");
DEBUG_PRINTLN(WiFi.macAddress());
// by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3C (for the 64x48)
// init done
// get rid of logo
display.clearDisplay();
display.display();
display.setTextColor(WHITE, BLACK); // this disables transparent mode; we can now overwrite existing text instead of clearing the display; see https://forum.arduino.cc/index.php?topic=383909.0
display.setTextSize(1);
display.setCursor(0, 0);
display.print("Connecting");
display.display();
// We start by connecting to a WiFi network
DEBUG_PRINT("Connecting to ");
DEBUG_PRINTLN(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
DEBUG_PRINT(".");
}
DEBUG_PRINTLN();
display.clearDisplay();
display.setCursor(0, 0);
display.print("Connected");
display.display();
DEBUG_PRINTLN("WiFi connected");
DEBUG_PRINT("IP address: ");
DEBUG_PRINTLN(WiFi.localIP());
DEBUG_PRINTLN("Starting UDP");
udp.begin(localPort);
DEBUG_PRINT("Local port: ");
DEBUG_PRINTLN(udp.localPort());
}
void loop()
{
//get a random server from the pool
WiFi.hostByName(ntpServerName, timeServerIP);
getTime();
printTime();
}
enum NTPSTATES
{
REQUEST,
PROCESS,
};
/*
get the time, either from NTP or by using a millis() based approach
*/
void getTime()
{
// keep track when we want to do a NTP request
static uint32_t nextNtpRefresh;
// timeout start time for reply on request
static uint32_t timeoutTimer;
// state machine state
static NTPSTATES ntpState;
int cb;
switch (ntpState)
{
case REQUEST:
if (millis() >= nextNtpRefresh)
{
nextNtpRefresh += ntpRefreshInterval;
DEBUG_PRINTLN(millis());
sendNTPpacket(timeServerIP); // send an NTP packet to a time server
timeoutTimer = millis();
ntpState = PROCESS;
}
updateNtpTime();
break;
case PROCESS:
cb = udp.parsePacket();
if (!cb)
{
//DEBUG_PRINTLN("no packet yet");
updateNtpTime();
if (millis() - timeoutTimer > ntpRequestTimeout)
{
ntpState = REQUEST;
}
}
else
{
DEBUG_PRINTLN(millis());
DEBUG_PRINT("packet received, length=");
DEBUG_PRINTLN(cb);
processNtpPacket();
ntpState = REQUEST;
}
break;
}
}
/*
send an NTP request to the time server at the given address
*/
void sendNTPpacket(IPAddress& address)
{
DEBUG_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();
}
/*
update ntpTime if we don't do not send a request or or are wauting for a reply
*/
void updateNtpTime()
{
static uint32_t nextUpdateTime;
if (millis() >= nextUpdateTime)
{
nextUpdateTime += 1000;
ntpTime += 1;
}
}
/*
process a received UDP packet
*/
void processNtpPacket()
{
/*
TODO: make sure that this is a reply to the NTP request
*/
// 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;
DEBUG_PRINT("Seconds since Jan 1 1900 = ");
DEBUG_PRINTLN(secsSince1900);
// now convert NTP time into everyday time:
DEBUG_PRINT("Unix time = ");
// Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
const unsigned long seventyYears = 2208988800UL;
// subtract seventy years and compensate for timezone
unsigned long epoch = secsSince1900 - seventyYears + timeOffset;
// print Unix time:
DEBUG_PRINTLN(epoch);
ntpTime = epoch;
}
void printTime()
{
static int prevMinute;
if (prevMinute != minute(ntpTime))
{
prevMinute = minute(ntpTime);
DEBUG_PRINT("Year = "); DEBUG_PRINTLN(year(ntpTime));
DEBUG_PRINT("Month = "); DEBUG_PRINTLN(month(ntpTime));
DEBUG_PRINT("Day = "); DEBUG_PRINTLN(day(ntpTime));
DEBUG_PRINT("Hour = "); DEBUG_PRINTLN(hour(ntpTime));
DEBUG_PRINT("Min = "); DEBUG_PRINTLN(minute(ntpTime));
DEBUG_PRINT("Sec = "); DEBUG_PRINTLN(second(ntpTime));
display.setTextSize(2);
//display.clearDisplay();
char buffer[10];
sprintf(buffer, "%02d/%02d", month(ntpTime), day(ntpTime));
display.setCursor(0, 0);
display.print(buffer);
display.display();
sprintf(buffer, "%02d:%02d", hour(ntpTime), minute(ntpTime));
display.setCursor(0, 20);
display.print(buffer);
display.display();
}
}