// rtc direkt nur mit zwei Buttons stellen // Erster Ansatz - 2021.04.11 #include RTC_DS3231 rtc; const uint8_t TL = 6; // Taster links const uint8_t TR = 7; // Taster rechts DateTime now; void setup() { Serial.begin(115200); Serial.println(F("Start....")); pinMode(TL, INPUT_PULLUP); pinMode(TR, INPUT_PULLUP); delay(1000); // Mal kurz inne halten rtc.begin(); // Ab hier nur zur Einstellung Uhr - kann komplett drin bleiben Nichts auskommentieren! now = rtc.now(); Serial.print(F("RTC-Time: ")); UhrzeitSeriell(); // Ausgabe der aktuellen rtc-Zeit uint32_t merkemillis = millis(); // Merker für Korrektur int32_t ut = now.unixtime(); // Merke aktuelle Zeit rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // stelle Uhr mit Kompilierzeit Serial.print(F("File-Time: ")); UhrzeitSeriell(); // Gebe Zeit aus now = rtc.now(); Serial.print(F("Abweichung Uhr / Kompilierzeit (s): ")); Serial.println(abs(now.unixtime() - ut)); // Ermittle Unterschied der Zeiten Serial.println(F("Kompilierzeit übernehmen? Taste links drücken")); uint32_t lastmillis = millis(); while (millis() - lastmillis < 10000 && digitalRead(TR)) // Warte auf Tastendruck oder Zeitablauf {} if (!digitalRead(TR)) // Taste gedrückt? { Serial.println(F("Uhrzeit gestellt")); // Ja } else // Nein { Serial.println(F("Uhrzeit bleibt")); // dann stelle wieder zurück rtc.adjust(ut); } now = rtc.now(); rtc.adjust(now.unixtime() + ((millis() - merkemillis) / 1000)); // mit Korrektur UhrzeitSeriell(); // Ende Einstellung Uhr } void loop() { Zeit(); } void Zeit() { static bool zeitStellen = false; // Merker static unsigned long zeitAusgabe = millis(); // für regelmäßige Ausgabe der Zeit if (!digitalRead(TL) && !zeitStellen) // Prüfung auf ersten Tatstendruck { Serial.println(F("Löse aus...")); zeitStellen = true; } if (zeitStellen) // verzweige in Uhreinstellmodus { zeitStellen = uhrStellen(zeitStellen); } if (millis() - zeitAusgabe > 10000) // regelmäßige Ausgabe der Uhrzeit { Serial.print("ZEIT: "); UhrzeitSeriell(); zeitAusgabe = millis(); } } bool uhrStellen(bool uebergabe) { enum {anfang, se, mi, st, ta, mo, ja, ende}; // für auswahl stunde/minute usw. static uint8_t auswahl = anfang; // Auswahl für switch static bool TLlaststate = LOW; static uint32_t lastmillis = 0; // const uint32_t startzeit = millis(); // Merker für Korrektur wird später verwendet uint16_t istJahr = now.year(); // Merker für Zeiten uint8_t istMonat = now.month(); uint8_t istTag = now.day(); static uint32_t tik = millis(); // Merker Zeit des letzten Tastendruck if (millis() - lastmillis > 100) { lastmillis = millis(); if (!digitalRead(TL) && !TLlaststate) // Taste gedrückt UND letzter auswahl LOW? { TLlaststate = HIGH; // setze auswahl tik = millis(); } else if (digitalRead(TL) && TLlaststate) // ... wenn nicht UND letzter auswahl gesetzt { TLlaststate = LOW; auswahl++; Serial.print(F("auswahl: ")); Serial.println(auswahl); } if (millis() - tik > 30000) { // Wenn keine Taste gedrückt wurde Serial.println("TimeOut Tastendruck ausgelöst"); auswahl = ende; } switch (auswahl) { case anfang: if (!digitalRead(TR)) { auswahl = se; tik = millis(); } break; case se: // stelle Sekunden if (!digitalRead(TR)) { tik = millis(); Serial.println(F("sek+")); now = rtc.now(); rtc.adjust(now.unixtime() + 1); // addiere now = rtc.now(); // aktuallisiere if (now.second() == 0) // Dann war Überlauf in die Minute { rtc.adjust(now.unixtime() - 60); // komme zurück in alte Minute } UhrzeitSeriell(); } break; case mi: // stelle Minuten if (!digitalRead(TR)) { tik = millis(); Serial.println(F("min+")); now = rtc.now(); rtc.adjust(now.unixtime() + 60); // addiere 1 Minute now = rtc.now(); if (now.minute() == 0) { // Überlauf in nächste Stunde? rtc.adjust(now.unixtime() - 3600); // Komme 1 Std. zurück } UhrzeitSeriell(); } break; case st: // stelle Stunden if (!digitalRead(TR)) { tik = millis(); Serial.println(F("std+")); now = rtc.now(); rtc.adjust(now.unixtime() + 3600); // addiere 1 Stunde now = rtc.now(); if (now.hour() == 0) // Überlauf in den nächsten Tag hinein? { rtc.adjust(now.unixtime() - 86400); // einen Tag zurück } UhrzeitSeriell(); } break; case ta: // stelle Tage if (!digitalRead(TR)) { tik = millis(); Serial.println(F("tag+")); now = rtc.now(); uint8_t lastmonat = now.month(); // Merke aktuellen Monat rtc.adjust(now.unixtime() + 86400); // addiere einen Tag now = rtc.now(); // hole daten if (now.month() != lastmonat) // Monat überlaufen? .... { rtc.adjust(now.unixtime() - 86400); // komme zurück in aktuellen Monat tageKorrektur(1); // .... dann stelle auf Monatsanfang } UhrzeitSeriell(); } break; case mo: // stelle Monate if (!digitalRead(TR)) { tik = millis(); Serial.println(F("mon+")); now = rtc.now(); istJahr = now.year(); // Merke aktuelles Jahr istMonat = now.month(); // Merke aktuellen Monat istTag = now.day(); // Merke aktuellen Tag while (istMonat == now.month()) // Solange der Monat sich nicht geändert hat { rtc.adjust(now.unixtime() + 86400); // addiere einen Tag now = rtc.now(); // hole neue Zeit } if (istJahr != now.year()) // Überlauf Jahreszahl? { rtc.adjust(now.unixtime() - 31536000);// dann ziehe 365 Tage ab now = rtc.now(); // aktuallisieren while (istJahr != now.year()) // bis wieder das Jahr stimmt { rtc.adjust(now.unixtime() - 86400); // ziehe Tag ab now = rtc.now(); } monateKorrektur(1); // Fange mit Monat 1 an } tageKorrektur(istTag); // Tage wieder setzen UhrzeitSeriell(); } break; case ja: // stelle Jahre if (!digitalRead(TR)) { tik = millis(); Serial.println(F("jahr+")); now = rtc.now(); istJahr = now.year(); // Merke Jahr istMonat = now.month(); istTag = now.day(); rtc.adjust(now.unixtime() + 31536000); // addiere 365 Tage now = rtc.now(); while (istJahr == now.year()) // solange Jahr noch nicht geändert... { rtc.adjust(now.unixtime() + 86400); // ...addiere einen Tag now = rtc.now(); } if (now.year() > 2030) // Überlauf? { rtc.adjust(now.unixtime() - 315360000);// hole zurück ins Jahr 2021 now = rtc.now(); } monateKorrektur(istMonat); // Monat auf merker setzen tageKorrektur(istTag); // Tag auch now = rtc.now(); UhrzeitSeriell(); } break; case ende: uebergabe = false; // Einstellung abgeschlossen auswahl = anfang; break; default: Serial.println(F("status nicht gefunden - ENDE")); auswahl = ende; break; } // Ende switch } return uebergabe; } void monateKorrektur(uint8_t sollMonat) { now = rtc.now(); while (sollMonat != now.month()) // solange gemerkter Monat nicht aktueller Monat { if (now.month() < sollMonat) // ist aktuell kleiner als germerkt? { rtc.adjust(now.unixtime() + 86400);// addiere einen Tag } else { rtc.adjust(now.unixtime() - 86400);// sonst ziehe eine Tag ab } now = rtc.now(); } } void tageKorrektur(uint8_t sollTag) { now = rtc.now(); while (sollTag != now.day()) // solange gemerkter Tag nicht aktueller Tag { if (now.day() < sollTag) // ist aktuell kleiner als germerkt? { rtc.adjust(now.unixtime() + 86400);// addiere einen Tag } else { rtc.adjust(now.unixtime() - 86400);// sonst ziehe eine Tag ab } now = rtc.now(); } } void UhrzeitSeriell() { now = rtc.now(); Serial.print(now.day(), DEC); Serial.print('.'); Serial.print(now.month(), DEC); Serial.print('.'); Serial.print(now.year(), DEC); Serial.print(" "); Serial.print(now.hour(), DEC); Serial.print(':'); Serial.print(now.minute(), DEC); Serial.print(':'); Serial.print(now.second(), DEC); Serial.println(); }