I need to read the PC time from an ESP8266.I have setup the PC as a NTP server & ESP8266 as NTP client. PC has connected to a non internet wifi router.
The problem is in below client code it starts from time 0.0.0 (Zero).Its not showing the PC time.
*Note - In this project there is no internet. I need to read the local PC time.
How to rectify it?
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <NTPClient.h>
// Replace with your network credentials
const char* ssid = "Link_Test";
const char* password = "123456";
// Replace with your PC's IP address or hostname running the NTP server
const char* ntpServerName = "192.168.1.2";
// Define NTP Client to get time
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
Serial.println("Connected to WiFi!");
// Set NTP server address
timeClient.setPoolServerName(ntpServerName);
// Initialize NTP client
timeClient.begin();
timeClient.setTimeOffset(0);
timeClient.forceUpdate();
}
void loop() {
timeClient.update();
// Print time obtained from the NTP server
Serial.println(timeClient.getFormattedTime());
delay(1000); // Wait for 1 second before updating the time again
}
You have to give the NTP-functions a little time to synchronise
/* Example Demo-Code for ESP8266 and ESP32
Showing how to
- organise code well structured into functions
- connecting to a WiFi
- synchronise time with an NTP-server
- if connecting fails how to scan and print available WiFi-networks
- how to use minuteOfDay and secondOfDay which make it easier to compare
- the actual time with a certain point of time
- a tricky way to use the serial monitor similar to a LC-Display
- non-blocking timing based on function millis() with a helper-function
- how to print a timestamp when the code was compiled
written by user StefanL38
*/
#if defined(ESP32)
#include <WiFi.h>
char deviceType[] = "ESP32";
#else
#include <ESP8266WiFi.h>
char deviceType[] = "ESP8266";
#endif
unsigned long MyTestTimer = 0; // variables MUST be of type unsigned long
const byte OnBoard_LED = 2;
int connectCounter = 0;
int NoOfWiFis;
long minuteOfDay;
long secondOfDay;
//const char *ssid = "your SSID";
//const char *password = "your password";
const char dayOfWeek[][16] = {"sunday",
"monday",
"tuesday",
"wednesday",
"thursday",
"friday",
"saturday"
};
// a lot of home-wlan-routers can be used as a NTP-server too
const char* ntpServer = "fritz.box";
const long gmtOffset_sec = 0;
const int daylightOffset_sec = 7200;
#include <time.h> // time() ctime()
time_t now; // this is the epoch
tm myTimeInfo; // the structure tm holds time information in a more convient way
int Year;
int Month;
int Day;
int Hour;
int Minute;
int Second;
int DayIndex;
void updateMyTimeVars() {
Year = myTimeInfo.tm_year + 1900; // years since 1900
Month = myTimeInfo.tm_mon + 1; // January = 0 (!)
Day = myTimeInfo.tm_mday;
Hour = myTimeInfo.tm_hour;
Minute = myTimeInfo.tm_min;
Second = myTimeInfo.tm_sec;
DayIndex = myTimeInfo.tm_wday;
}
void clearSerialMonitor() {
for (int i = 0; i < 50; i++) {
Serial.println(); // print 50 empty lines
}
}
void showTime() {
time(&now); // read the current time
localtime_r(&now, &myTimeInfo); // update the structure tm with the current time
updateMyTimeVars();
Serial.print("year:");
Serial.print(Year);
Serial.print(" month:");
if (Month < 10) {
Serial.print("0");
}
Serial.print(Month);
Serial.print(" day:");
if (Day < 10) {
Serial.print("0");
}
Serial.print(Day); // day of month
Serial.print(" hour:");
if (Hour < 10) {
Serial.print("0");
}
Serial.print(Hour); // hours since midnight 0-23
Serial.print(" min:");
if (Minute < 10) {
Serial.print("0");
}
Serial.print(Minute); // minutes after the hour 0-59
Serial.print(" sec:");
if (Second < 10) {
Serial.print("0");
}
Serial.print(Second); // seconds after the minute 0-61*
Serial.print(" DayIndex:");
Serial.print(DayIndex); // days since Sunday 0-6
Serial.print(" name of day ");
Serial.print(dayOfWeek[DayIndex]);
minuteOfDay = Hour * 60 + Minute;
secondOfDay = Hour * 3600 + Minute * 60 + Second;
Serial.println();
Serial.println();
Serial.print("minuteOfDay ");
Serial.print(minuteOfDay);
Serial.print(" secondOfDay ");
Serial.print(secondOfDay);
// 12 hours 4 minutes 59 seconds = 12:04:59
if (secondOfDay < (12 * 3600 + 4 * 60 + 59) ) {
Serial.println(" actual time is before 12:04:59");
}
else {
Serial.println(" actual time is AFTER 12:04:59");
}
Serial.println();
Serial.println();
}
void connectToWifi() {
Serial.print("try connecting to ");
Serial.println(ssid);
WiFi.persistent(false);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
yield(); // very important to have this function call to enable backround-processes
BlinkHeartBeatLED(OnBoard_LED, 333);
if ( TimePeriodIsOver(MyTestTimer, 500) ) {
Serial.print(".");
connectCounter++;
if (connectCounter % 20 == 0) {
Serial.println();
}
}
if (connectCounter > 120) {
break;
}
}
if (WiFi.status() == WL_CONNECTED) {
Serial.print("\n connected.");
Serial.println(WiFi.localIP() );
}
else {
Serial.print("\n unable to connect to WiFi with name #");
Serial.print(ssid);
Serial.println("#");
ScanWiFis();
Serial.print("\n code stopped with while(true) yield() ");
while (true) {
yield();
}
}
}
void ScanWiFis() {
int WiFiIdx;
Serial.println("Startscanning for networks");
NoOfWiFis = WiFi.scanNetworks();
Serial.println("scanning done List of SSIDs");
Serial.print("found number of networks ");
Serial.println(NoOfWiFis);
for (WiFiIdx = 0; WiFiIdx < NoOfWiFis; WiFiIdx++) {
// Print SSID and RSSI for each network found
Serial.print(WiFiIdx);
Serial.print(" #");
Serial.print( String( WiFi.SSID(WiFiIdx) ) );
Serial.print("# RSSI ");
Serial.print( String (WiFi.RSSI(WiFiIdx)) );
Serial.print(" dB");
Serial.println();
}
}
void synchroniseWith_NTP_Time() {
Serial.print("configTime uses ntpServer ");
Serial.println(ntpServer);
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
Serial.print("synchronising time");
while (myTimeInfo.tm_year + 1900 < 2000 ) {
time(&now); // read the current time
localtime_r(&now, &myTimeInfo);
BlinkHeartBeatLED(OnBoard_LED, 100);
delay(100);
Serial.print(".");
}
Serial.print("\n time synchronsized \n");
showTime();
}
void PrintFileNameDateTime() {
Serial.println( F("Code running comes from file ") );
Serial.println(__FILE__);
Serial.print( F(" compiled ") );
Serial.print(__DATE__);
Serial.print( F(" ") );
Serial.println(__TIME__);
}
boolean TimePeriodIsOver (unsigned long & periodStartTime, unsigned long TimePeriod) {
unsigned long currentMillis = millis();
if ( currentMillis - periodStartTime >= TimePeriod )
{
periodStartTime = currentMillis; // set new expireTime
return true; // more time than TimePeriod) has elapsed since last time if-condition was true
}
else return false; // not expired
}
void BlinkHeartBeatLED(int IO_Pin, int BlinkPeriod) {
static unsigned long MyBlinkTimer;
pinMode(IO_Pin, OUTPUT);
if ( TimePeriodIsOver(MyBlinkTimer, BlinkPeriod) ) {
digitalWrite(IO_Pin, !digitalRead(IO_Pin) );
}
}
void setup() {
Serial.begin(115200);
delay(2000);
Serial.println("\n Setup-Start \n");
PrintFileNameDateTime();
connectToWifi();
synchroniseWith_NTP_Time();
}
void loop() {
BlinkHeartBeatLED(OnBoard_LED, 100);
if ( TimePeriodIsOver(MyTestTimer, 1000) ) {
clearSerialMonitor();
showTime();
}
}
as already shown - you should not use external libraries for NTP on an ESP8266 as the NTP functionality is already part of the ESP Core.
For usual the first NTP request will happen within 60 seconds using the core functions. But there is also a function sntp_startup_delay_MS_rfc_not_less_than_60000 that can be used to reduce that
I have another question. If there is two or three NTP servers on a PC, will that code read time from standard Microsoft time server? I mean if all three time servers runs together how the ESP decide from which one to get..!!