[erledigt] Alle 5min eine Aktion mit DS3231 - wie?

Hallo,

ich stehe gerade etwas auf dem Schlauch bei meinem Temperaturlogger, und suche einen Lösungsansatz.
Ich möchte gern alle 5 Minuten, getriggert durch die RTC bei Minute 0, 5, 10, 15, etc. mehrere Werte in ein Array
schreiben, und nach 1 Stunde dann auf eine SD-Card schieben. Mit alle 5 Minuten (interval) habe ich kein Problem, aber bei RTC-Minute 0, 5, 10, 15, etc. schon. Ich benutze die DS3231.h

Evtl. schiebt jemand den Wald etwas beiseite, damit ich die Bäume besser sehe.

Gruß André

Da es mehrere DS3231.h gibt, musst DU uns schon den Link zu der Lib geben, die Du verwendest.

Gruß Tommy

Hallo Tommy,

es ist diese hier: GitHub - NorthernWidget/DS3231: Communicates between Arduino-programmed AVR and Maxim DS3231 RTC: splice of Ayars' (http://hacks.ayars.org/2011/04/ds3231-real-time-clock.html) and Jeelabs/Ladyada's (https://github.com/adafruit/RTClib) libraries

Gruß André

RTC_minute%5 würde ich probieren.

mfG Thorsten

Du hast in Deiner Beschreibung 2 Aussagen vermischt:

a) aller 5 Minuten --> Anfang beliebig
b) zu 0, 5, 10, ... --> fester Bezug

Was ist gültig?

Gruß Tommy

Hallo Tommy,

ich meine b) und hatte gehofft, daß das mit "getriggert durch die RTC" eindeutig ist.
Was ich inzwischen probiert habe:
Serial.println(clock.dateFormat("i", dt));
zeigt mir die Minute an, scheint aber String zu sein, und keine Zahl?

Gruß André

Hast Du Dir mal Beispiele Deiner Lib angeschaut? z.B. das hier. (.pde in .ino umbenennen).
(ungetestet)

void loop() {
static int8_t altMinute= -1;
DateTime now = RTC.now();
byte min = now.minute();
  if (minute % 5 == 0 && (min > altMinute || min == 0)) {  // modulo-Division
    altMinute = min;
    // hier machst Du irgendwas.
  }
}

Da eine Minute ziemlich lang ist, musst Du Dir merken, dass Du schon in dieser 5 Minutenzeit etwas gemacht hast.

Gruß Tommy

Hallo,

wie Du an die aktuelle Minutenwerte dran kommst weist Du ? Es gibt da sicher mehrere Möglichkeiten ich hab sowas mal für feste Uhrzeiten alle zwei Sunden gemacht. Mit Millis ging das nicht lange gut, da ist das natürlich weggedriftet. Also 2:00 4:00 6:00 ....usw.

Ansatz : zu bestimmten Zeiten was tun und merken ob Du es schon getan hast. Die Zeiten können minuten eines ganzen Tages sein, also TagesMinute= Stunde*60+Minute, so wie bei mir. Bei Dir reich aber nur minuten, weil es sich ja jede Stunde wiederholen soll.

ein Bool Array "isdone" mit 12 Elementen als Status.
ein Byte Index als Zeiger auf aktuelle Element das Array´s
ein Byte Array Sollzeit[12]( 0,5,10,... 55 ) als Vorgabe der Minuten wann das Ereignis eintreten soll

Wenn Du die Minuten auf = abfragst ergibt sich ein Zeitfenster von 1 minute in der Du das Ereigniss verarbeiten kannst. Wenn Minuten 0 sind setzt Du zunächst alle wieder auf 0 und den Index ebenfalls, damit das von vorne beginnen kann. Im Prinziep kannst Du auch auf >= abfragen.

die Abfrage ist dann in etwa so

wenn RTCminute = Sollzeit[index] und status [index] = false
status[index]=true
index = index +1

hier was machen

Im Setup musst Du so eine Abfrage dann allerdings einmal für alle Werte des Arryas in einer Schleife machen damit Du die die "isdone" Status Werte die innerhalb der aktuellen Stunde bereits gesetzt sein müssen schon mal auf true setzt. Sozusagen als Anfangswert. Sonst werden Dir beim Staten unter Umständen gleich 12 Ereignisse gleichzeitig bearbeitet.

Gruß Heinz

Hallo,

@ Tommy, bei dem verlinkten now.pde (.ino) stolpert er schon über RTClib RTC; mit dem Fehler 'RTClib' does not name a type

Bei Deinem Sketch bleibe ich an >> DateTime now = RTC.now(); << hängen, mit 'DateTime' was not declared in this scope, nach meinem Verständnis sollte das doch über die Lib deklariert sein, wenn sie eingebunden ist?!
Auf jeden Fall schon mal Danke für die if-Zeile, darüber hatte ich mir auch schon Gedanken gemacht, wie ich nur einmal in der betreffenden Minute meine Daten einsammle. Ich muss nur die Minuten %5 zu fassen bekommen, wo ich noch nicht weiter bin.

@ Heinz, ganz lieben Dank für Deine Ausführungen!
Ich habe mich am WE erstmal mit Arrays beschäftigt, und mir ein 12 x 5 int Array aufgebaut, welches ich sauber befüllen, auf 0 setzen kann und neu beschreiben kann. Aber da habe ich es über einen einfachen Interval getestet, nicht über eine RTC getriggert.

Evtl. geht es über eine andere RTC-Lib besser, dann würde ich auch eine andere versuchen?

Gruß André

Dann benutzt Du entweder eine andere Lib oder die ist nicht ordentlich installiert.

Gruß Tommy

Hallo Tommy,

laut Bibliotheksverwalter ist es diese, eine weiter DS3231 ist nicht installiert.
Ich kann die Zeit ja auch so abfragen: Serial.print(clock.dateFormat("d. F Y H:i:s", dt));
Nur bekomme ich nicht meine 5 Minuten-Abfrage gebacken.

Aber lass für heute erstmal gut sein, ich melde mich morgen wieder.

Schönen Abend noch,
Gruß André

Die von Dir angegebene Lib hat keine Methode "dateFormat". Also benutzt Du eine andere.

Gruß Tommy

Hallo Tommy,

tut mir aufrichtig leid, die Files im Ordner sagen tatsächlich was anderes als die Bibliotheksverwaltung.

Damit habe ich mich natürlich auch selbst bestens verwirrt. :-[

Gruß André

Das passiert.

Schau Dir das Beispiel an.

Da ist es keine Methode, sondern ein Wert.

Gruß Tommy

Hi

Was mir nicht ganz klar ist: Hat der Arduino noch was Anderes zu tun, als im 5-Minuten-Interval Daten zwischenzuspeichern?
Wenn NICHT, kannst Du den Arduino auch schlafen schicken und der RTC einen Alarm in 5 Minuten einstellen - der entsprechende Pin der RTC muß dann über einen Interrupt erfasst werden, damit der Arduino wieder wach wird.

Wenn der Arduino die ganze Zeit noch andere Dinge zu erledigen hat, wird Es wohl egal sein, ob man die Uhrzeit pollt, oder in jedem loop()-Durchlauf auf den Alarm-Pin schaut - im Gegenteil: Beim Alarm muß man Diesen ja auch jedes Mal neu einstellen.

MfG

Hallo,

@ Tommy, dank Deiner Hilfe habe ich es hinbekommen, nur fehlte noch die letzte Bedingung in der IF-Zeile, sonst wäre die Bedingung bei Minute = 0 für die ganze Minute gültig. Ich hätte es vermutlich komplizierter über einen Counter gelöst.

// snip ///////////////////////////////////////////////////////

dt = clock.getDateTime();
static int8_t altMinute = -1;
byte Minute = (dt.minute);
if (Minute % 5 == 0 && (Minute > altMinute || Minute == 0 && altMinute != 0))
{
  altMinute = Minute;
  // hier machst Du irgendwas.
  Serial.println(F(">>>>>> Bitte einmal! <<<<<"));
}
// snip ///////////////////////////////////////////////////////

@ postmaster, das Ding soll im Netzbetrieb (akkugpuffert) laufen, und mir verschiedene Temperaturen laufend anzeigen, im 5 Minutentakt durch die RTC mitloggen und nach 1 Stunde das Array auf die SD-Karte schieben.

Mal schauen wie weit ich da mit einem Nano komme, da die SD-Lib einen sehr kräftigen Schluck vom RAM möchte, da ist mein 1h-Array mit 120 Bytes Kinderkram dagegen.

Gruß André

Spontan aus dem Bauch raus: Warum schreibst Du nicht alle fünf Minuten auf die SD-Karte?

Ich brauche den Grund nicht zu wissen, aber sollte es keinen geben, könntest Du nochmal drüber nachdenken.

SpaghettiCode:
Hallo,

@ Tommy, dank Deiner Hilfe habe ich es hinbekommen, nur fehlte noch die letzte Bedingung in der IF-Zeile, sonst wäre die Bedingung bei Minute = 0 für die ganze Minute gültig. Ich hätte es vermutlich komplizierter über einen Counter gelöst.

Deshalb hatte ich altMinute auch mit -1 initialisiert.

Gruß Tommy

... nach 1 Stunde das Array auf die SD-Karte schieben.

Mal schauen wie weit ich da mit einem Nano komme, da die SD-Lib einen sehr kräftigen Schluck vom RAM möchte, da ist mein 1h-Array mit 120 Bytes Kinderkram dagegen.

Eine SD - Karte wird effektiv sowieso nur in ganzen 512 Byte großen Blöcken beschrieben (deswegen braucht die SD Lib so viel RAM). Wenn es dir nicht drauf ankommt, dass du zwischendurch im laufenden Betrieb die Karte rausnehmen möchtest, kannst du dir also den Aufwand für das 1h-Array sparen und stattdessen jede Sunde mal myFile.flush() aufrufen...

Hallo

Das mit dem modolo ist natürlich schon geschickt gelöst , da ist mein Ansatz dann doch zu verdreht gedacht.

if (Minute % 5 == 0 && (Minute > altMinute || Minute == 0 && altMinute != 0))

Heinz