Skip to content

Instantly share code, notes, and snippets.

@sandip4n
Created October 22, 2020 11:07
Show Gist options
  • Save sandip4n/af8eb616b2d131d6ae5786ceeb9b6b03 to your computer and use it in GitHub Desktop.
Save sandip4n/af8eb616b2d131d6ae5786ceeb9b6b03 to your computer and use it in GitHub Desktop.
#undef __DEBUG__
/*
* Connections
* NodeMCU D1 --> I2C LCD SCL
* NodeMCU D2 --> I2C LCD SDA
* NodeMCU VIN --> I2C LCD VCC
* NodeMCU GND --> I2C LCD GND
*
* P.S. This assumes that the NodeMCU board is powered
* from the USB port. That provides a relatively fixed
* 5V power input and can be fed directly to the LCD
* display.
*/
/* Configurable parameters */
#define WIFI_SSID "my-ssid"
#define WIFI_PASS "my-pass"
#include <ezTime.h>
#include <ArduinoJson.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <LiquidCrystal_I2C.h>
#define WIFI_CONN_RETRIES 25
#define WIFI_CONN_INTERVAL 250 /* milliseconds */
#define HTTP_GET_TIMEOUT 10000 /* milliseconds */
#define NTP_SYNC_TIMEOUT 2 /* seconds */
Timezone tz;
HTTPClient http;
LiquidCrystal_I2C lcd(0x27, 16, 2);
void connect()
{
while (true) {
WiFi.disconnect();
while (WiFi.status() == WL_CONNECTED);
delay(1000);
WiFi.begin(WIFI_SSID, WIFI_PASS);
delay(1000);
/* Wait for connection */
for (int i = 0; i < WIFI_CONN_RETRIES; i++) {
if (WiFi.status() == WL_CONNECTED)
return;
delay(WIFI_CONN_INTERVAL);
}
}
}
void setup()
{
lcd.init();
lcd.clear();
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
#ifdef __DEBUG__
Serial.begin(115200);
Serial.setDebugOutput(true);
setDebug(DEBUG);
#endif
WiFi.persistent(false);
WiFi.setAutoConnect(false);
WiFi.setAutoReconnect(false);
connect();
/* Use geolocation to determine timezone */
DynamicJsonDocument doc(512);
while (true) {
http.setTimeout(HTTP_GET_TIMEOUT);
http.begin("http://worldtimeapi.org/api/ip");
if (!http.GET() || deserializeJson(doc, http.getString()))
connect();
else
break;
}
/* Update local timezone */
tz.setLocation(doc["timezone"]);
setServer("time.google.com");
while (!waitForSync(NTP_SYNC_TIMEOUT))
connect();
String tzName = tz.getTimezoneName();
lcd.setCursor(16 - tzName.length(), 1);
lcd.backlight();
lcd.print(tzName);
digitalWrite(LED_BUILTIN, HIGH);
tz.setEvent(update, tz.now() + 1);
}
void update()
{
lcd.setCursor(0, 0);
lcd.print(dayShortStr(tz.weekday()));
lcd.setCursor(5, 0);
lcd.print((char) (tz.day() / 10 + 48));
lcd.print((char) (tz.day() % 10 + 48));
lcd.print('-');
lcd.print(monthShortStr(tz.month()));
lcd.print('-');
lcd.print((char) (tz.year() / 1000 + 48));
lcd.print((char) (tz.year() / 100 % 10 + 48));
lcd.print((char) (tz.year() / 10 % 10 + 48));
lcd.print((char) (tz.year() % 10 + 48));
lcd.setCursor (0, 1);
lcd.print((char) (tz.hourFormat12() / 10 + 48));
lcd.print((char) (tz.hourFormat12() % 10 + 48));
lcd.print(':');
lcd.print((char) (tz.minute() / 10 + 48));
lcd.print((char) (tz.minute() % 10 + 48));
lcd.print(':');
lcd.print((char) (tz.second() / 10 + 48));
lcd.print((char) (tz.second() % 10 + 48));
lcd.print(tz.isAM() ? "am" : "pm");
if (timeStatus() == timeNotSet || timeStatus() == timeNeedsSync) {
digitalWrite(LED_BUILTIN, LOW);
#ifdef __DEBUG__
Serial.print("ntp: Out of sync, status is ");
Serial.println(timeStatus());
#endif
/* Check connectivity status */
while (!waitForSync(NTP_SYNC_TIMEOUT))
connect();
digitalWrite(LED_BUILTIN, HIGH);
}
/* Reschedule event for next second */
tz.setEvent(update, tz.now() + 1);
}
void loop()
{
events();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment