
Ziele des Projekts
Die Weckzeit wird zusammen mit Wochentag, Datum und Uhrzeit auf dem 4-zeiligen LCD-Display mit I²C-Schnittstelle angezeigt. Die Einstellungen können mit Tastern oder einer Fernbedienung vorgenommen werden.
Außerdem wird die mit dem RTC-Modul gemessene Temperatur angezeigt. Für die Aktivierung des Wecksignals wird die ⇒Alarmfunktion des RTC-Moduls DS3231 genutzt.
Die Weckmelodie wird mit RTTTL abgespielt.
RTTTL (Ring Tone Text Transfer Language) sind Klingeltöne, die ursprünglich von Nokia für ihre Mobiltelefone entwickelt wurden. Ein Klingelton muss drei Bestandteile haben:
- den Namen des Klingeltons
- die Standardvorgaben: die Dauer der Noten und die verwendete Oktave
- die durch Kommata getrennten Noten (internationale Notenbezeichnung c, d, e, f, g, a, b) alle Teile sind durch einen Doppelpunkt getrennt
Beispiel Te Deum:
TeDeum:d=4,o=5,b=63:8c,8f,16f,16g,8a
d=4: Standardnotenlänge Viertelnote
o=5: Angabe der Oktave
b=63: Abspielgeschwindigkeit 63 Schläge pro Minute
8c: Note C als Achtelnote gespielt
Als Wecksignal stehen verschiedene Melodien zur Verfügung.
Das Programm spielt die Melodien:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
#include "PlayRtttl.hpp" int Lautsprecher = 5; 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 Elise[] = "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 Ode[] = "Ode: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"; // 4 char Fuenfte[] = "Fuenfte:d=4,o=5,b=180:8f,8f,8f,1c#,8p,8d#,8d#,8d#,1c,8p,8f,8f,8f,8c#,8f#,8f#,8f#,8f,8c#6,8c#6,8c#6,2a#,8p"; void setup() { playRtttlBlocking(Lautsprecher, TeDeum); delay(1000); playRtttlBlocking(Lautsprecher, Elise); delay(1000); playRtttlBlocking(Lautsprecher, Ode); delay(1000); playRtttlBlocking(Lautsprecher, Bolero); delay(1000); playRtttlBlocking(Lautsprecher, Fuenfte); } void loop() { // bleibt leer, Programm läuft nur einmal } |
Weitere Klingeltöne zum Download bei 🔗PICAXE
Wecker mit Tastern
Anwendungsbeispiel (Danke an Norbert Schrills)


- linker Taster: eine Stunde vorwärts
- mittlerer Taster: eine Minute weiter
- rechter Taster: Wecker ein- oder ausschalten


Die zuvor eingestellte Zeit und der Zustand des Weckers (ein/aus) werden auf dem internen Speicher (⇒EEPROM) eines Arduinos gespeichert.
Benötigte Bauteile
- 3 Taster
- ⇒4-zeiliges LCD mit I²C-Schnittstelle
- ⇒RTC-Modul DS3231
- Lautsprecher
- Leitungsdrähte

Die Laustärke des Lautsprechers kannst du mit einem vorgeschalteten Widerstand regulieren.

Der Schaltplan
(Fahre mit der Maus über das Bild, um die Bezeichnungen der Bauteile zu sehen)
Das Programm
Die zuvor eingestellte Zeit und der Zustand des Weckers (ein/aus) werden auf dem internen Speicher eines Arduinos gespeichert. Du kannst in Zeile 54 eine der Melodien als Wecksignal einstellen.
Bibliotheken und Variablen

![]() | ![]() |

Einstellungen:
- Uhrzeiten, in denen das Display dunkel geschaltet werden kann
ZeitBeleuchtungAus/ZeitBeleuchtungEin
Angabe einer Uhrzeit ohne vorangestellte 0 - Anzeige der Sekunden ein/aus
SekundenAnzeigen true/false - Dauer des Wecksignals in Sekunden
DauerWecksignal - Anzeige der Temperatur ein/aus
AnzeigeTemperatur true/false - Auswahl der Melodie:
0: TeDeum
1: FuerElise
2: OdeAnDieFreude
3: Bolero
4: Fuenfte - Licht beim Wecksignal ein/aus
Lichtwecker true/false

Solange die Weckmelodie abgespielt wird, bleibt der Sekundenzeiger stehen. Anschließend wird wieder der aktuelle Wert angezeigt.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
#include "RTClib.h" #include "LCDIC2.h" #include "EEPROM.h" #include "Bounce2.h" #include "PlayRtttl.hpp" // 4-zeiliges LCD LCDIC2 lcd(0x27, 20, 4); // Name des RTC-Moduls RTC_DS3231 rtc; #define AlarmInterruptPin 2 // Alarm beim Start auf false setzen volatile bool Alarm = false; #define Lautsprecher 5 #define LED 6 #define TasterLinks 9 #define TasterMitte 10 #define TasterRechts 11 // Standardwerte werden teilweise später durch EEPROM überschrieben int StundeWeckzeit = 7; int MinuteWeckzeit = 0; bool SekundenAnzeigen = true; bool WeckerEinAus = true; bool LichtWecker = true; bool AnzeigeTemperatur = true; bool LichtEinschalten = true; int Weckmelodie = 4; int Schlummerzeit = 1; int ZeitBeleuchtungAus = 22; int ZeitBeleuchtungEin = 7; // Tasten Bounce zuordnen 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 Elise[] = "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 Ode[] = "Ode: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"; // 4 char Fuenfte[] = "Fuenfte:d=4,o=5,b=180:8f,8f,8f,1c#,8p,8d#,8d#,8d#,1c,8p,8f,8f,8f,8c#,8f#,8f#,8f#,8f,8c#6,8c#6,8c#6,2a#,8p,8f,8f,8f,8c,8f#,8f#,8f#,8f,8d#6,8d#6,8d#6,1c6"; |
Der setup-Teil
Nachdem die Zeit mit dem Zeitpunkt des Kompilierens gesetzt wurde, musst du vor einem erneutem Hochladen die Zeile 32 mit // versehen, ansonsten stimmt nach einem Stromausfall oder einem erneutem Einstecken der Stromzufuhr die Zeit nicht mehr.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
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__))); // 32K-Pin am DS3231 deaktivieren rtc.disable32K(); // Pin 2 als Interrupt-Pin pinMode(AlarmInterruptPin, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(AlarmInterruptPin), Wecken, FALLING); // Alarme löschen und deaktivieren rtc.clearAlarm(1); rtc.clearAlarm(1); rtc.disableAlarm(1); rtc.disableAlarm(2); // LCD starten lcd.begin(); // Cursor "verstecken" lcd.setCursor(false); // Weckzeit Stunde/Minute aus EEPROM lesen StundeWeckzeit = EEPROM.read(0); MinuteWeckzeit = EEPROM.read(2); // Status der Weckzeit lesen ein/aus WeckerEinAus = EEPROM.read(4); // aktuelle Zeit lesen DateTime aktuell = rtc.now(); // Alarm setzen DateTime alarmTime (aktuell.year(), aktuell.month(), aktuell.dayOfTheWeek(), StundeWeckzeit, MinuteWeckzeit, 0); rtc.setAlarm1(alarmTime, DS3231_A1_Hour); // wenn Stunde/Minute übereinstimmen rtc.setAlarm1(alarmTime, DS3231_A1_Hour); } |
Der loop-Teil
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 |
void loop() { String Stunde, Minute, Weckzeit; int CursorPosition = 0; // aktuelle Zeit lesen DateTime aktuell = rtc.now(); // Stunde einstellen if (WeckzeitStunde.update()) { if (WeckzeitStunde.read() == LOW) { if (StundeWeckzeit >= 23) StundeWeckzeit = 0; else StundeWeckzeit ++; // Weckzeit Stunde an Position 0 in EEPROM schreiben EEPROM.update(0, StundeWeckzeit); // Weckzeit und Alarm neu setzen DateTime alarmTime (aktuell.year(), aktuell.month(), aktuell.dayOfTheWeek(), StundeWeckzeit, MinuteWeckzeit, 0); rtc.setAlarm1(alarmTime, DS3231_A1_Hour); } } // Minute einstellen if (WeckzeitMinute.update()) { if (WeckzeitMinute.read() == LOW) { if (MinuteWeckzeit >= 59) MinuteWeckzeit = 0; else MinuteWeckzeit ++; // Weckzeit Minute an Position 2 in EEPROM schreiben EEPROM.update(2, MinuteWeckzeit); // Weckzeit und Alarm neu setzen DateTime alarmTime (aktuell.year(), aktuell.month(), aktuell.dayOfTheWeek(), StundeWeckzeit, MinuteWeckzeit, 0); rtc.setAlarm1(alarmTime, DS3231_A1_Hour); } } // Wecker ein/aus if (StatusWecker.update()) { if (StatusWecker.read() == LOW) { WeckerEinAus = !WeckerEinAus; // Status Wecker schreiben if(WeckerEinAus) EEPROM.update(4, 1); else EEPROM.update(4, 0); } } // 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; } lcd.print(" "); if(AnzeigeTemperatur) { // Temperatur ermitteln String Temperatur = String(rtc.getTemperature(), 1); // Wert wid im angelsächsisches Zahlenformat ermittelt // . durch , ersetzen Temperatur.replace(".", ","); lcd.setCursor(12, 0); lcd.print(Temperatur + "\337C "); } lcd.setCursor(0, 1); lcd.print(String(aktuell.day()) + "."); // Cursorposition verschieben CursorPosition += 3; // Monatsnamen anzeigen lcd.print(" "); switch (aktuell.month()) { case 1: lcd.print("Januar"); CursorPosition += 6; break; case 2: lcd.print("Februar"); CursorPosition += 7; break; case 3: lcd.print("M\341rz"); CursorPosition += 4; break; case 4: lcd.print("April"); CursorPosition += 5; break; case 5: lcd.print("Mai"); CursorPosition += 3; break; case 6: lcd.print("Juni"); CursorPosition += 4; break; case 7: lcd.print("Juli"); CursorPosition += 4; break; case 8: lcd.print("August"); CursorPosition += 6; break; case 9: lcd.print("September"); CursorPosition += 9; break; case 10: lcd.print("Oktober"); CursorPosition += 7; break; case 11: lcd.print("November"); CursorPosition += 8; break; case 12: lcd.print("Dezember"); CursorPosition += 8; break; } lcd.print(" "); lcd.print(String(aktuell.year())); // Jahreszahl + Leerzeichen CursorPosition += 5; // mit Leerzeichen auffüllen for(int i = CursorPosition; i < 19; i++) { lcd.print(" "); } 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); lcd.setCursor(15, 3); if(LichtWecker) lcd.print("L"); else lcd.print(" "); lcd.setCursor(17, 3); if(WeckerEinAus) { if (Schlummerzeit > 9) lcd.print("S" + String(Schlummerzeit)); else lcd.print("S " + String(Schlummerzeit)); } else lcd.print(" "); // String zusammensetzen String aktuelleZeit = Stunde + ":" + Minute; if(WeckerEinAus) { if (Alarm) { if(rtc.alarmFired(1)) { // 255 = maximaler Wert if (LichtWecker) analogWrite(LED, 255); WeckmelodieSpielen(); rtc.clearAlarm(1); analogWrite(LED, 0); rtc.setAlarm2(rtc.now() + TimeSpan(0, 0, Schlummerzeit, 0), DS3231_A2_Minute); } // Schlummern if(rtc.alarmFired(2)) { if (LichtWecker) analogWrite(LED, 255); WeckmelodieSpielen(); rtc.clearAlarm(2); analogWrite(LED, 0); } } Alarm = false; } } |
Die Funktion Wecken setzt die Variable Alarm auf true:
|
1 2 3 4 |
void Wecken() { Alarm = true; } |
Die Variable Weckmelodie bestimmt, welche Melodie gespielt wird:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
oid WeckmelodieSpielen() { switch(Weckmelodie) { case 0: playRtttlBlocking(Lautsprecher, TeDeum); break; case 1: playRtttlBlocking(Lautsprecher, Elise); break; case 2: playRtttlBlocking(Lautsprecher, Ode); break; case 3: playRtttlBlocking(Lautsprecher, Bolero); break; case 4: playRtttlBlocking(Lautsprecher, Fuenfte); break; default: break; } } |
Wecker mit Fernbedienung
Die Fernbedienung bietet die Möglichkeit die Einstellungen im laufenden Betrieb zu ändern, die neuen Einstellungen zu speichern und auf dem LCD anzuzeigen.


| Taste | bewirkt | Speichern im EEPROM | Anzeige im Display |
|---|---|---|---|
| Pfeil oben | eine Stunde vorwärts | ja | ja |
| Pfeil unten | eine Stunde zurück | ja | ja |
| Pfeil rechts | eine Minute weiter | ja | ja |
| Pfeil links | eine Minute zurück | ja | ja |
| OK | Wecker ein- oder ausschalten | ja | ja |
| 1 | Melodie TeDeum | ja | nein |
| 2 | Melodie Elise | ja | nein |
| 3 | Melodie Ode | ja | nein |
| 4 | Melodie Bolero | ja | nein |
| 5 | Melodie Fuenfte | ja | nein |
| 6 | Wecksignal mit Licht ein/aus | ja | ja (L) |
| 7 | Schlummerzeit verringern | ja | S + Anzahl Minuten |
| 8 | Schlummerzeit vergößern | ja | S + Anzahl Minuten |
| 9 | Anzeige der Sekunden ein/aus | nein | ja |
| 0 | Licht ein-/ausschalten | nein | nein |
| * | Hintergrundbeleuchtung einschalten | nein | ja |
| # | Hintergrundbeleuchtung ausschalten | nein | ja |

Benötigte Bauteile
- ⇒Infrarot-Empfänger mit Keyes-Fernbedienung
alternativ eine ⇒andere Fernbedienung - ⇒4-zeiliges LCD mit I²C-Schnittstelle
- ⇒RTC-Modul DS3231
- Lautsprecher
- Leitungsdrähte
Der Schaltplan
(Fahre mit der Maus über das Bild, um die Bezeichnungen der Bauteile zu sehen)
Die weiße LED ist optional.
Das Programm
Einstellungen
Wenn du das Programm zum ersten Mal startest, sind alle Werte im EEPROM auf 0 gesetzt. Mit diesem Programm kannst du die Werte anzeigen:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#include "EEPROM.h" void setup() { Serial.begin(9600); // auf serielle Verbindung warten while (!Serial); delay(1000); for (int i = 0; i < 14; i++) { Serial.println(EEPROM.read(i)); } } void loop() { // bleibt leer, Programm wird nur einmal ausgeführt } |
Mit diesem Programm kannst du alle Werte auf 0 setzen:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
#include "EEPROM.h" void setup() { Serial.begin(9600); // auf serielle Verbindung warten while (!Serial); delay(1000); for (int i = 0; i < 14; i++) { EEPROM.write(i, 0); } // geschriebene Zahlen lesen for (int i = 0; i < 12; i++) { Serial.println(EEPROM.read(i)); } } void loop() { // bleibt leer, Programm wird nur einmal ausgeführt } |
Bibliotheken und Variable

![]() | ![]() |


Wenn Tasten auf der Fernbedienung gedrückt werden, kann es zu kurzen zeitlichen Verzögerungen kommen. Diese werden aber bei der nächsten Abfrage des RTC-Moduls korrigiert.

Solange die Weckmelodie abgespielt wird, bleibt die Sekundenanzeige stehen. Anschließend wird wieder der aktuelle Wert angezeigt.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
#include "RTClib.h" #include "LCDIC2.h" #include "EEPROM.h" #include "IRremote.hpp" #include "PlayRtttl.hpp" // Interruptpin des Infrarot-Empfängers #define EmpfaengerPin 3 #define Lautsprecher 5 #define LED 6 // 4-zeiliges LCD LCDIC2 lcd(0x27, 20, 4); // Name des RTC-Moduls RTC_DS3231 rtc; // Interrupt-Pin -> Alarm auslösen #define AlarmInterruptPin 2 // Alarm beim Start auf false setzen volatile bool Alarm = false; volatile bool IRAktiv = false; // Standardwerte werden teilweise später durch EEPROM überschrieben int StundeWeckzeit = 7; int MinuteWeckzeit = 0; bool SekundenAnzeigen = true; bool WeckerEinAus = true; bool LichtWecker = true; bool LichtEinschalten = true; bool AnzeigeTemperatur = true; int Weckmelodie = 0; int Schlummerzeit = 1; // 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 Elise[] = "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 Ode[] = "Ode: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"; // 4 char Fuenfte[] = "Fuenfte:d=4,o=5,b=180:8f,8f,8f,1c#,8p,8d#,8d#,8d#,1c,8p,8f,8f,8f,8c#,8f#,8f#,8f#,8f,8c#6,8c#6,8c#6,2a#,8p"; |
Der setup-Teil
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
void setup() { // Infrarot-Empfänger starten IrReceiver.begin(EmpfaengerPin); rtc.begin(); // Zeitpunkt des Kompilierens als aktuelle Zeit setzen rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // 32K-Pin am DS3231 deaktivieren rtc.disable32K(); // Pin 2 als Interrupt-Pin pinMode(AlarmInterruptPin, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(EmpfaengerPin), IRAbfragen, FALLING); attachInterrupt(digitalPinToInterrupt(AlarmInterruptPin), Wecken, FALLING); // Alarme löschen und deaktivieren rtc.clearAlarm(1); rtc.clearAlarm(1); rtc.disableAlarm(1); rtc.disableAlarm(2); rtc.writeSqwPinMode(DS3231_OFF); // LCD starten lcd.begin(); // Cursor "verstecken" lcd.setCursor(false); // Einstellungen aus EEPROM lesen StundeWeckzeit = EEPROM.read(0); MinuteWeckzeit = EEPROM.read(2); WeckerEinAus = EEPROM.read(4); Weckmelodie = EEPROM.read(6); SekundenAnzeigen = EEPROM.read(8); Schlummerzeit = EEPROM.read(10); LichtWecker = EEPROM.read(12); // aktuelle Zeit lesen DateTime aktuell = rtc.now(); // Alarm setzen DateTime alarmTime (aktuell.year(), aktuell.month(), aktuell.day(), StundeWeckzeit, MinuteWeckzeit, 0); rtc.setAlarm1(alarmTime, DS3231_A1_Hour); } |
Der loop-Teil
Die Tastencodes beziehen sich auf die Keyes-Fernbedienung. Wenn du eine andere Fernbedienung verwendest, musst du die ⇒Tastencodes anpassen.

Wenn der Druck auf die Taste der Fernbedienung zu schnell hintereinander registriert wird, kannst du in Zeile 15 die Zeit für delay etwas erhöhen.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 |
void loop() { String Stunde, Minute, Weckzeit; int CursorPosition = 0; // aktuelle Zeit lesen DateTime aktuell = rtc.now(); if (IRAktiv && IrReceiver.decode()) { // resume -> nächsten Wert lesen IrReceiver.resume(); if (IrReceiver.decodedIRData.command > 0 && IrReceiver.decodedIRData.command < 95) { delay(200); // Pfeil oben -> Stunden ++ if (IrReceiver.decodedIRData.command == 70) { if (StundeWeckzeit >= 23) StundeWeckzeit = 0; else StundeWeckzeit ++; // Weckzeit Stunde an Position 0 in EEPROM schreiben EEPROM.update(0, StundeWeckzeit); DateTime StartAlarm (aktuell.year(), aktuell.month(), aktuell.day(), StundeWeckzeit, MinuteWeckzeit, 0); rtc.setAlarm1(StartAlarm, DS3231_A1_Hour); } // Pfeil unten Stunden -- if (IrReceiver.decodedIRData.command == 21) { if (StundeWeckzeit == 0) StundeWeckzeit = 23; else StundeWeckzeit --; // Weckzeit Stunde an Position 0 in EEPROM schreiben EEPROM.update(0, StundeWeckzeit); DateTime alarmTime (aktuell.year(), aktuell.month(), aktuell.day(), StundeWeckzeit, MinuteWeckzeit, 0); rtc.setAlarm1(alarmTime, DS3231_A1_Hour); } // Pfeil rechts -> Minuten ++ if (IrReceiver.decodedIRData.command == 67) { if (MinuteWeckzeit >= 59) { MinuteWeckzeit = 0; StundeWeckzeit ++; EEPROM.update(0, StundeWeckzeit); // Weckzeit und Alarm neu setzen DateTime alarmTime (aktuell.year(), aktuell.month(), aktuell.day(), StundeWeckzeit, MinuteWeckzeit, 0); rtc.setAlarm1(alarmTime, DS3231_A1_Hour); } else MinuteWeckzeit ++; // Weckzeit Stunde an Position 0 in EEPROM schreiben EEPROM.update(2, MinuteWeckzeit); // Weckzeit und Alarm neu setzen DateTime alarmTime (aktuell.year(), aktuell.month(), aktuell.day(), StundeWeckzeit, MinuteWeckzeit, 0); rtc.setAlarm1(alarmTime, DS3231_A1_Hour); } // Pfeil links -> Minuten -- if (IrReceiver.decodedIRData.command == 68) { if (MinuteWeckzeit == 0) { MinuteWeckzeit = 59; StundeWeckzeit --; EEPROM.update(0, StundeWeckzeit); // Weckzeit und Alarm neu setzen DateTime alarmTime (aktuell.year(), aktuell.month(), aktuell.day(), StundeWeckzeit, MinuteWeckzeit, 0); rtc.setAlarm1(alarmTime, DS3231_A1_Hour); } else MinuteWeckzeit --; // Weckzeit Stunde an Position 2 in EEPROM schreiben EEPROM.update(2, MinuteWeckzeit); // Weckzeit und Alarm neu setzen DateTime alarmTime (aktuell.year(), aktuell.month(), aktuell.day(), StundeWeckzeit, MinuteWeckzeit, 0); rtc.setAlarm1(alarmTime, DS3231_A1_Hour); } // OK -> Wecker ein/aus if (IrReceiver.decodedIRData.command == 64) { WeckerEinAus = !WeckerEinAus; // Status Wecker an Position 4 in EEPROM schreiben if(WeckerEinAus) EEPROM.update(4, 1); else EEPROM.update(4, 0); } // # -> Hintergrundbeleuchtung aus if (IrReceiver.decodedIRData.command == 74) lcd.setBacklight(false); // * -> Hintergrundbeleuchtung ein if (IrReceiver.decodedIRData.command == 66) lcd.setBacklight(true); // Melodie an Position 6 in EEPROM schreiben // 1 -> Melodie TedDeum if (IrReceiver.decodedIRData.command == 22) { Weckmelodie = 0; EEPROM.update(6, 0); } // 2 -> Melodie FuerElise if (IrReceiver.decodedIRData.command == 25) { Weckmelodie = 1; EEPROM.update(6, 1); } // 3 -> Melodie OdeandieFreude if (IrReceiver.decodedIRData.command == 13) { Weckmelodie = 2; EEPROM.update(6, 2); } // 4 -> Melodie Bolero if (IrReceiver.decodedIRData.command == 12) { Weckmelodie = 3; EEPROM.update(6, 3); } // 5 -> Melodie FuenfteSymphonie if (IrReceiver.decodedIRData.command == 24) { Weckmelodie = 4; EEPROM.update(6, 4); } // 6 -> Wecken mit Licht if (IrReceiver.decodedIRData.command == 94) { LichtWecker = !LichtWecker; if(LichtWecker) EEPROM.update(12, 1); else EEPROM.update(12, 0); } // 7 -> Schlummern - if (IrReceiver.decodedIRData.command == 8) { if (Schlummerzeit > 0) Schlummerzeit --; EEPROM.update(10, Schlummerzeit); lcd.setCursor(17, 3); if (Schlummerzeit > 9) lcd.print("S" + String(Schlummerzeit)); else lcd.print("S " + String(Schlummerzeit)); } // 8 -> Schlummern + if (IrReceiver.decodedIRData.command == 28) { Schlummerzeit ++; EEPROM.update(10, Schlummerzeit); lcd.setCursor(17, 3); if (Schlummerzeit > 9) lcd.print("S" + String(Schlummerzeit)); else lcd.print("S " + String(Schlummerzeit)); } // 0 Licht ein/aus if (IrReceiver.decodedIRData.command == 82) { if (LichtEinschalten) { analogWrite(LED, 200); LichtEinschalten =!LichtEinschalten; } else { analogWrite(LED, 0); LichtEinschalten =!LichtEinschalten; } } // 9 Sekunden anzeigen ein/aus // Status Sekundenzeiger an Position 8 in EEPROM schreiben if (IrReceiver.decodedIRData.command == 90) { SekundenAnzeigen = !SekundenAnzeigen; if(SekundenAnzeigen) EEPROM.update(8, 1); else EEPROM.update(8, 0); } } IRAktiv = false; } // Wochentag, Datum und Zeit anzeigen lcd.setCursor(0, 0); /* Wochentag anzeigen 0 = Sonntag 1 = Montag ... 6 = Samstag */ switch (aktuell.day()) { 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; } lcd.print(" "); 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()) + "."); // Cursorposition verschieben CursorPosition += 3; // Monatsnamen anzeigen lcd.print(" "); switch (aktuell.month()) { case 1: lcd.print("Januar"); CursorPosition += 6; break; case 2: lcd.print("Februar"); CursorPosition += 7; break; case 3: lcd.print("M\341rz"); CursorPosition += 4; break; case 4: lcd.print("April"); CursorPosition += 5; break; case 5: lcd.print("Mai"); CursorPosition += 3; break; case 6: lcd.print("Juni"); CursorPosition += 4; break; case 7: lcd.print("Juli"); CursorPosition += 4; break; case 8: lcd.print("August"); CursorPosition += 6; break; case 9: lcd.print("September"); CursorPosition += 9; break; case 10: lcd.print("Oktober"); CursorPosition += 7; break; case 11: lcd.print("November"); CursorPosition += 8; break; case 12: lcd.print("Dezember"); CursorPosition += 8; break; } lcd.print(" "); lcd.print(String(aktuell.year())); // Jahreszahl + Leerzeichen CursorPosition += 5; // mit Leerzeichen auffüllen for(int i = CursorPosition; i < 19; i++) { lcd.print(" "); } 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())); } else lcd.print(" "); lcd.setCursor(8, 2); 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); lcd.setCursor(15, 3); if(LichtWecker) lcd.print("L"); else lcd.print(" "); lcd.setCursor(17, 3); if(WeckerEinAus) { if (Schlummerzeit > 9) lcd.print("S" + String(Schlummerzeit)); else lcd.print("S " + String(Schlummerzeit)); } else lcd.print(" "); /* Weckzeit erreicht -> Alarm auslösen -> Melodie abspielen -> wenn Variable Lichtwecker gesetzt: LED einschalten -> LCD-Hintergrundbeleuchtung einschalten -> Alarm2 -> Schlummern */ if(WeckerEinAus) { if (Alarm) { if(rtc.alarmFired(1)) { // 255 = maximaler Wert if (LichtWecker) analogWrite(LED, 255); WeckmelodieSpielen(); rtc.clearAlarm(1); analogWrite(LED, 0); rtc.setAlarm2(rtc.now() + TimeSpan(0, 0, Schlummerzeit, 0), DS3231_A2_Minute); IrReceiver.begin(EmpfaengerPin); } // Schlummern if(rtc.alarmFired(2)) { if (LichtWecker) analogWrite(LED, 255); WeckmelodieSpielen(); rtc.clearAlarm(2); analogWrite(LED, 0); IrReceiver.begin(EmpfaengerPin); } } Alarm = false; } } |
Die über den Interruptpin ausgelöste Funktion IRAbfragen() setzt die Variable IRAktiv auf true:
|
1 2 3 4 |
void IRAbfragen() { IRAktiv = true; } |
Die Funktion Wecken setzt die Variable Alarm auf true:
|
1 2 3 4 |
void Wecken() { Alarm = true; } |
Die Variable Weckmelodie bestimmt, welche Melodie gespielt wird:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
void WeckmelodieSpielen() { switch(Weckmelodie) { case 0: playRtttlBlocking(Lautsprecher, TeDeum); break; case 1: playRtttlBlocking(Lautsprecher, Elise); break; case 2: playRtttlBlocking(Lautsprecher, Ode); break; case 3: playRtttlBlocking(Lautsprecher, Bolero); break; case 4: playRtttlBlocking(Lautsprecher, Fuenfte); break; default: break; } } |
Ähnliche Projekte
- Datum und Zeit mit ESP und time.h anzeigen
- Datum und Zeit mit dem NTP-Protokoll anzeigen
- DHT – Messdaten und Zeit auf TFT anzeigen
- Stoppuhr
- Uhr mit TFT 240×240 Pixeln
- Uhrzeit auf LED-Matrix anzeigen
- Zeit mit time.h auf einem TFT anzeigen
- Wecker mit einem RTC-Modul
- Zeit im Seriellen Monitor mit ESP-Mikrocontroller anzeigen
- Datum, Uhrzeit und Temperatur auf einem LCD mit einem RTC-Modul anzeigen
Letzte Aktualisierung:



