/*
Project: ESP32 Binary Clock
Description: Basic test of ESP32 & NTP
Creation date: 12/10/22
Author: AnonEngineering
// Learn about the ESP32 WiFi simulation in
// https://docs.wokwi.com/guides/esp32-wifi
// https://randomnerdtutorials.com/esp32-ntp-timezones-daylight-saving/
// https://wokwi.com/projects/350262062471971412
License: Beerware
*/
#include <WiFi.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
const char* NTP_SERVER = "pool.ntp.org";
const int16_t UTC_OFFSET = -18000;
const int16_t UTC_OFFSET_DST = 3600;
const char* SSID = "Wokwi-GUEST";
const char* PASS = "";
// see https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv
// and https://www.netburner.com/learn/time-zones-and-daylight-savings-with-olson-and-posix/
const char* TZ_LOCAL = "EST5EDT4,M3.2.0/01:00:00,M11.1.0/02:00:00";
//const char* TZ_LOCAL = "CST6CDT,M3.2.0,M11.1.0";
//const char* TZ_LOCAL = "MST7MDT,M3.2.0,M11.1.0";
//const char* TZ_LOCAL = "PST8PDT,M3.2.0,M11.1.0";
const int HOURS_TEN_PINS[2] = {15, 14};
const int HOURS_ONE_PINS[4] = {13, 12, 11, 10};
const int MINS_TEN_PINS[3] = {6, 5, 4};
const int MINS_ONE_PINS[4] = {3, 2, 1, 0};
const int HOUR_SW_PIN = 7;
LiquidCrystal_I2C lcd(0x27, 20, 4);
void initTime(String timezone) {
struct tm timeinfo;
Serial.println("Setting up time");
configTime(0, 0, "pool.ntp.org"); // First connect to NTP server, with 0 TZ offset
if (!getLocalTime(&timeinfo)) {
Serial.println(" Failed to obtain time");
lcd.setCursor(0, 3);
lcd.print("NTP: NG");
return;
}
Serial.println(" Got the time from NTP");
lcd.setCursor(0, 3);
lcd.print("NTP: OK");
// Now we can set the real timezone
setTimezone(timezone);
lcd.setCursor(11, 3);
lcd.print("TZ: ");
lcd.setCursor(15, 3);
lcd.println(&timeinfo, "%Z");
}
void printLocalTime() {
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
Serial.println("Connection Err");
return;
}
Serial.println(&timeinfo, "%H:%M:%S %Z");
Serial.println(&timeinfo, "%m/%d/%Y");
}
void setTimezone(String timezone) {
Serial.printf(" Setting Timezone to %s\n", timezone.c_str());
// Now adjust the TZ. Clock settings are adjusted to show the new local time
setenv("TZ", timezone.c_str(), 1);
tzset();
}
void showBinTime() {
struct tm timeinfo;
static bool bAMPM = false;
static int intHour12 = 0;
if (!getLocalTime(&timeinfo)) {
Serial.println("Connection Err");
return;
}
intHour12 = timeinfo.tm_hour;
if (digitalRead(HOUR_SW_PIN) == false) { // 12 hour time
if (intHour12 < 12) {
bAMPM = true; // am
} else {
intHour12 = intHour12 - 12;
bAMPM = false; // pm
}
if (intHour12 == 0) { // make midnight & noon 12
intHour12 = 12;
}
Serial.print(intHour12); // 12 hour time
Serial.print(&timeinfo, ":%M:%S");
if (bAMPM == true) {
Serial.print(" AM ");
} else {
Serial.print(" PM ");
}
Serial.println(&timeinfo, "%Z");
} else {
Serial.println(&timeinfo, "%H:%M:%S %Z"); // 24 hour time
}
//Serial.println(&timeinfo, "%m/%d/%Y"); // month/day/year
Serial.println(&timeinfo, "%A"); // day of week
Serial.println(&timeinfo, "%B %d, %Y"); // month, day , year
Serial.println();
// seperate digits
/*
void showDigit(int digit) {
for (int bitIndex = 7; bitIndex >= 0; bitIndex--) { // Cycle through the 4 bits of BCD
int bits = digit / pow (2, bitIndex); // Integer division for each power of 2
digitalWrite (PIN[bitIndex], bits % 2); // Modulo 2 of each bits integer division
// prints for test
Serial.print("Pin ");
Serial.print(PIN[bitIndex]);
Serial.print(" ");
Serial.print((bits % 2) ? "1 " : "0 ");
}
Serial.println();
delay (1000);
}
*/
int now10Hour = intHour12 / 10;
int now1Hour = intHour12 % 10;
int now10Min = timeinfo.tm_min / 10;
int now1Min = timeinfo.tm_min % 10;
// BCD for each digit
for (int j = 0; j < 4; j ++) {
int aux = now1Min / pow (2, j);
digitalWrite (MINS_ONE_PINS[j], aux % 2);
}
for (int j = 0; j < 3; j ++) {
int aux = now10Min / pow (2, j);
digitalWrite (MINS_TEN_PINS[j], aux % 2);
}
for (int j = 0; j < 4; j ++) {
int aux = now1Hour / pow (2, j);
digitalWrite (HOURS_ONE_PINS[j], aux % 2);
}
for (int j = 0; j < 2; j ++) {
int aux = now10Hour / pow (2, j);
digitalWrite (HOURS_TEN_PINS[j], aux % 2);
}
}
void setup() {
Serial.begin(115200);
Wire.begin();
lcd.begin(20, 4);
lcd.backlight();
// setup pins - TODO, make dynamic*****************************************
for (int i = 0; i <= 6; i++) {
pinMode(i, OUTPUT);
}
for (int i = 10; i <= 15; i++) {
pinMode(i, OUTPUT);
}
pinMode(HOUR_SW_PIN, INPUT_PULLUP);
Serial.println("ESP32-S2 Binary Clock");
lcd.print("ESP32S2 Binary Clock");
WiFi.begin(SSID, PASS, 6);
while (WiFi.status() != WL_CONNECTED) {
delay(250);
Serial.print('.');
}
Serial.println("");
Serial.println("WiFi connected");
lcd.setCursor(0, 1);
lcd.println("WiFi connected");
lcd.setCursor(0, 2);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
lcd.print("IP addr: ");
lcd.println(WiFi.localIP());
Serial.println("Online!");
initTime(TZ_LOCAL);
printLocalTime();
}
void loop() {
//
delay(10); // improves wokwi simulation
//
static unsigned long prevTime = 0;
if (millis() - prevTime >= 1000) {
prevTime = millis();
showBinTime();
}
}
Loading
esp32-s2-devkitm-1
esp32-s2-devkitm-1