So i was trying to make a screen display the data that it got from the DH11 and the current time in my country, so i installed the TimeLib library to get the time from a server so i connected it to my mobile data hotspot. But if the internet connection was not avalabile the code in the loop() function won't run, so i made a piece of code that lets the board try to connect to the network only 20 times than run the code without internet, but when i tried it out and i noticed that an adittional delay was added , the delay wasn't in the code tho. That delay is a big problem because i have to update the screen fast . And when i turn off the hotspot on my phone the delay is not noticeable at first, but after 2-3 seconds i can notice that the delay becomes bigger and bigger and bigger, even stopping the code from running..
#include <Wire.h>
#include "SSD1306Wire.h"
#include <SimpleDHT.h>
#include <TimeLib.h>
#include <WiFiUdp.h>
#include <ESP8266WiFi.h>
#include <NTPClient.h>
// Define the digital pin used to connect the module
const int dht_pin = D4;
const int button_pin = D3; // Define the digital pin for the button
SimpleDHT11 dht11;
// Initialize the OLED display using Wire library
SSD1306Wire display(0x3c, SDA, SCL);
// Variables to store temperature and humidity
byte temperature = 0;
byte humidity = 0;
// Variable to track the current page
int currentPage = 1;
// WiFi settings
const char *ssid = "hotspot-ssid";
const char *password = "hotspot-password";
// NTP settings
const char *ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 2 * 3600; // 2 hours offset for Bucharest
const int daylightOffset_sec = 3600; // 1 hour offset for daylight saving time
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, ntpServer, gmtOffset_sec);
void setup() {
// Start the Serial communication at 115200 bits/s
Serial.begin(115200);
// Connect to Wi-Fi
initWiFi();
timeClient.begin();
display.init();
display.setContrast(255);
display.display();
pinMode(button_pin, INPUT_PULLUP); // Set the button pin as INPUT_PULLUP
}
void loop() {
display.clear();
// Read the values
dht11.read(dht_pin, &temperature, &humidity, NULL);
// Display the values in Serial Monitor
Serial.print("Temperature: ");
Serial.print(temperature);
Serial.println(" *C");
Serial.print("Humidity: ");
Serial.print(humidity);
Serial.println(" H");
Serial.println();
// Check if the button is pressed
if (digitalRead(button_pin) == LOW) {
// Toggle between pages
currentPage = (currentPage == 1) ? 2 : 1;
delay(20); // Add a small delay to avoid button debounce
}
// Display content based on the current page
if (currentPage == 1) {
display.setFont(ArialMT_Plain_24);
display.drawString(0, 0, "Temp: " + String(temperature) + " *C");
display.drawString(0, 30, "Hum: " + String(humidity) + " H");
} else if (currentPage == 2) {
// Display clock for the second page
display.setFont(ArialMT_Plain_24);
if (WiFi.status() == WL_CONNECTED){
display.drawString(15, 13, timeClient.getFormattedTime());
}
if (WiFi.status() != WL_CONNECTED)
display.drawString(20, 13, "No WiFi");
}
display.display();
delay(150); // Delay to control the refresh rate
timeClient.update(); // Update the NTP time
}
void initWiFi() {
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi...");
int maxAttempts = 20;
int connectionAttempts = 0;
while (WiFi.status() != WL_CONNECTED && connectionAttempts < maxAttempts) {
Serial.print('.');
delay(250);
connectionAttempts++;
if (WiFi.waitForConnectResult() == WL_CONNECTED) {
Serial.println("\nConnected to WiFi. IP address: " + WiFi.localIP().toString());
return; // Exit the function when connected
}
}
Serial.println("\nWi-Fi connection failed. Proceeding without Wi-Fi.");
}
There is a significant delay introduced in the above. The function waitForConnectionResult() has a prototype of:
int8_t waitForConnectResult(unsigned long timeoutLength = 60000);
..at least on the ESP8266. It seems the ESP32 version has been amended to match. The function has a default timeout value of 60000 milliseconds, or 60 seconds. Unless a different value is specified, that's how long it will wait for the WiFi status to reach WL_CONNECTED, which, if the Internet is not connected, it will never arrive at. Your loop has 20 retries, so 20 x 60 seconds, or 20 minutes. Add to that the delay of 250 milliseconds x 20. The initWiFi function is called in setup(), so this delay will occur at startup.
If the Internet i stopped during the execution of void loop(), I am not sure how that behaves. The connection will, of course, be dropped and the display should show "No WiFi". But what happens when the Internet is reconnected I am not sure. Does it reconnect automatically, or does the WiFi client need to be reset after a time in order to properly reconnect? Perhaps someone more knowledgeable than myself has the answer?
BTW, I second the above comment about millis(). It is usually a better way to handle timing of things than delay(). Delay() blocks further program execution until the delay is complete, a problem that can be avoided by using millis().
Here is a video that simply explains how millis() can be used to do different things with different timing intervals without blocking execution of other code:
That's the old depreciated way. Get rid of those time libraries and all the time code. NTP with daylightsavings is now built into the ESP core. Read this page.
Adding a RTC will get you time when internet NTP is not available. See this page.
Try this test sketch. Add your WiFi credentials and change the location string to your country.
The lookup link is in the sketch.
This sketch waits until a valid time string is received
Leo..
#include <ESP8266WiFi.h>
#include <coredecls.h>
unsigned long prevTime;
bool ntp;
time_t now;
tm tm;
void time_is_set() { // valid time string received
Serial.println(F("time was updated"));
ntp = true;
}
void setup() {
Serial.begin(74880); // native baud rate
Serial.println(F("\nESP8266 NTP clock"));
// https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv
configTime("EET-2EEST,M3.5.0/3,M10.5.0/4", "ro.pool.ntp.org"); // location, local pool
settimeofday_cb(time_is_set);
WiFi.mode(WIFI_STA);
WiFi.begin("MY_SSID", "MY_PW"); // WiFi credentials
while (WiFi.status() != WL_CONNECTED) delay(200);
while (!ntp); // wait here until a valid time string is received
}
void loop() {
time(&now); // epoch
localtime_r(&now, &tm); // local
if (now != prevTime) { // only if time has changed
prevTime = now; // update
printf("%02u:%02u:%02u\n", tm.tm_hour, tm.tm_min, tm.tm_sec);
}
}