#include <Wire.h>
#include <RTClib.h>
#include <WiFi.h>
#include <time.h>
RTC_DS3231 rtc;
const char* ssid = "Wokwi-GUEST";
const char* password = "";
const char* ntpServer = "pool.ntp.org";
// automatische Sommer-/Winterzeitumstellung für Deutschland
const char* timeZone = "CET-1CEST,M3.5.0/2,M10.5.0/3";
const int ledPin = 2; // LED für Morsecode-Zeitanzeige
const int led2Pin = 15; // zweite LED, blinkt bei bestimmten Sekundenzeiten
const int piezoPin = 4; // Piezo für Morsecode-Töne
const int lightPin = 16; // Beleuchtungsausgang
// Morsecode Definition
const int dotDuration = 200;
const int dashDuration = 900;
const int symbolSpace = 200;
const int letterSpace = 900;
const int wordSpace = 1400;
void setup() {
Serial.begin(115200);
pinMode(ledPin, OUTPUT);
pinMode(led2Pin, OUTPUT);
pinMode(piezoPin, OUTPUT);
pinMode(lightPin, OUTPUT);
digitalWrite(lightPin, LOW); // Standard: aus
// RTC starten
if (!rtc.begin()) {
Serial.println("Fehler beim Verbinden mit der RTC!");
while (1);
}
if (rtc.lostPower()) {
Serial.println("RTC hat die Stromversorgung verloren, Zeit neu einstellen...");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
// WLAN starten
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Verbindung zu WiFi...");
}
Serial.println("Mit WiFi verbunden.");
// NTP konfigurieren
configTime(0, 0, ntpServer);
setenv("TZ", timeZone, 1);
tzset();
if (syncNTP()) {
Serial.println("NTP-Zeit synchronisiert.");
} else {
Serial.println("Fehler beim Abrufen der NTP-Zeit.");
}
}
bool syncNTP() {
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
return false;
}
rtc.adjust(DateTime(
timeinfo.tm_year + 1900,
timeinfo.tm_mon + 1,
timeinfo.tm_mday,
timeinfo.tm_hour,
timeinfo.tm_min,
timeinfo.tm_sec
));
return true;
}
void loop() {
DateTime now = rtc.now();
int hours = now.hour();
int minutes = now.minute();
int seconds = now.second();
// Beleuchtung abhängig von der Uhrzeit
if ((hours > 17 || (hours == 17 && minutes >= 30)) && (hours < 23 || (hours == 23 && minutes < 30))) {
digitalWrite(lightPin, HIGH);
} else {
digitalWrite(lightPin, LOW);
}
// LED-Steuerung für Zusatzblinks
if (seconds == 30) {
blinkLed(led2Pin, 2);
} else if (seconds == 45) {
blinkLed(led2Pin, 3);
} else if (seconds == 56) {
blinkLed(led2Pin, 1);
}
// Zeitanzeige im Morsecode bei jeder vollen Minute
if (seconds == 0) {
Serial.printf("Es ist %02d:%02d\n", hours, minutes);
morseNumber(hours);
delay(wordSpace);
morseNumber(minutes);
}
delay(1000);
}
void blinkLed(int pin, int times) {
for (int i = 0; i < times; i++) {
digitalWrite(pin, HIGH);
delay(1000);
digitalWrite(pin, LOW);
if (i < times - 1) {
delay(1000);
}
}
}
void morseNumber(int number) {
morseDigit(number / 10);
delay(letterSpace);
morseDigit(number % 10);
}
void morseDigit(int digit) {
switch (digit) {
case 0: morseSignal("-----"); break;
case 1: morseSignal(".----"); break;
case 2: morseSignal("..---"); break;
case 3: morseSignal("...--"); break;
case 4: morseSignal("....-"); break;
case 5: morseSignal("....."); break;
case 6: morseSignal("-...."); break;
case 7: morseSignal("--..."); break;
case 8: morseSignal("---.."); break;
case 9: morseSignal("----."); break;
}
}
void morseSignal(const char* signal) {
while (*signal) {
if (*signal == '.') {
digitalWrite(ledPin, HIGH);
analogWrite(piezoPin, 85); // ca. 1V PWM
delay(dotDuration);
} else if (*signal == '-') {
digitalWrite(ledPin, HIGH);
analogWrite(piezoPin, 85);
delay(dashDuration);
}
digitalWrite(ledPin, LOW);
analogWrite(piezoPin, 0);
delay(symbolSpace);
signal++;
}
}