#include <Wire.h>
#include <RTClib.h>
#include <WiFi.h>
#include <time.h>
RTC_DS3231 rtc;
const char* ssid = "Wokwi-GUEST"; // Ersetze durch deine SSID
const char* password = ""; // Ersetze durch dein WLAN-Passwort
const char* ntpServer = "pool.ntp.org";
// Anpassen der Zeitzone für automatische Sommer-/Winterzeitumstellung
const char* timeZone = "CET-1CEST,M3.5.0/2,M10.5.0/3"; // MEZ/MESZ für Deutschland
const int ledPin = 2; // LED für Morsecode-Zeitanzeige
const int led2Pin = 15; // Zweite LED, blinkt bei bestimmten Sekundenzeiten
// Morsecode Definition
const int dotDuration = 200; // Dauer eines Punktes in ms
const int dashDuration = 900; // Dauer eines Striches in ms
const int symbolSpace = 200; // Abstand zwischen Punkt und Strich in ms
const int letterSpace = 900; // Abstand zwischen Buchstaben in ms
const int wordSpace = 1400; // Abstand zwischen Wörtern in ms
void setup() {
Serial.begin(115200);
// LEDs konfigurieren
pinMode(ledPin, OUTPUT);
pinMode(led2Pin, OUTPUT);
// I2C-Verbindung für 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__))); // Stellt die RTC auf das Kompilierungsdatum ein
}
// WLAN-Verbindung herstellen
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Verbindung zu WiFi...");
}
Serial.println("Mit WiFi verbunden.");
// NTP-Konfiguration mit automatischer Sommer-/Winterzeit
configTime(0, 0, ntpServer); // Setzt den NTP-Server
setenv("TZ", timeZone, 1); // Setzt die Zeitzone für MEZ/MESZ
tzset(); // Wendet die Zeitzone an
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 mit der NTP-Zeit synchronisieren
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(); // Zeit von der RTC holen
int seconds = now.second();
// LED-Steuerung für spezielle Sekundenzeiten
if (seconds == 30) {
blinkLed(led2Pin, 2); // 2x blinken bei 30 Sekunden
} else if (seconds == 45) {
blinkLed(led2Pin, 3); // 3x blinken bei 45 Sekunden
} else if (seconds == 56) {
blinkLed(led2Pin, 1); // 1x blinken bei 56 Sekunden
}
// Zeitanzeige im Morsecode bei jeder vollen Minute
if (seconds == 0) {
int hours = now.hour();
int minutes = now.minute();
// Uhrzeit in der Konsole anzeigen
Serial.printf("Es ist %02d:%02d\n", hours, minutes);
// Stunden im Morsecode anzeigen
morseNumber(hours);
// Pause zwischen Stunden und Minuten
delay(wordSpace);
// Minuten im Morsecode anzeigen
morseNumber(minutes);
}
delay(1000); // 1 Sekunde warten und erneut prüfen
}
void blinkLed(int pin, int times) {
for (int i = 0; i < times; i++) {
digitalWrite(pin, HIGH); // LED an
delay(1000); // 1 Sekunde warten
digitalWrite(pin, LOW); // LED aus
if (i < times - 1) {
delay(1000); // 1 Sekunde Pause zwischen Blinken
}
}
}
void morseNumber(int number) {
// Zahl in zwei Ziffern zerlegen und im Morsecode darstellen
morseDigit(number / 10); // Zehnerstelle
delay(letterSpace); // Abstand zwischen Ziffern
morseDigit(number % 10); // Einerstelle
}
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);
delay(dotDuration);
} else if (*signal == '-') {
digitalWrite(ledPin, HIGH);
delay(dashDuration);
}
digitalWrite(ledPin, LOW);
delay(symbolSpace);
signal++;
}
}