#include "RTClib.h"
#include "LiquidCrystal_I2C.h"
#include "EEPROM.h"
#include "Bounce2.h"
#include "PlayRtttl.hpp"
// 4-zeiliges LCD
LiquidCrystal_I2C lcd(0x27, 20, 4);
// Name des RTC-Moduls
RTC_DS3231 rtc;
int Lautsprecher = 5;
int TasterLinks = 7;
int TasterMitte = 8;
int TasterRechts = 9 ;
// Beginn der Weckzeit
int StundeWeckzeit = 7;
int MinuteWeckzeit = 0;
// Uhrzeiten Aus/-einschaltung Hintergrundbeleuchtung
int ZeitBeleuchtungAus = 22;
int ZeitBeleuchtungEin = 7;
// Sekunden anzeigen ein/aus
bool SekundenAnzeigen = true;
// Dauer des Signal in Sekunden
int DauerWecksignal = 10;
bool WeckerEinAus;
bool AnzeigeTemperatur = false;
Bounce WeckzeitStunde = Bounce();
Bounce WeckzeitMinute = Bounce();
Bounce StatusWecker = Bounce();
// 0
char TeDeum[] =
"Te_Deum:d=4,o=5,b=63:8c,8f,16f,16g,8a,8f,c6,8a,8a,8a#,16c6,16a#,16a,16a#,8c6,16g,16f,16g,16a,8g";
// 1
char FuerElise[] =
"Elise:d=8,o=5,b=125:32p,e6,d#6,e6,d#6,e6,b,d6,c6,4a.,32p,c,e,a,4b.,32p,e,g#,b,4c.6,32p,e,e6,d#6,e6,d#6,e6,b,d6,c6,4a";
// 2
char OdeandieFreude[] =
"Ode_an_die_Freude:d=4,o=6,b=100:a5,a5,a_5,c,c,a_5,a5,g5,f5,f5,g5,a5,a.5,8g5,2g5,";
// 3
char Bolero[] =
"Bolero:d=4,o=5,b=80:c6,8c6,16b,16c6,16d6,16c6,16b,16a,8c6,16c6,16a,c6,8c6,16b,16c6,16a,16g,16e,16f,2g,16g,16f,16e,16d,16e,16f,16g,16a,g,g,";
int Weckmelodie = 0;
void setup()
{
pinMode(TasterLinks, INPUT_PULLUP);
pinMode(TasterMitte, INPUT_PULLUP);
pinMode(TasterRechts, INPUT_PULLUP);
// Instanzen des Objekts Bounce für jede Taste zuordnen
// Zeitintervall einstellen
WeckzeitStunde.attach(TasterLinks);
WeckzeitStunde.interval(20);
WeckzeitMinute.attach(TasterMitte);
WeckzeitMinute.interval(20);
StatusWecker.attach(TasterRechts);
StatusWecker.interval(20);
Serial.begin(9600);
// auf serielle Verbindung warten
while (!Serial) {;}
delay(1000);
rtc.begin();
/*
wenn Datum und Zeit nicht korrekt -> Datum/Zeit setzen
Jahr, Monat, Tag, Stunde, Minute, Sekunde
keine führende 0 setzen
rtc.adjust(DateTime(2025, 4, 14, 16, 42, 30));
*/
// rtc.adjust(DateTime(2025, 4, 14, 16, 42, 30));
// Zeitpunkt des Kompilierens als aktuelle Zeit setzen
// rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// LCD starten
lcd.init();
// Hintergrundbeleuchtung einschalten
lcd.backlight();
Serial.println(StundeWeckzeit);
Serial.println(MinuteWeckzeit);
Serial.println(WeckerEinAus);
}
void loop()
{
String Stunde, Minute, Weckzeit;
// aktuelle Zeit lesen
DateTime aktuell = rtc.now();
// Stunde einstellen
if (WeckzeitStunde.update())
{
if (WeckzeitStunde.read() == LOW)
{
if (StundeWeckzeit >= 23) StundeWeckzeit = 0;
else StundeWeckzeit ++;
}
}
// Minute einstellen
if (WeckzeitMinute.update())
{
if (WeckzeitMinute.read() == LOW)
{
if (MinuteWeckzeit >= 59) MinuteWeckzeit = 0;
else MinuteWeckzeit ++;
}
}
// Wecker ein/aus
if (StatusWecker.update())
{
if (StatusWecker.read() == LOW)
{
WeckerEinAus = !WeckerEinAus;
}
}
// Wochentag, Datum und Zeit anzeigen
lcd.setCursor(0, 0);
/*
Wochentag anzeigen
0 = Sonntag
1 = Montag
...
6 = Samstag
*/
switch (aktuell.dayOfTheWeek())
{
case 0:
lcd.print("Sonntag ");
break;
case 1:
lcd.print("Montag ");
break;
case 2:
lcd.print("Dienstag ");
break;
case 3:
lcd.print("Mittwoch ");
break;
case 4:
lcd.print("Donnerstag");
break;
case 5:
lcd.print("Freitag ");
break;
case 6:
lcd.print("Samstag ");
break;
}
if(AnzeigeTemperatur)
{
// Temperatur ermitteln
String Temperatur = String(rtc.getTemperature(), 1);
// Wert wid im angelsächsisches Zahlenformat ermittelt
// . durch , ersetzen
Temperatur.replace(".", ",");
lcd.print(Temperatur + "\337C ");
}
lcd.setCursor(0, 1);
lcd.print(String(aktuell.day()) + ".");
// Monatsnamen anzeigen
lcd.print(" ");
switch (aktuell.month())
{
case 1:
lcd.print("Januar");
break;
case 2:
lcd.print("Februar");
break;
case 3:
lcd.print("M\341rz");
break;
case 4:
lcd.print("April");
break;
case 5:
lcd.print("Mai");
break;
case 6:
lcd.print("Juni");
break;
case 7:
lcd.print("Juli");
break;
case 8:
lcd.print("August");
break;
case 9:
lcd.print("September");
break;
case 10:
lcd.print("Oktober");
break;
case 11:
lcd.print("November");
break;
case 12:
lcd.print("Dezember");
break;
}
lcd.print(" ");
lcd.print(String(aktuell.year()));
lcd.setCursor(0, 2);
// wenn Stunden < 10 -> führende 0 setzen
if (aktuell.hour() < 10) lcd.print("0");
lcd.print(String(aktuell.hour()));
lcd.print(':');
// wenn Minuten < 10 -> führende 0 setzen
if (aktuell.minute() < 10) lcd.print("0");
lcd.print(String(aktuell.minute()));
if(SekundenAnzeigen)
{
lcd.print(':');
// wenn Sekunden < 10 -> führende 0 setzen
if (aktuell.second() < 10) lcd.print("0");
lcd.print(String(aktuell.second()));
}
// Steuerung der Hintergrundbeleuchtung
if(aktuell.hour() == ZeitBeleuchtungAus) lcd.setBacklight(false);
if(aktuell.hour() == ZeitBeleuchtungEin) lcd.setBacklight(true);
if (WeckerEinAus) lcd.print(" Wecker ein");
else lcd.print(" Wecker aus");
/*
Weckzeit formatieren -> führende 0 ergänzen
4 mögliche Fälle
Stunde < 10 Minute < 10
Stunde < 10 Minute > 9
Stunde > 10 Minute < 10
Stunde > 10 Minute > 9
*/
if (StundeWeckzeit < 10 && MinuteWeckzeit < 10)
{
Weckzeit = "0" + String(StundeWeckzeit) + ":0" + String(MinuteWeckzeit);
}
if (StundeWeckzeit < 10 && MinuteWeckzeit > 9)
{
Weckzeit = "0" + String(StundeWeckzeit) + ":" + String(MinuteWeckzeit);
}
if (StundeWeckzeit > 9 && MinuteWeckzeit < 10)
{
Weckzeit = String(StundeWeckzeit) + ":0" + String(MinuteWeckzeit);
}
if (StundeWeckzeit > 9 && MinuteWeckzeit > 9)
{
Weckzeit = String(StundeWeckzeit) + ":" + String(MinuteWeckzeit);
}
lcd.setCursor(0, 3);
lcd.print("Weckzeit: " + Weckzeit);
// führende 0 setzen
if (aktuell.hour() < 10) Stunde = "0" + String(aktuell.hour());
else Stunde = String(aktuell.hour());
// führende 0 setzen
if (aktuell.minute() < 10) Minute = "0" + String(aktuell.minute());
else Minute = String(aktuell.minute());
// String zusammensetzen
String aktuelleZeit = Stunde + ":" + Minute;
if(WeckerEinAus)
{
if (aktuelleZeit == Weckzeit && aktuell.second() < DauerWecksignal)
{
switch(Weckmelodie)
{
case 0:
startPlayRtttl(Lautsprecher, TeDeum);
while (updatePlayRtttl())
{
delay(1);
}
break;
case 1:
startPlayRtttl(Lautsprecher, FuerElise);
while (updatePlayRtttl())
{
delay(1);
}
break;
case 2:
startPlayRtttl(Lautsprecher, OdeandieFreude);
while (updatePlayRtttl())
{
delay(1);
}
break;
case 3:
startPlayRtttl(Lautsprecher, Bolero);
while (updatePlayRtttl())
{
delay(1);
}
break;
default:
break;
}
}
}
}linker Taster: Stunde +
mittlerer Taster: Minute +
rechter Taster: Wecker ein/aus