Dealing with RTC DS3231 date and time am Arduino

Wenn eine RTC am Arduino steckt -> wie kommt dann die aktuelle Zeit da drauf?
Hier meine Lösung:

#include <DS3232RTC.h> // https://github.com/JChristensen/DS3232RTC
#include <TimeLib.h>       // https://github.com/PaulStoffregen/Time
#include "Timezone.h"      //by Jack Christensen, not included in the Arduino IDE !!!


//uncomment to set the RTC time to compiler start time after sketch upload
#define SET_TIME


//Timezone
//Central European Time (Frankfurt, Paris, Berlin)
TimeChangeRule CEST = { "CEST", Last, So, Mrz, 2, 120 };     //Central European Summer Time
TimeChangeRule CET = { "CET ", Last, So, Okt, 3, 60 };       //Central European Standard Time
Timezone TZ(CEST, CET);
TimeChangeRule *tcr;        //pointer to the time change rule, use to get the TZ abbrev


#ifdef SET_TIME
bool getTime(const char *str, tmElements_t &tm) {
  uint8_t Hour, Min, Sec;
  if (sscanf(str, "%d:%d:%d", &Hour, &Min, &Sec) != 3) {
    return false;
  }
  tm.Hour = Hour;
  tm.Minute = Min;
  tm.Second = Sec;
  return true;
}

bool getDate(const char *str, tmElements_t &tm) {
  const char *monthName[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
  char Month[12];
  int Day, Year;
  uint8_t monthIndex;

  if (sscanf(str, "%s %d %d", Month, &Day, &Year) != 3) {
    return false;
  }
  for (monthIndex = 0; monthIndex < 12; monthIndex++) {
    if (strcmp(Month, monthName[monthIndex]) == 0) break;
  }
  if (monthIndex >= 12) return false;
  tm.Day = Day;
  tm.Month = monthIndex + 1;
  tm.Year = CalendarYrToTm(Year);
  return true;
}

void print_time(time_t t, bool line_break) {
  char buf[24];
  sprintf(buf, "%s %02d.%02d.%d %02d:%02d:%02d", dayShortStr(weekday(t)), day(t), month(t), year(t), hour(t), minute(t), second(t));
  Serial.print(String(buf));
  if (line_break) {
    Serial.println();
  }
}

#endif

void setup() {
#ifdef SET_TIME
  tmElements_t tm;
  // get the date and time the compiler was run
  if (getDate(__DATE__, tm) && getTime(__TIME__, tm)) {

    Serial.print(F("Compiler start time as Strings: Time="));
    Serial.print(__TIME__);
    Serial.print(F(", Date="));
    Serial.println(__DATE__);

    Serial.print(F("Compiler start time from system: "));
    print_time(makeTime(tm), true);

    time_t compile_time = TZ.toUTC(makeTime(tm));
    Serial.print(F("Compiler start time in UTC: "));
    print_time(compile_time, true);
    
    //add xxx sec's to compiler start time

    //muss ausprobiert werden, ob nach dem Upload die RTC Zeit in UTC genau übereinstimmt
    compile_time += 28;

    // and configure the RTC with this info
    RTC.set(compile_time);
    Serial.println(F("MakeTime was set"));

    time_t current_time = TZ.toLocal(RTC.get(), &tcr);
    Serial.print(F("Current Middle European Time: "));
    print_time(current_time, true);

    setTime(current_time);
    
    if (timeStatus() != timeSet)
      Serial.println(F("Unable to sync with the RTC"));
    else
      Serial.println(F("RTC has set the system time"));
  }
#endif

  setSyncProvider(RTC.get);   // the function to get the time from the RTC

  
  //do other stuff
  ...
}

void loop() {
  //get time in local Timezone	
  time_t local_time = TZ.toLocal(RTC.get(), &tcr);

  //wenn  setSyncProvider(RTC.get) gesetzt ist, geht auch
  time_t local_time = TZ.toLocal(now(), &tcr);


  //do other stuff
  ...

}

Hat jemand Verbesserungsvorschläge?

Du könntest Dir auch die Zeit per serieller Schnittstelle schicken und dann die Uhr stellen. Dadurch kannst Du sie jederzeit stellen.
z.B.:

"Set:08:09:00:01:12:2020"

Gruß Tommy

Haut in meinem Fall nicht hin, weil der Arduino immer pennt, bis er von der RTC über einen Interrupt PIN geweckt wird.
Ich könnte aber einen Taster einsetzen, der den Sleep Modus verhindert.
Taste drücken->Arduino geht in "Programmiermodus" ->eine LED zeigt das an.
Zeit seriell übertragen
Taste erneut drücken ->Arduino geht zu seinen Aufgaben zurück ->LED ist wieder aus.

Ja, könnte man auch tun.

Gruß Tommy

Oder man übergibt die Zeit per Sketch. Einfach über__TIME__ DATE vom PC holen und überschreibt dann sofort den Sketch mit dem endgültigen.
Grüße Uwe

uwefed:
Oder man übergibt die Zeit per Sketch.

Macht er ja.
Zusätzlich noch mit Berichtigung, da mit DATE TIME die Compilezeit genommen wird.