Aus dem Thread für die Autorennbahn ab Serielle Datenstring vom Computer im Adruino Mega einlesen und aufteilen - #122 by Benziner - Deutsch - Arduino Forum war die Vorgabe eine RTC mit zwei Tasten zu bedienen. Das sowas funktioniert ist nicht das Problem.
Ich will mit meinem Code erreichen:
- wird nur mit zwei Tasten bedient
- direkt gestellt ohne Zwischenvariablen.
-- Damit wird auch immer das richtige Datum gesetzt - Zusätzlich nicht mehr im SetupCode mal das setzen der RTC einbinden und mal nicht
Verwende die RTCLib von Adafruit. Die übernimmt u.a. die komplette Kommunikation (nicht nur für DS3231)
Herausforderung ist:
- das Datum soll auch gesetzt werden
- das Setzen soll beim Überlauf wieder bei 0 (Zeit) oder 1 (Datum) beginnen und die Folgezahl nicht verändert werden
Beispiel: Beim Überlauf von Stunde 23 auf Stunde 0 würde der Tag, beim Monat 12 auf Monat 1 würde Jahr 1 hochgezählt usw.
Adafruit hat in der Lib eine Funktion TimeSpan, aber die geht auch nur bis einen Tag. Beim Monat sind es aber zwischen 28 bis 31 Tage...
Was der Code machen soll:
Im Setup vergleiche RTC-Zeit mit der Zeit des Kompilat und biete an die Zeit zu setzen.
Nach 10 Sekunden gehe automatisch mit der bisherigen RTC weiter.
Im loop: Wird die Taste zur Einstellung der Uhr gedrückt, verzweige in den Einstellmodus
Im Einstellmodus wird mit einer Taste ausgewählt, welcher Teil der Uhr gestellt wird. Mit der anderen Taste wird der Wert verändert. Nur aufzählend. Kommt es zum Überlauf fange mit dem ersten Wert an und setze den Überlauf zurück.
Wird das Jahr zuweit gestellt, kommt es auf 2021 zurück.
Wenn 30 Sekunden keine Taste gedrückt wird, verlasse den Einstellmodus automatisch.
Gestellt wird nur mit der Größe "Sekunden" (rtc.adjust(Zeit in unixtime))
Ich benötige nur merkende Variablen für den akuellen Zustand vor der Verstellung.
Der Code kommt ohne delay() aus.
Achtung: Ich formatiere anders als viele von Euch. Dadurch sieht das nach sehr vielen Zeilen aus.
Ist aber nicht so schlimm und ich hoffe ich habe es ausreichend kommentiert.
Ist noch nicht fertig, aber vielleicht schaut mal jemand drüber, ob ich mich an irgendeiner Stelle sehr verhauen habe.
Code hier ohne Kommentare wegen der Zeichenbegrenzung. Das Post musste auf 8600 Zeichen an Stelle 9000 gekürzt werden - kommentiert als txt-Anhang
// rtc direkt nur mit zwei Buttons stellen
// Erster Ansatz-2021.04.11
#include <RTClib.h>
RTC_DS3231 rtc;
const uint8_t TL=6;
const uint8_t TR=7;
DateTime now;
void setup() {
Serial.begin(115200);
Serial.println(F("Start...."));
pinMode(TL, INPUT_PULLUP);
pinMode(TR, INPUT_PULLUP);
delay(1000);
rtc.begin();
now=rtc.now();
Serial.print(F("RTC-Time: "));
UhrzeitSeriell();
uint32_t merkemillis=millis();
int32_t ut=now.unixtime();
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
Serial.print(F("File-Time: "));
UhrzeitSeriell();
now=rtc.now();
Serial.print(F("Abweichung Uhr / Kompilierzeit (s): "));
Serial.println(abs(now.unixtime()-ut));
Serial.println(F("Kompilierzeit übernehmen? Taste links drücken"));
uint32_t lastmillis=millis();
while (millis()-lastmillis<10000 && digitalRead(TR)){}
if (!digitalRead(TR)){
Serial.println(F("Uhrzeit gestellt"));
}
else{
Serial.println(F("Uhrzeit bleibt"));
rtc.adjust(ut);
}
now=rtc.now();
rtc.adjust(now.unixtime()+((millis()-merkemillis) / 1000));
UhrzeitSeriell();
}
void loop(){
Zeit();
}
void Zeit(){
static bool zeitStellen=false;
static unsigned long zeitAusgabe=millis();
if (!digitalRead(TL) && !zeitStellen){
Serial.println(F("Löse aus..."));
zeitStellen=true;
}
if (zeitStellen){
zeitStellen=uhrStellen(zeitStellen);
}
if (millis()-zeitAusgabe>10000){
Serial.print("ZEIT: ");
UhrzeitSeriell();
zeitAusgabe=millis();
}
}
bool uhrStellen(bool uebergabe){
enum {anfang, se, mi, st, ta, mo, ja, ende};
static uint8_t auswahl=anfang;
static bool TLlaststate=LOW;
static uint32_t lastmillis=0;
// const uint32_t startzeit=millis();
uint16_t istJahr=now.year();
uint8_t istMonat=now.month();
uint8_t istTag=now.day();
static uint32_t tik=millis();
if (millis()-lastmillis>100){
lastmillis=millis();
if (!digitalRead(TL) && !TLlaststate){
TLlaststate=HIGH;
tik=millis();
}
else if (digitalRead(TL) && TLlaststate){
TLlaststate=LOW;
auswahl++;
Serial.print(F("auswahl: "));
Serial.println(auswahl);
}
if (millis()-tik>30000){
Serial.println("TimeOut Tastendruck ausgelöst");
auswahl=ende;
}
switch (auswahl){
case anfang:
if (!digitalRead(TR)){
auswahl=se;
tik=millis();
}
break;
case se:
if (!digitalRead(TR)){
tik=millis();
Serial.println(F("sek+"));
now=rtc.now();
rtc.adjust(now.unixtime()+1);
now=rtc.now();
if (now.second() == 0){
rtc.adjust(now.unixtime()-60);
}
UhrzeitSeriell();
}
break;
case mi:
if (!digitalRead(TR)){
tik=millis();
Serial.println(F("min+"));
now=rtc.now();
rtc.adjust(now.unixtime()+60);
now=rtc.now();
if (now.minute() == 0){
rtc.adjust(now.unixtime()-3600);
}
UhrzeitSeriell();
}
break;
case st:
if (!digitalRead(TR)){
tik=millis();
Serial.println(F("std+"));
now=rtc.now();
rtc.adjust(now.unixtime()+3600);
now=rtc.now();
if (now.hour() == 0){
rtc.adjust(now.unixtime()-86400);
}
UhrzeitSeriell();
}
break;
case ta:
if (!digitalRead(TR)){
tik=millis();
Serial.println(F("tag+"));
now=rtc.now();
uint8_t lastmonat=now.month();
rtc.adjust(now.unixtime()+86400);
now=rtc.now();
if (now.month() != lastmonat){
rtc.adjust(now.unixtime()-86400);
tageKorrektur(1);
}
UhrzeitSeriell();
}
break;
case mo:
if (!digitalRead(TR)){
tik=millis();
Serial.println(F("mon+"));
now=rtc.now();
istJahr=now.year();
istMonat=now.month();
istTag=now.day();
while (istMonat == now.month()){
rtc.adjust(now.unixtime()+86400);
now=rtc.now();
}
if (istJahr != now.year()){
rtc.adjust(now.unixtime()-31536000);
now=rtc.now();
while (istJahr != now.year()){
rtc.adjust(now.unixtime()-86400);
now=rtc.now();
}
monateKorrektur(1);
}
tageKorrektur(istTag);
UhrzeitSeriell();
}
break;
case ja:
if (!digitalRead(TR)){
tik=millis();
Serial.println(F("jahr+"));
now=rtc.now();
istJahr=now.year();
istMonat=now.month();
istTag=now.day();
rtc.adjust(now.unixtime()+31536000);
now=rtc.now();
while (istJahr == now.year()){
rtc.adjust(now.unixtime()+86400);
now=rtc.now();
}
if (now.year()>2030){
rtc.adjust(now.unixtime()-315360000);
now=rtc.now();
}
monateKorrektur(istMonat);
tageKorrektur(istTag);
now=rtc.now();
UhrzeitSeriell();
}
break;
case ende:
uebergabe=false;
auswahl=anfang;
break;
default:
Serial.println(F("status nicht gefunden-ENDE"));
auswahl=ende;
break;
}
}
return uebergabe;
}
void monateKorrektur(uint8_t sollMonat){
now=rtc.now();
while (sollMonat != now.month()){
if (now.month()<sollMonat){
rtc.adjust(now.unixtime()+86400);
}
else{
rtc.adjust(now.unixtime()-86400);
}
now=rtc.now();
}
}
void tageKorrektur(uint8_t sollTag){
now=rtc.now();
while (sollTag != now.day()){
if (now.day()<sollTag){
rtc.adjust(now.unixtime()+86400);
}
else{
rtc.adjust(now.unixtime()-86400);
}
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();
}
RTC_set_202120411.txt (9.61 KB)