#include <WiFi.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <time.h>
// ==========================
// OLED display settings
// ==========================
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// ==========================
// WiFi credentials
// ==========================
const char *ssid = "Wokwi-GUEST";
const char *password = "";
// ==========================
// Switch settings (4-bit binary)
// ==========================
#define SW0 2 // LSB
#define SW1 3
#define SW2 4
#define SW3 5 // MSB
int lastTZ = -1; // store previous value to detect changes
// ==========================
// Timezone definitions (16 total)
// ==========================
struct Timezone {
const char* tz; // TZ database string
const char* name; // Display name
};
Timezone timezones[] = {
{ "GMT0", "GMT/UTC" },
{ "IST-2IDT,M3.4.4/26,M10.5.0", "Israel" },
{ "EST5EDT,M3.2.0,M11.1.0", "US Eastern" },
{ "CST6CDT,M3.2.0,M11.1.0", "US Central" },
{ "MST7MDT,M3.2.0,M11.1.0", "US Mountain" },
{ "PST8PDT,M3.2.0,M11.1.0", "US Pacific" },
{ "GMT0BST,M3.5.0/1,M10.5.0", "London" },
{ "CET-1CEST,M3.5.0,M10.5.0/3", "Central Europe" },
{ "EET-2EEST,M3.5.0/3,M10.5.0/4", "Eastern Europe" },
{ "MSK-3", "Moscow" },
{ "JST-9", "Tokyo" },
{ "KST-9", "Seoul" },
{ "IST-5:30", "Delhi" },
{ "HKT-8", "Hong Kong" },
{ "AEST-10AEDT,M10.1.0,M4.1.0/3", "Sydney" },
{ "NZST-12NZDT,M9.5.0,M4.1.0/3", "New Zealand" }
};
const int timezoneCount = sizeof(timezones) / sizeof(timezones[0]);
int currentTZ = 0;
// ==========================
// Display refresh
// ==========================
unsigned long lastUpdate = 0;
const long updateInterval = 1000;
void setup() {
Serial.begin(115200);
Wire.begin(8, 9);
// Setup switches
pinMode(SW0, INPUT_PULLUP);
pinMode(SW1, INPUT_PULLUP);
pinMode(SW2, INPUT_PULLUP);
pinMode(SW3, INPUT_PULLUP);
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;);
}
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
display.display();
// Connect WiFi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) delay(500);
// Configure NTP
configTime(0, 0, "pool.ntp.org", "time.nist.gov");
applyTimezone();
}
void applyTimezone() {
setenv("TZ", timezones[currentTZ].tz, 1);
tzset();
Serial.print("Switched timezone to: ");
Serial.println(timezones[currentTZ].name);
}
// Read switches as binary number
int readSwitches() {
int val = (digitalRead(SW0) == LOW ? 1 : 0)
| (digitalRead(SW1) == LOW ? 2 : 0)
| (digitalRead(SW2) == LOW ? 4 : 0)
| (digitalRead(SW3) == LOW ? 8 : 0);
return val;
}
String formatTwoDigits(int number) {
return number < 10 ? "0" + String(number) : String(number);
}
String getFormattedDate(struct tm *timeinfo) {
String day = formatTwoDigits(timeinfo->tm_mday);
String month = formatTwoDigits(timeinfo->tm_mon + 1);
String year = String(timeinfo->tm_year + 1900);
return day + "/" + month + "/" + year;
}
String get12HourTime(struct tm *timeinfo) {
int hour = timeinfo->tm_hour;
String period = hour < 12 ? " AM" : " PM";
if (hour == 0) hour = 12;
else if (hour > 12) hour -= 12;
return formatTwoDigits(hour) + ":" + formatTwoDigits(timeinfo->tm_min) + " " + period;
}
void drawCenteredText(String text, int y, int textSize) {
display.setTextSize(textSize);
int16_t x1, y1;
uint16_t w, h;
display.getTextBounds(text, 0, 0, &x1, &y1, &w, &h);
display.setCursor((SCREEN_WIDTH - w) / 2, y);
display.print(text);
}
void loop() {
// ==========================
// Handle switch input
// ==========================
int newTZ = readSwitches();
if (newTZ != lastTZ && newTZ < timezoneCount) {
currentTZ = newTZ;
applyTimezone();
lastTZ = newTZ;
}
// ==========================
// Update display
// ==========================
if (millis() - lastUpdate >= updateInterval) {
lastUpdate = millis();
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
Serial.println("Failed to get time");
return;
}
display.clearDisplay();
// DATE
display.fillRect(0, 0, SCREEN_WIDTH, 20, SSD1306_WHITE);
display.setTextColor(SSD1306_BLACK);
drawCenteredText(getFormattedDate(&timeinfo), 5, 2);
// TIME
display.setTextColor(SSD1306_WHITE);
String timeStr = get12HourTime(&timeinfo);
drawCenteredText(timeStr.substring(0, 6), 28, 3);
// AM/PM
display.setTextSize(2);
display.setCursor((SCREEN_WIDTH / 2) + 40, 32);
display.print(timeStr.substring(7));
// TZ name
display.setTextSize(1);
drawCenteredText(String("Zone: ") + timezones[currentTZ].name, 56, 1);
display.display();
}
// WiFi reconnect
if (millis() % 10000 == 0 && WiFi.status() != WL_CONNECTED) {
WiFi.reconnect();
}
}
Loading
esp32-c3-devkitm-1
esp32-c3-devkitm-1