Reputation: 1820
I have an ESP8266 that connects to WiFi and then calls an NTP server to get the time. Originally, I had set up the WiFi connection to work off a "config.h" file with SSID and password - the vanilla approach. Later, I set up a WiFi Manager with the AsyncWebServer library to avoid hardcoding credentials as shown in this tutorial by Rui Santos .
Now the user enters WiFi credentials on a web-page hosted by the ESP8266 which provides a Wireless Access Point. These credentials are stashed away in files on the local file-system (LittleFS) and accessed when making the WiFi connection from that point onwards. Upon connecting, the ESP8266 runs a web-server that hosts a static web-page.
This works fine and the ESP8266 connects to WiFi BUT the NTP service no longer works! I get a fixed time ~ 12:00 midnight from the NTP client. When I revert to connecting to WiFi the vanilla way, the NTP service works as expected.
Here is my code for making the WiFi connection in station mode. The class GuruWebServer
has methods initializeaLittle()
, readaLittle()
and writeaLittle()
for file-system operations. The key method, initializeWiFi()
, returns true
when connection is successfully made with the credentials stashed away in the file-system and returns false
otherwise. The method has a loop with millis()
in which the attempt to connect to WiFi is made until timeout (e.g. 60s).
I observe that the SSID and password are correctly recorded and WiFi connection is successfully made. Subsequently, using LanScan (on Mac), I can see the ESP8266 at the station IP address as configured. Using a browser, I can load the web-page it serves. However, I am no longer able to get the time-and-date from calling the NTP service.
bool GuruWebServer::initializeWiFi() {
/*
* Make WiFi connection when SSID and PWD are available
* and set up station for web-service.
*/
// Initialize LittleFS
this->initializeaLittle();
// Connect to WiFi
this->readaLittle(&SSID, Path2_SSID);
this->readaLittle(&PWD, Path2_PWD);
this->readaLittle(&IP, Path2_IP);
this->readaLittle(&Gateway, Path2_Gateway);
String conn_ack = (String)"SSID <" + SSID + "> | PWD <" + PWD + "> | IP <" + IP + "> | Gateway <" + Gateway + ">";
if (SSID == "" || PWD == "") { // Files not populated!
Serial.println("Found NO SSID or PWD!");
return false;
}
WiFi.mode(WIFI_STA);
localIP.fromString(IP.c_str());
localGateway.fromString(Gateway.c_str());
if (!WiFi.config(localIP, localGateway, subnet)) {
Serial.println("Configured NO station!");
return false;
}
WiFi.begin(SSID, PWD);
unsigned long _now = millis();
unsigned long _then = _now; // Marker for ticker
unsigned long _stop = _now; // Marker for timeout
unsigned long delta_minor = 0; // Time since last tick
unsigned long delta_major = 0; // Time since start
while (WiFi.status() != WL_CONNECTED) {
_now = millis();
delta_minor = _now - _then; // Time since last tick
delta_major = _now - _stop; // Time since start
if (delta_minor > 1000) { // Mark time and reset delta
_then = _now;
Serial.print (".");
}
if (delta_major > 60000) { // Stop attempting connection
String timely = (String)"Now " + _now + " Stop " + _stop + " Diff " + delta_major;
Serial.println(timely);
Serial.println("Made NO WiFi connection!");
return false; // Exit false
} // end IF
} // end WHILE WiFi
Serial.println(WiFi.localIP());
return true;
}
To get time, I have used NTPClient library in the main program as follows:
#include <NTPClient.h>
#include <WiFiUdp.h>
WiFiUDP NTP_UDP;
NTPClient timeClient(NTP_UDP, "us.pool.ntp.org");
and in the setup()
function of "main.cpp", I have:
// Connect to the NTP client
delay(500);
timeClient.begin();
timeClient.setTimeOffset(-18000); // Central time GMT-5 ~ -5 x 3600
timeClient.update();
Serial.println(timeClient.getFormattedTime());
The github branch rev007 has the code with WiFi Manager and rev006 has the vanilla WiFi.
I have tried the following:
configTime()
function.AsyncWebServer server(80);
.Grateful for any help figuring this out, thank you.
UPDATE
I have simplified the code to illustrate the problem. This single script sets up the ESP8266 as WiFi station. The device connects to WiFi successfully but is unsuccessful calling the NTP service.
#include <Arduino.h>
#include <time.h>
#include "LittleFS.h"
#include <ESP8266WiFi.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
WiFiUDP NTP_UDP;
NTPClient timeClient(NTP_UDP, "pool.ntp.org");
// Alt.
#include "config.h"
IPAddress localIP;
IPAddress localGateway;
IPAddress subnet(255, 255, 255, 0);
void setup() {
Serial.begin(9600);
WiFi.mode(WIFI_STA);
// Comment out from here --->
localIP.fromString(IP);
localGateway.fromString(Gateway);
if (!WiFi.config(localIP, localGateway, subnet)) {
Serial.println("Configured NO station!");
}
// <--- upto here!
WiFi.begin(SSID, PWD);
unsigned long _now = millis();
unsigned long _then = _now; // Marker for ticker
unsigned long _stop = _now; // Marker for timeout
unsigned long delta_minor = 0; // Time since last tick
unsigned long delta_major = 0; // Time since start
while (WiFi.status() != WL_CONNECTED) {
_now = millis();
delta_minor = _now - _then; // Time since last tick
delta_major = _now - _stop; // Time since start
if (delta_minor > 1000) { // Mark time and reset delta
_then = _now;
Serial.print (".");
}
if (delta_major > 60000) { // Stop attempting connection
String timely = (String)"Now " + _now + " Stop " + _stop + " Diff " + delta_major;
Serial.println(timely);
Serial.println("Made NO WiFi connection!");
} // end IF
} // end WHILE WiFi
Serial.println(WiFi.localIP());
// Connect to the NTP client
delay(3000);
timeClient.begin();
timeClient.setTimeOffset(-18000); // Central time GMT-5 ~ -5 x 3600
delay(3000);
timeClient.update();
Serial.println(timeClient.getFormattedTime());
}
void loop() {
// put your main code here, to run repeatedly:
}
When I comment out the code as shown so as not to configure the IP address from settings but let it be determined at run-time, then all is well.
Upvotes: 1
Views: 1182
Reputation: 11
If you want using WiFiManager just leave wifiManager.setSTAStaticIPConfig
and use this after wifiManager.autoConnect
WiFi.begin();
WiFi.config(IPAddress(192, 168, 1, 148), IPAddress(192, 168, 1, 1), IPAddress(192, 168, 1, 1), IPAddress(255, 255, 255, 0));
It working for me on ESP8266.
Upvotes: 1
Reputation: 4034
I'm curious enough to try your code. The issue is without the proper DNS setup, the NTP(UDP) won't be able to resolve the NTP name "pool.ntp.org", I tested your code with slightly modification and simplification. Without specifying the DNS with WiFi.config(localIP, localGateway, subnet)
, the timeClient.update()
simply can't establish a NTP connection, by adding a DNS IP to WiFi.config(localIP, localGateway, subnet, dns)
, the following code works like a charm.
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
WiFiUDP NTP_UDP;
NTPClient timeClient(NTP_UDP, "pool.ntp.org");
#include "config.h"
IPAddress localIP(192, 168, 0, 120); // my local ip
IPAddress localGateway(192, 168, 0, 1); // my local gateway
IPAddress subnet(255, 255, 255, 0);
IPAddress dns(1, 1, 1, 1); // CloudFlare DNS server
void setup() {
Serial.begin(9600);
while (!Serial);
WiFi.mode(WIFI_STA);
WiFi.begin(SSID, PWD);
WiFi.config(localIP, localGateway, subnet, dns);
int count = 0;
while (WiFi.status() != WL_CONNECTED) {
delay(500);
if (count++ > 20) ESP.restart(); //timeout, reboot
}
Serial.println(WiFi.localIP());
// Connect to the NTP client
timeClient.begin();
timeClient.setTimeOffset(8*3600); //my timezone
if (timeClient.update())
Serial.println(timeClient.getFormattedTime());
}
void loop() {
}
Upvotes: 2