Jump to content

[RTC-Bricklet] Callbacks?


Nic

Recommended Posts

Ein wenig seltsam ist das mit dem RTC, ich finde nicht eine einzige Callback-Fkt.! Ich möchte in meinen Anwendungen eig. schon die aktuelle Zeit über einen Callb. erhalten können, ohne Umweg über einen zusätzlichen Timer und Polling!

 

Also ein simpler CB/Listener wie z.B. http://www.tinkerforge.com/de/doc/Software/Bricklets/GPS_Bricklet_Java.html#BrickletGPS.DateTimeListener sollte schon drin sein.

 

Link zu diesem Kommentar
Share on other sites

Einen Date/Time Callback nach GPS Vorbild können wir einbauen. Dessen Periode würde dann genau wie beim GPS Bricklet mit der internen Uhr des Bricks gemessen.

 

Ein generischer Timer ist das schon schwieriger. Der IC auf dem Bricklet bietet aber eine Alarmfunktion bei der man einstellen kann zu welchem Datum und Uhrzeit sie ausgelöst werden soll:

 

set_alarm(int8_t month, int8_t day, int8_t hour, int8_t minute, int8_t second)

 

Das funktioniert dann nach dem Muster von cron unter Linux:

 

set_alarm(4, 2, 20, 15, 0)

 

Diese setzt einen Alarm für 20:15 Uhr am 2. April. Der Alarm würde dann per Callback mitgeteilt.

 

Wäre das was? Oder was stellt ihr euch da vor?

Link zu diesem Kommentar
Share on other sites

Dessen Periode würde dann genau wie beim GPS Bricklet mit der internen Uhr des Bricks gemessen.
Ja erstmal als "Standard" wie beim GPS, z.b. über SetDateTimeCallbackPeriod würde man das Interval in ms eintragen zu dem der Callback periodisch auslöst. Damit könnte man z.B. als Photograph Intervallaufnahmen steuern.

 

SetAlarm wäre hilfreich den RTC als Schaltuhr für Zeitsteuerung zu verwenden.

Ich würde dann aber auch noch den relativen Bezug ermöglichen, also z.B. wiederholend jeden Samstag um 15.36 Uhr. Natürlich vorausgesetzt dass der IC das hergibt.

 

 

Link zu diesem Kommentar
Share on other sites

Der periodische Callback des RTC Bricklets wäre nicht besser/genauer als jeder andere Callback. Das GPS Bricklet nutzt für die Taktung der Callbacks nicht die GPS Zeit und das RTC Bricklet würde dafür nicht die RTC Zeit benutzten. Dafür müsste in jedem Tick I2C kommuniziert werden, was nicht möglich ist.

 

Oder willst du darauf hinaus, dass du den Date/Time Callback mit einer Periode von z.B. 1 Sekunde einstellt um dann z.B. Zeitspannen im Minutenbereich zu messen. Du also einfach jede Sekunde Prüfen kannst ob deine Minute schon rum ist. Das hat natürlich dann den Nachteil, dass du da lokal Ungenauigkeit reinbekommst, weil nicht definiert ist wann die Zeit den abgelesen wird.

 

Für solche Kurzzeitmessungen ist meistens ein lokaler Timer am besten, fürchte ich. Jede Programmiersprache bringt dafür irgendwas mit, das für diesen Zweck besser funktionieren wird als das Real-Time Clock Bricklet.

 

Es kommst aber auch darauf an was du machen willst. Wenn du über 100 Minuten hinweg insgesamt 100 Bilder aufnehmen willst, dann willst du möglicherweise keinen sich aufsummierenden Fehler den ein einfacher Intervalltimer hätte.

 

Das Real-Time Clock Bricklet kommt dann zum tragen, wenn es um längere Zeiträume geht und keine andere Zeitquelle verfügbar ist. Zum Beispiel ein RED Brick oder ein Raspberry Pi ohne Internetanbindung. Beide haben keine eigene Real-Time Clock und halten ihre Zeit über den Prozessortakt. In diesen Fällen kann das Real-Time Clock Bricklet als bessere Uhr genutzt werden.

 

Mit der möglichen set_alarm Funktion

 

set_alarm(int8_t month, int8_t day, int8_t hour, int8_t minute, int8_t second)

 

kannst du dir einen wiederholend Alarm für jeden Samstag um 15:36 Uhr bauen. Der nächste Samstag ist der 2. April, also den Alarm auf "2. April 15:36 Uhr" stellen

 

set_alarm(4, 2, 15, 36, 0)

 

Sobald der Alarm ausgelöst wurde kannst du ihn auf den folgende Samsatg, den 9. April einstellen

 

set_alarm(4, 9, 15, 36, 0)

 

usw.

Link zu diesem Kommentar
Share on other sites

Stirnrunzel  :o

Der periodische Callback des RTC Bricklets wäre nicht besser/genauer als jeder andere Callback.
Es gibt im RTC überhaupt noch keinen Callback! Es reicht aber zumind. einen Callback zu haben wie z.B. im GPS OnDateTime etc. Alles andere vergiss was ich geschrieben habe.
In diesen Fällen kann das Real-Time Clock Bricklet als bessere Uhr genutzt werden.
Und genau dafür will ich es nehmen, für einen 20 Euro teuren Bricklet kann ich erwarten, dass da einfache  Callbacks drin sind, mit dem ich mir z.B. einfach die aktuelle Uhrzeit in die Anwendung triggere. Wenn der poppelige IO4 einen Timer-gesteuerten Monoflop hergibt verstehe ich nicht warum dass im RTC ein OnDateTime nicht machbar wäre.

Sobald der Alarm ausgelöst wurde kannst du ihn auf den folgende Samsatg, den 9. April einstellen
Gut setzt aber woraus das ich noch eine eigene Routine schreiben muss um den richtigen Tag zu berechnen. Aber egal ein einfaches setAlarm tut es auch.
Link zu diesem Kommentar
Share on other sites

Nic, es geht mir nicht darum dem Nutzer Funktionalität vorenthaltenen, oder das etwas nicht machbar wäre. Es geht mir darum zu verstehen warum du diesen Callback verwenden willst, was da der Nutzen für dich ist, warum das besser/einfacher ist als ein Timer aus der Stdlib deiner Programmiersprache. Damit ich da am Ende die beste Lösung für heraus kristallisieren kann.

 

Also, die nächste Softwareversion für das RTC Bricklet wird einen Date/Time Callback wie das GPS Bricklet bekommen und eine set/get_alarm Funktion mit Alarm Callback. Vielleicht bekomme ich beim Alarm auch noch ein Feld für den Wochentag unter. Das gibt der IC zwar nicht direkt her, aber das könnte vielleicht durch Kombination zweier Funktionen des ICs möglich sein, muss ich testen.

Link zu diesem Kommentar
Share on other sites

Ok, prima und danke. Und meine flüchtigen Gedanken musst du nicht immer so genau unter die Lupe nehmen ;)

set_alarm: Ich würde empfehlen erstmal nur ein simplen Callback(int8_t month, int8_t day, int8_t hour, int8_t minute, int8_t second) implementieren solange nicht hier aus der Community noch weiteres Feedback/Wünsche kommen.

Link zu diesem Kommentar
Share on other sites

Also, ich bin jetzt mit der ersten Implementierung durch. Es wird folgendes neu geben:

 

- Date/Time und Timestamp Callback für die beiden Getter entsprechend dem Muster des GPS Bricklets:

 

set_date_time_callback_period(uint32 period)
get_date_time_callback_period() -> uint32 period

CALLBACK_DATE_TIME -> uint16 year, uint8 month, uint8 day, uint8 hour, uint8 minute, uint8 second, uint8 centisecond, uint8 weekday

set_timestamp_callback_period(uint32 period)
get_timestamp_callback_period() -> uint32 period

CALLBACK_TIMESTAMP -> int64 timestamp

 

- Alarmfunktion nach cron Vorbild:

 

set_alarm(int8 month, int8 day, int8 hour, int8 minute, int8 second, int8 weekday)
get_alarm() -> int8 month, int8 day, int8 hour, int8 minute, int8 second, int8 weekday

CALLBACK_ALARM -> uint16 year, uint8 month, uint8 day, uint8 hour, uint8 minute, uint8 second, uint8 centisecond, uint8 weekday, int64 timestamp

 

Damit kann man jetzt z.B. einen wiederholenden Alarm für jeden Samstag um 15:36 Uhr einstellen:

 

set_alarm(-1, -1, 15, 36, -1, 6)

 

Die -1 für Monat, Tag und Sekunde besagt, dass Monat, Tag und Sekunde egal sind. Der Alarm Callback wird ausgelöst, wenn sich an einem Samstag (6) die Uhrzeit von 15:35 Uhr auf 15:36 Uhr ändert.

 

Der Alarm Callback gibt dann Datum und Uhrzeit (plus Zeitstempel) zurück zu dem der Alarm ausgelöst wurde.

 

Um den Alarm zu deaktivieren ruft man set_alarm() mit -1 für alles auf:

 

set_alarm(-1, -1, -1, -1, -1, -1)

 

Entspricht das den Vorstellungen? Jetzt es ist noch früh genug da noch Änderungen zu machen.

Link zu diesem Kommentar
Share on other sites

Ich würde generell eine 0 statt -1 setzen um etwas abzuschalten, so haben wir das bisher auch bei Callbacks gemacht. Und dann eine public Konstante in die API ev. hinzufügen die genausowas beschreibt FLAG_NOOP(=0) oder so ähnlich. Dann muss ich bei der Anwendungsprogrammierung nicht mehr drüber nachdenken: war das jetzt eine 0 oder xyz sondern setze statt einem Zahlenwert diese Konstante.

 

Mir würde es erstmal reichen, wenn es noch geht, könnte man auch optional jeden Werktag setzen, da wäre dann quasi so universell wie bei einer Schaltuhr, jeden Montag und Samstag um 15.38 Uhr. Also ev. über ein Array oder Flags (rtcMonday || rtcSaturday) ... Aber nur wenn das ohne zusätzl. Aufwand geht.

 

Wäre schön wenn diesbzgl. auch mal andere User ihre Meinung abgeben könnten... >:( Bevor dann wieder der Katzenjammer in der Community anfängt "Öh so blöde Fkt. kann ich ja gar nicht verwenden...".

Link zu diesem Kommentar
Share on other sites

Hallo,

 

Wäre schön wenn diesbzgl. auch mal andere User ihre Meinung abgeben könnten...

 

ich persönlich kann mit der Implementierung leben. Für mich geeigneter wäre allerdings ein periodischer Callback, z.B. alle 5 Sekunden (unabhängig von Tag/Uhrzeit). Also sowas wie

setCallbackPeriod(<time in millis>)

--> Man bekommt alle "<time in millis>" einen Aufruf.

Link zu diesem Kommentar
Share on other sites

Ich kann 0 nicht nehmen, denn 0 ist ein gültiger Wert, z.B. für 00:12 Uhr muss hour auf 0 gesetzt werden. Daher -1 für alle Felder.

 

Kurz meine 5 Cent:

Es wäre schön die 0 doch als "NULL" benutzen zu können. das Problem mit "00:12" kann umschifft werden in dem die ZeitAngabe als ganzes gesehen wird. Also Stunden u. Minuten zusammen. Ein "00:00" müsste dann explizit so eingegeben werden, wobei eine "0:0" als "NULL" gewertet würde.

Bedeutet dass ein Aufruf mit lauter 0 ein Löschen zur Folge hat (0 Zeit an 0 Tagen).

Link zu diesem Kommentar
Share on other sites

Wäre schön wenn diesbzgl. auch mal andere User ihre Meinung abgeben könnten... >:( Bevor dann wieder der Katzenjammer in der Community anfängt "Öh so blöde Fkt. kann ich ja gar nicht verwenden...".

 

Hmm, also ich verstehe nicht wirklich wofür du diesen Callback brauchst?

Dafür bieten doch die Programmiersprachen mehr als genug Möglichkeiten.

Also von daher ist es mir ziemlich egal und ich bin mit jeder Lösung zufrieden :)

Link zu diesem Kommentar
Share on other sites

kreaktiv, das funktioniert so nicht. Du gibst da keinen String an und ich kann und will auch Stunden und Minuten nicht auf einen Wert zusammenführen, denn dadurch geht Funktionalität verloren. Mit

 

set_alarm(int8 month, int8 day, int8 hour, int8 minute, int8 second, int8 weekday)

 

kann ich sagen set_alarm(-1, -1, -1, 5, -1, -1) was zu einem Alarm 5 Minuten nach jeder vollen Stunde führt. Das kann ich nicht mehr angeben, wenn Stunden und Minuten zu einem Wert zusammengeführt sind, denn dann muss ich auch immer die Stunde mit angeben.

 

Die -1 wird bleiben, da geht kein Weg dran vorbei. Es wird aber eine Konstante dafür geben: ALARM_FIELD_DISABLED.

Link zu diesem Kommentar
Share on other sites

Equinox, so eine Art Alarm sieht der IC erstmal nicht direkt vor. Was ich aber wahrscheinlich machen kann ist der set_alarm Funktion ein int32 repeat (in Sekunden) Parameter geben:

 

set_alarm(int8 month, int8 day, int8 hour, int8 minute, int8 second, int8 weekday, int32 repeat)

 

Wenn das gesetzt ist dann setzt das Bricklet selbst einen neuen Alarm sobald der erste ausgelöst wurde. Zum Beispiel:

 

set_alarm(-1, -1, -1, -1, -1, -1, 5)

 

dies löst 5 Sekunden nach Aufruf dieser Funktion einen Alarm aus. Dann setzt das Bricklet intern den nächsten Alarm auf den aktuellen Tag und Zeit plus 5 Sekunden. Wenn der Alarm also das erste mal am Samstag den 11.06. um 15:23:42 Uhr ausgelöst wurde, dann ruft das Bricklet intern

 

set_alarm(10, 6, 15, 23, 42 + 5, -1, 5)

 

auf, um den nächsten Alarm für in 5 Sekunden zu konfigurieren. Damit kannst du also einen wiederkehrenden Alarm einstellen.

 

Darüber kann dann natürlich auch ein Alarm eingestellt werden, der das erste mal in 2 Tagen ausgelöst wird, dann aber alle 45 Minuten wiederholt wird.

Link zu diesem Kommentar
Share on other sites

Ja eine Repeat Angabe wäre prima, ev. könnte man mit diesem Wert auf 0 den CB grundsätzlich abschalten, eine Auslösung einmalig mit 1 usw. Wie gebe ich die dauerhafte Wiederholung an? Max (int) ?

Hmm, also ich verstehe nicht wirklich wofür du diesen Callback brauchst?

Du (noch) nicht, aber vielleicht andere User, da fragst du besser wehnerc :) Aber der Vorteil von Callbacks generell ist klar, oder?

Dafür bieten doch die Programmiersprachen mehr als genug Möglichkeiten.
Warum soll ich für u.U. banales Monitoring von Werten extra Infrastruktur progr.? Auf einem Single-Core ARM und node.js muss ich das nicht unbedingt haben.
Link zu diesem Kommentar
Share on other sites

repeat wäre nicht die Anzahl der Wiederholungen, sondern die Zeit in Sekunden zwischen den Wiederholungen. Ich nenne repeat um in interval.

 

Wenn du das int32 interval Parameter auf -1 setzt, gibst du an, dass du keine automatische Wiederholung des Alarm in einem festen interval von X Sekunden haben willst, sondern nur dann einen Alarm haben willst, wenn du wenn das aktuelle Datum/Uhrzeit dem eingestellten Alarm entspricht.

 

Um den Alarm abzustellen musst du dann set_alarm(-1, -1, -1, -1, -1, -1, -1) aufrufen.

 

Mit set_alarm(-1, -1, -1, -1, -1, -1, 45) sagst du, dass dir das aktuelle Datum/Uhrzeit egal ist und du ab sofort einen Alarm alle 45 Sekunden haben willst.

 

Mit set_alarm(4, 21, 13, 27, 59, -1, -1) sagst du, dass du einen Alarm am 21. April um 13:27:59 Uhr haben willst.

 

Mit set_alarm(8, 17, 0, 0, 0, -1, 300) sagst du, dass du ab dem 17. August 00:00:00 Uhr alle 5 Minuten einen Alarm haben willst.

Link zu diesem Kommentar
Share on other sites

set_date_time_callback_period(uint32 period)

get_date_time_callback_period() -> uint32 period

 

CALLBACK_DATE_TIME -> uint16 year, uint8 month, uint8 day, uint8 hour, uint8 minute, uint8 second, uint8 centisecond, uint8 weekday

Wird das periodische Auslösen unter Angabe der MillSec nicht schon abgedeckt durch den OnDateTime Callback?

 

Meinte Equinox doch diesen...

periodischer Callback, z.B. alle 5 Sekunden (unabhängig von Tag/Uhrzeit).

 

Link zu diesem Kommentar
Share on other sites

Das periodische Auslösen des Date/Time Callbacks wird mit der ungenauen Uhr des Bricks gemessen, nicht mit der genaueren Uhr des Real-Time Clock Bricklets. Genau so wie beim GPS Bricklet nicht die GPS Uhr für das Auslösen des Callbacks benutzt wird. Deswegen sagte ich auch vorher schon dieser Callback ist von seiner zeitlichen Beschaffenheit nicht besser als jeder andere Period-Callback irgendeines anderen Bricklets.

 

Sprich, wenn ich den Date/Time Callback auf 30 Minuten Intervall einstelle, dann wird dieses Intervall mit der ungenauen Uhr des Bricks gemessen. Diese Ungenauigkeit sammelt sich über die Zeit auf und die Callback drift recht schnell von seinem 30 Minuten Raster ab. Für die Period-Callbacks ist das normalerweise kein Problem, da diese üblicherweise viel kürzere Intervall verwenden und auch nicht so auf Genaugkeit angewiesen sind. Wenn ich aber einen Alarm zur jeder vollen und halben Stunden haben will, dann ist die Uhr des Bricks nicht gut genug.

 

Bei set_alarm(-1, -1, -1, -1, -1, -1, 1800) wird das 30 Minuten Intervall mit der RTC Uhr gemessen, die viel genauer ist als die Uhr des Bricks. Damit kann ich erreichen, dass der Alarm Callback z.B. in einem recht festen 30 Minuten Raster immer zur vollen und zur halben Stunde aufgerufen wird.

Link zu diesem Kommentar
Share on other sites

Das es im Zusammenhang mit der Ungenauigkeit eines Brick-Timers zu tun hat, ist mir nicht aufgefallen. Mit ist das auch neu, dass die internen Timer eines Brick generell nicht so genau sind. Habe ich hier im Forum oder Doku das übersehen? Mit welchen Abweichungen hat man i.d.R zu rechnen?

 

Gilt die Ungenauigkeit auch für die Monoflop-Timer?

Link zu diesem Kommentar
Share on other sites

Wie genau die Zeitmessung der Bricklets ist hängt von vielen Faktoren ab. Für die üblichen Zeitspannen im Sekunden- bis mehrere Minutenbereich die bei Period-Callbacks und z.B. auch Monoflops zu erwarten sind ist die Zeitmessung der Bricklets hinreichend gut genug. Im Stundenbereich wirst du schon merkliche Abweichungen sehen.

 

Daher meine Aussage, dass wenn du z.B. Callbacks zur vollen und halben Stunde über mehrere Stunden oder Tage hinweg haben willst, dann ist die interne Zeitmessung der Bricklets dafür nicht gut genug.

Link zu diesem Kommentar
Share on other sites

Für die üblichen Zeitspannen im Sekunden- bis mehrere Minutenbereich die bei Period-Callbacks und z.B. auch Monoflops zu erwarten sind ist die Zeitmessung der Bricklets hinreichend gut genug. Im Stundenbereich wirst du schon merkliche Abweichungen sehen.

Mit Bereichen meinst du den jetzt gesamten Messbereich von Betriebsstart bis -ende des CBs, oder die Periode?

Link zu diesem Kommentar
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Gast
Reply to this topic...

×   Du hast formatierten Text eingefügt.   Formatierung jetzt entfernen

  Only 75 emoji are allowed.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Clear editor

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

×
×
  • Neu erstellen...