#include <WiFi.h>
#include <time.h>
#include <Wire.h>
#include <RTClib.h>
#include <Adafruit_NeoPixel.h>
// ======================================
// WLAN
// ======================================
const char* ssid = "Wokwi-GUEST";
const char* password = "";
// ======================================
// Zeitzone Deutschland
// ======================================
const char* timeZone = "CET-1CEST,M3.5.0/2,M10.5.0/3";
const char* ntpServer = "pool.ntp.org";
// ======================================
// LED Ring
// ======================================
#define LED_PIN 2
#define LED_COUNT 16
#define BRIGHTNESS 240
Adafruit_NeoPixel ring(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
// ======================================
// RTC
// ======================================
RTC_DS3231 rtc;
bool ntpOK = false;
// ======================================
// Farben
// ======================================
uint32_t colorHour;
uint32_t colorMinute;
uint32_t colorSecond;
// ======================================
void setup() {
Serial.begin(115200);
delay(500);
// LED Ring
ring.begin();
ring.setBrightness(BRIGHTNESS);
ring.clear();
ring.show();
colorHour = ring.Color(0, 0, 255); // Blau
colorMinute = ring.Color(255, 0, 80); // Pink
colorSecond = ring.Color(0, 255, 0); // Grün
// I2C
Wire.begin(21,22);
// RTC
if (!rtc.begin()) {
Serial.println("DS3231 nicht gefunden!");
} else {
Serial.println("DS3231 gefunden.");
}
// WLAN
connectWiFi();
// NTP
syncTimeFromNTP();
// RTC synchronisieren
if (ntpOK) {
updateRTCFromSystemTime();
} else {
Serial.println("NTP fehlgeschlagen - RTC wird verwendet.");
}
}
// ======================================
void loop() {
int h,m,s;
if (ntpOK) {
struct tm timeinfo;
if (getLocalTime(&timeinfo)) {
h = timeinfo.tm_hour;
m = timeinfo.tm_min;
s = timeinfo.tm_sec;
} else {
readTimeFromRTC(h,m,s);
}
} else {
readTimeFromRTC(h,m,s);
}
showBinaryTime(h,m,s);
delay(250);
}
// ======================================
void connectWiFi() {
Serial.print("Verbinde WLAN");
WiFi.begin(ssid,password);
unsigned long startAttempt = millis();
while (WiFi.status() != WL_CONNECTED &&
millis() - startAttempt < 15000) {
Serial.print(".");
delay(500);
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println();
Serial.println("WLAN verbunden.");
Serial.print("IP: ");
Serial.println(WiFi.localIP());
} else {
Serial.println();
Serial.println("WLAN-Verbindung fehlgeschlagen.");
}
}
// ======================================
void syncTimeFromNTP() {
if (WiFi.status() != WL_CONNECTED) {
ntpOK = false;
return;
}
Serial.println("Hole Zeit per NTP...");
// Automatische Sommer-/Winterzeit
configTzTime(timeZone, ntpServer);
struct tm timeinfo;
if (getLocalTime(&timeinfo,15000)) {
ntpOK = true;
Serial.println("NTP erfolgreich.");
Serial.println(&timeinfo,"%d.%m.%Y %H:%M:%S");
} else {
ntpOK = false;
Serial.println("NTP fehlgeschlagen.");
}
}
// ======================================
void updateRTCFromSystemTime() {
struct tm timeinfo;
if (getLocalTime(&timeinfo)) {
rtc.adjust(DateTime(
timeinfo.tm_year + 1900,
timeinfo.tm_mon + 1,
timeinfo.tm_mday,
timeinfo.tm_hour,
timeinfo.tm_min,
timeinfo.tm_sec
));
Serial.println("RTC aktualisiert.");
}
}
// ======================================
void readTimeFromRTC(int &h,int &m,int &s) {
DateTime now = rtc.now();
h = now.hour();
m = now.minute();
s = now.second();
}
// ======================================
void showBinaryTime(int hour, int minute, int second) {
ring.clear();
// 24h in 12h umwandeln
int displayHour = hour % 12;
if (displayHour == 0) {
displayHour = 12;
}
// ==========================
// Sekunden LED 0 - 5
// ==========================
for (int bit = 0; bit < 6; bit++) {
if (second & (1 << bit)) {
ring.setPixelColor(bit, colorSecond);
}
}
// ==========================
// Minuten LED 6 - 11
// ==========================
for (int bit = 0; bit < 6; bit++) {
if (minute & (1 << bit)) {
ring.setPixelColor(6 + bit, colorMinute);
}
}
// ==========================
// Stunden LED 12 - 15
// ==========================
for (int bit = 0; bit < 4; bit++) {
if (displayHour & (1 << bit)) {
ring.setPixelColor(12 + bit, colorHour);
}
}
ring.show();
}