#include <RTClib.h>
#include <TimeLib.h>
#include <Wire.h>
// --- RTC and Time Zone Definitions ---
RTC_DS3231 rtc;
//RTC_DS1307 rtc;
const uint8_t TZ_COLUMNS = 4;
// Time Zone definitions (Name, POSIX String, Standard Name, DST Name)
const char *const TZ_DATA[][TZ_COLUMNS] = {
{ "Europe", "CET-1CEST,M3.5.0/2:00:00,M10.5.0/2:00:00", "CET", "CEST" }, // Central European Time
{ "UTC", "GMT0", "UTC", "UTC" }, // UTC
// Add other time zones here if needed for TZrows calculation
};
const uint8_t TZ_ROWS = sizeof(TZ_DATA) / sizeof(TZ_DATA[0]);
// Global variables for time
uint8_t TZ_SELECT = 0; // Default Time Zone: Europe
struct tm ltz; // Local Time structure (filled by localtime_r)
time_t UTCsec; // Universal Time Coordinated (Epoch seconds)
time_t prevTime = 0; // For time tick debouncing
// --- CORE FUNCTIONS ---
// Function to update global UTCsec and TimeLib from RTC
void updateClock() {
// Get epoch time from RTC (ASSUMED TO BE UTC)
UTCsec = rtc.now().unixtime();
// Set TimeLib system clock to UTC time for internal consistency
setTime(UTCsec);
}
// Function to convert UTCsec to Local Time (LT) and print results
void GetLocalTimeStr() {
// CRITICAL STEP: Convert UTC (UTCsec) to Local Time (ltz)
// localtime_r uses the global 'TZ' environment variable set in setup()
localtime_r(&UTCsec, <z);
// --- DIAGNOSTICS FOR WOKWI ---
// 1. RAW RTC READ (Expected: UTC)
DateTime now_rtc = rtc.now();
Serial.printf("DEBUG: Raw RTC Time (Expected UTC): %04d-%02d-%02d %02d:%02d:%02d\n", now_rtc.year(), now_rtc.month(), now_rtc.day(), now_rtc.hour(), now_rtc.minute(), now_rtc.second());
// 2. CONVERTED LOCAL TIME (Expected: LT = UTC + Offset)
Serial.printf("DEBUG: LT Converted (ltz): %04d-%02d-%02d %02d:%02d:%02d (%s)\n", ltz.tm_year + 1900, ltz.tm_mon + 1, ltz.tm_mday, ltz.tm_hour, ltz.tm_min, ltz.tm_sec, ltz.tm_isdst ? TZ_DATA[TZ_SELECT][3] : TZ_DATA[TZ_SELECT][2]);
// 3. UTCsec value
Serial.printf("DEBUG: UTC Epoch: %lu\n\n", UTCsec);
}
// --- SETUP ---
void setup () {
Serial.begin(115200);
Wire.begin();
if (!rtc.begin()) {
Serial.println("Error: Cannot find RTC DS3231!");
while (1) {
delay(100);
}
}
// >>> NOWA SEKCJA TYMCZASOWA DLA WOKWI <<<
DateTime now_check = rtc.now();
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// >>> KONIEC SEKCJI HACKUJĄCEJ WOKWI <<<
// 1. INITIAL TIME SYNC: Read RTC -> UTCsec -> set TimeLib system clock
// This uses the time set via Wokwi's 'initTime' attribute.
updateClock();
// 2. SET POSIX TIMEZONE RULES (Only set Local Time Zone)
// We set the TZ rules for Central Europe (CET-1CEST)
setenv("TZ", TZ_DATA[TZ_SELECT][1], 1);
tzset();
// Wait a moment for TZ rules to stabilize in the ESP32 OS
delay(100);
// 3. Initial calculation of Local Time strings
GetLocalTimeStr();
}
// --- LOOP ---
void loop () {
// 1. UPDATE BASE TIME (UTC) from RTC every cycle
updateClock();
// 2. Update Local Time and Display Strings only on a second tick
if (second(now()) != second(prevTime)) {
GetLocalTimeStr(); // Convert UTCsec to LT and print results
prevTime = now(); // Update the previous time variable
}
delay(100);
}
//"attrs": { "initTime": "1970-01-01T00:00:00Z" }