Forum: Mikrocontroller und Digitale Elektronik Extrahierung der Zeit - DS3231


von Tim (mski)


Lesenswert?

Hi!

Wisst ihr oder habt Ihr eine Idee, wie ich aus dem Aufruf der Zeit 
"rtc.get.Time()" die Stunden und Minuten in unterschiedliche Variablen 
packen kann?

Gruß

von Joe L. (joelisa)


Lesenswert?

Fragen, die mir die Ente innerhalb von Sekunden beantworten kann -- 
darauf brauche ich hier nicht zu antworten...

von Sebastian R. (sebastian_r569)


Lesenswert?

Jop, weiß ich.

von Gerhard O. (gerhard_)


Lesenswert?

Tim schrieb:
> Hi!
>
> Wisst ihr oder habt Ihr eine Idee, wie ich aus dem Aufruf der Zeit
> "rtc.get.Time()" die Stunden und Minuten in unterschiedliche Variablen
> packen kann?
>
> Gruß

Moin,

Guck Dir mal die key word Link hier an:

https://github.com/adafruit/RTClib

https://github.com/adafruit/RTClib/blob/master/keywords.txt

Am besten Du studierst die Referenz der rtc Bibliothek.

Mit dem damit vorhandenen Syntax kann man auf alle internen RTC Register 
zugreifen. Beispiel:

1
...
2
DateTime now = rtc.now(); // kopier die aktuelle Zeit vom Ds3231
3
4
int hour = now.hour(); // Kopier die aktuelle Stundenzahl in die Variable "hour"
5
...

Sieh Dir die Beispiele dort an. Hier siehst Du wie man sie gebraucht.
Es ist wichtig, daß wie im folgenden Beispiel die Lib richtig gebraucht 
wird. Studiere jede Programmzeile dort, die sich auf diese Lib bezieht.

https://github.com/adafruit/RTClib/blob/master/examples/ds3231/ds3231.ino

Gerhard

: Bearbeitet durch User
von Tim (mski)


Lesenswert?

Vielen Dank Gerhard!

Scheint einfach. Hatte ich nicht gedacht. Probiere ich aus, sobald ich 
kann.

Schönen Tag noch :)

von Tim (mski)


Lesenswert?

Verstehe ich das richtig, dass ein neues Objekt erzeugt wird "now" und 
dem dann die Methode rtc.now(); zugewiesen wird?

Tut mir leid, aber bin da noch frisch, was Klassen und so angeht.

von Harald K. (kirnbichler)


Lesenswert?

Tim schrieb:
> und dem dann die Methode rtc.now(); zugewiesen wird?

Nein, dem wird das Ergebnis bzw. der Rückgabewert der Funktion 
zugewiesen.

von Tim (mski)


Lesenswert?

Stehen denn "DateTime now" und "now.hour();" in Verbindung. Verwirrt 
mich etwas, da in beiden "now" steht.

: Bearbeitet durch User
von Achim M. (minifloat)


Lesenswert?

rtc.now() liefert einen Rückgabewert des Typs DateTime, was dann an ein 
Objekt "now" des Typs DateTime zugewiesen wird.

Objekte des Typs DateTime haben eine Funktion .hour() im Bauch, die dir 
dann nur die Stunde im Basisdatentyp int als Rückgabewert liefert.

Oder eben so:
1
DateTime jetzt = rtc.now(); // kopier die aktuelle Zeit vom Ds3231
2
3
int hour = jetzt.hour(); // Kopier die aktuelle Stundenzahl in die Variable "hour"

mfg mf

: Bearbeitet durch User
von Tim (mski)


Lesenswert?

Vielen Dank!

Wieso muss ich die Zeit zwischenspeichern und kann die Stunden nicht 
direkt in eine Variable packen?

von Harald K. (kirnbichler)


Lesenswert?

Tim schrieb:
> Wieso muss ich die Zeit zwischenspeichern


Musst Du nicht.

> und kann die Stunden nicht
> direkt in eine Variable packen?

Kannst Du:
1
int hour = rtc.now().hour();

Wenn Du aber noch andere Zeitanteile bestimmen willst, ist diese 
Vorgehensweise nicht zu empfehlen, sie ist einerseits ineffizient (weil 
für jeden Aufruf ein Objekt vom Typ DateTime angelegt und wieder 
weggeworfen wird), und weil die verschiedenen Aufrufe nacheinander 
erfolgen, die Uhrzeit aber weiterläuft.

Stell' Dir mal vor, daß es gerade 3:59:59 und 999 Millisekunden ist.
Der erste Aufruf liefert "3" für die Stunden. Zwischenzeitlich 
verstreicht aber etwas Zeit, die RTC schaltet um auf 4:00:00, und der 
zweite Aufruf, der die Minuten holen soll, liefert "00".

Das Ergebnis ist dann 3:00, obwohl es 4:00 ist.

Dagegen hilft die Verwendung der "Hilfsvariablen", denn die darin 
gespeicherten Werte verändern sich nicht.

Ansonsten könntest Du auch nachsehen, welche anderen Funktionen die 
Klasse zur Verfügung stellt, von deren Typ das Objekt rtc ist.

Dazu könntest Du entweder die Dokumentation zu Rate ziehen oder aber 
in der Headerdatei mit der Klassendekaration nachsehen.

: Bearbeitet durch User
von Rainer W. (rawi)


Lesenswert?

Tim schrieb:
> Wisst ihr oder habt Ihr eine Idee, wie ich aus dem Aufruf der Zeit
> "rtc.get.Time()" die Stunden und Minuten in unterschiedliche Variablen
> packen kann?

Stunden und Minuten kannst du direkt per I2C unter Adresse 02h bzw. 01h 
aus der DS3231 auslesen - fertig.

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

Tim schrieb:
> Wisst ihr oder habt Ihr eine Idee, wie ich aus dem Aufruf der Zeit
> "rtc.get.Time()" die Stunden und Minuten in unterschiedliche Variablen
> packen kann?

Dann mußt Du wohl einfach mal die Doku zu Deiner ungenannten Lib lesen.
Typisch werden die Variablen in einer Struct abgelegt. Es kann auch 
sein, daß sie nicht binär (uint8_t), sondern packed BCD sind, wie sie im 
Chip vorliegen.

von Tim (mski)


Lesenswert?

Rainer W. schrieb:
> Stunden und Minuten kannst du direkt per I2C unter Adresse 02h bzw. 01h
> aus der DS3231 auslesen - fertig.

Klingt gut. Wie funktioniert das?

von Tim (mski)


Lesenswert?

Harald K. schrieb:
> int hour = rtc.now().hour();

Leuchtet jetzt mehr ein - zumindest weiß ich jetzt wie. Aber nicht ganz 
warum.
Ich kenne es nur nach dem Schema Objekt.Funktion/Methode();"

Verstehe jetzt nicht, was rtc.now() ist.

von Wilhelm M. (wimalopaan)


Lesenswert?

Tim schrieb:
> Verstehe jetzt nicht, was rtc.now() ist.

Die Elementfunktion now() des Objektes in rtc liefert ein temporäres, 
anonymes Objekt des Typs DateTime zurück. Und für dieses Objekt rufst Du 
dann die Elementfunktion hour() auf.

von Rainer W. (rawi)


Lesenswert?

Tim schrieb:
> Wie funktioniert das?

Einfach ein paar Softwareschichten weglassen.
Die IIC-Zugriffe sind im Datenblatt genau beschrieben.

von Tim (mski)


Lesenswert?

Wilhelm M. schrieb:
> Die Elementfunktion now() des Objektes in rtc liefert ein temporäres,
> anonymes Objekt des Typs DateTime zurück. Und für dieses Objekt rufst Du
> dann die Elementfunktion hour() auf.

Okay, es ist noch ein wenig klarer. Muss aber noch einmal nachfragen - 
bitte nicht steinigen.

"now()" - Elementenfuktion, weil die sich im der Klasse, im Bereich 
"public" Befindet!? Der Begriff Elementenfunktion ist mir nämlich 
ebenfalls neu.

Richtig?

Wieso schreibst du "des Objektes in"? Ist "rtc" nicht ein erzeugtes 
Objekt, für das dann die Funktion "now()" aufgerufen wird?!

Gruß

von Wilhelm M. (wimalopaan)


Lesenswert?

Tim schrieb:
> Wilhelm M. schrieb:
>> Die Elementfunktion now() des Objektes in rtc liefert ein temporäres,
>> anonymes Objekt des Typs DateTime zurück. Und für dieses Objekt rufst Du
>> dann die Elementfunktion hour() auf.
>
> Okay, es ist noch ein wenig klarer. Muss aber noch einmal nachfragen -
> bitte nicht steinigen.
>
> "now()" - Elementenfuktion, weil die sich im der Klasse, im Bereich
> "public" Befindet!? Der Begriff Elementenfunktion ist mir nämlich
> ebenfalls neu.

C++ kennt Funktionen in zwei Arten: freie Funktionen und Funktionen als 
Elemente einer Klasse, die Elementfunktionen. Dieser Name ist mit 
Bedacht gewählt, weil C++ ein paar mehr Möglichkeiten als bspw. Java 
hat. Bei Java haben wir nur "Elementfunktionen", die dort dann aber 
Methoden heißen, weil Java ein Sprache ist, in der man sinnvoll nur OO 
programmieren kann. Mit C++ kann man aber rein prozedural, OO, 
functional und meta-programmatisch programmieren. Daher der generelle 
Name Funktion: freie Funktion und Elementfunktion. Free function and 
element function. Die Variablen in einer Klasse nennt man 
dementsprechend auch Datenelemente.

> Richtig?

Ja.

> Wieso schreibst du "des Objektes in"? Ist "rtc" nicht ein erzeugtes
> Objekt, für das dann die Funktion "now()" aufgerufen wird?!

Ich empfehle folgende Nomenklatur:

Datentyp:
Der Datentyp definiert eine Menge von möglichen Werten sowie eine Menge 
von Operationen.

Objekt:
Ein Objekt ist ein Speicherbereich, in dem ein Wert des gegebenen 
Datentyps abgelegt ist.

Wert:
Ein Wert ist eine Folge von Bits mit einem Datentyp.

Variable:
Eine Variable ist ein Objekt mit einem Namen (Bezeichner).

Demzufolge kannst Du auch Variable zu rtc sagen, oder in Langform: rtc 
ist reine abstrakte Referenz (ein Name) für ein Objekt.

Folgendes Beispiel macht das deutlich:
1
int a{42};
2
int& ra = a;

Es gibt hier ein Objekt vom Typ int und a ist ein Name dafür. Genauso 
ist aber ra ein (weiterer) Name dafür. Es gibt aber nur ein(!) Objekt 
und zwei Namen.

Ich habe das deswegen so geschrieben, damit Du auch den Unterschied zu 
einem temporären-anonymen Objekt erkennen kannst, was die 
Elementfunktion now() zurückliefert. Im Compiler-Jargon sagt man dazu 
auch rvalue (im Gegensatz zu lvalue, was im wesentlichen einem benannten 
Objekt gleich kommt). Diese Unterscheidung ist für C++ wesentlich.

: Bearbeitet durch User
von Tim (mski)


Lesenswert?

Vielen Dank für die Erläuterung!

Was davon ist dann "rtc". Finde das, nur für sich stehend, nicht in der 
Lib.

: Bearbeitet durch User
von Falk B. (falk)


Lesenswert?

Tim schrieb:
> Was davon ist dann "rtc". Finde das, nur für sich stehend, nicht in der
> Lib.

https://github.com/adafruit/RTClib/blob/master/examples/ds3231/ds3231.ino

Das ist ein einfaches Beispiel.
1
RTC_DS3231 rtc;

RTC_DS3231 ist eine Klasse, welche in der Bibliothek definiert wird. rtc 
ist der vom Programmierer gewählte Name für eine Variable vom Typ 
RTC_DS3231. Man kann auch sagen, rtc ist ein (Daten)objekt.
1
if (! rtc.begin()) {

Hier wird eine Methode des Objekts rtc aufgerufen, welches die RTC 
initialisiert. Ähnlich wie Serial.begin();
1
DateTime now = rtc.now();

Hier wird eine neue Variable vom Typ DateTime und dem Namen now 
definiert, welche sofort mit der Methode rtc.now() beschrieben wird. now 
enthält sowohl das Datum als auch die Uhrzeit in einem internen Format. 
Wie das aufgebaut ist, spielt keine Rolle, den der Zugriff auf Zeit und 
Datum erfolgt mittels der dazugehörigen Methoden.

Was hier irritiert ist, das now sowohl der Name der Variablen ist als 
auch der Name der Methode der Klasse im Objekt rtc. Beides sind 
verschiedene Dinge, auch wenn sie mit der gleichen Sache zu tun haben.
1
now.year()

Diese Methode des Objekts now liefert das Jahr. Etc. für Tag, Tag der 
Woche, Stunde, Minute, Sekunde etc.
1
Serial.print(rtc.getTemperature());

Mit der Funktion kann man sogar die Temperatur der RTC auslesen, da ist 
halt eine Sonderfunktion dieses ICs. Die meisten RTCs haben das nicht.

von Tim (mski)


Lesenswert?

Oh, hab in den falschen Dateien gesucht - .h und .cpp

Steige mit der Ordner-/Dateistruktur von den Libs nicht durch.

Danke!

von Tim (mski)


Lesenswert?

Ist "rtc" also ein anderes Wort für die Klasse "RTC_DS3231"?

Tut mir leid, so 100%ig verstehe ich das noch nicht.

Kenne es so, dass wenn eine Klasse genannt wird, das neue Objekt mit 
Parametern in Klammern folgt, mit den in der Klasse gearbeitet wird. Ist 
es hier also was anderes?

Bsp.: RTC_DS3231 rct(var.);

von Cyblord -. (cyblord)


Lesenswert?

Mach doch bitte mal einen C++ Kurs oder sowas. Muss dieser Thread jetzt 
hier als Grundkurs Klassen und Objekte herhalten? Einfach mal selber 
einlesen. Und DANACH fette Projekte mit RTC machen. So geht die richtige 
Reihenfolge.

von Falk B. (falk)


Lesenswert?

Tim schrieb:
> Ist "rtc" also ein anderes Wort für die Klasse "RTC_DS3231"?

Nö. rtc ist ein vom Programmierer des Beispiels gewählter Variablenname. 
Man könnte es auch MeineEchtzeituhr nennen, ist halt mehr 
Schreibaufwand.

> Tut mir leid, so 100%ig verstehe ich das noch nicht.
>
> Kenne es so, dass wenn eine Klasse genannt wird, das neue Objekt mit
> Parametern in Klammern folgt, mit den in der Klasse gearbeitet wird. Ist
> es hier also was anderes?
>
> Bsp.: RTC_DS3231 rct(var.);

Das sind Initialisierungsparameter. Die gibt es manchmal, aber nicht 
immer.

von Markus O. (markusjo)


Lesenswert?

Also ist es das, ohne Initialisierungsparameter?

: Bearbeitet durch User
von Wilhelm M. (wimalopaan)


Lesenswert?

Falk B. schrieb:

> Das sind Initialisierungsparameter. Die gibt es manchmal, aber nicht
> immer.

Was sollen den Initialisierungsparameter sein? Bitte verwirre den armen 
Tim nicht nocht mehr.

Falk B. schrieb:
>> Bsp.: RTC_DS3231 rct(var.);

RTC_DS3231: eine Datentyp
rtc: ein Variablenname
var: ein Argument (für den Konstruktor von rtc)

Vgl. mit:

int abc(42);

int: ein Datentyp (in diesem Fall ein eingebauter Datentyp)
abc: ein Variablenname
42: ein Argument (für den "Konstruktor" von abc)

von Cyblord -. (cyblord)


Lesenswert?


von Falk B. (falk)


Lesenswert?

Wilhelm M. schrieb:
>> Das sind Initialisierungsparameter. Die gibt es manchmal, aber nicht
>> immer.
>
> Was sollen den Initialisierungsparameter sein?

Der Versuch einer Beschreibung eines armen C-Programmierers ;-)

von Markus O. (markusjo)


Lesenswert?

Dachte, dass die oft genannten Variablen, Objekte sind, in den Variablen 
hinterlegt werden.

Also ruft man mit "rtc" die Klasse auf?

: Bearbeitet durch User
von Wilhelm M. (wimalopaan)


Lesenswert?

Markus O. schrieb:
> Dachte, dass die oft genannte Variablen ein Objekt ist, was in diesem
> aber gespeichert wird, die Variable ist.

Guggst Du hier: Beitrag "Re: Extrahierung der Zeit - DS3231"

> Also ruft man mit "rtc" die Klasse auf?

Nein. Eine Klasse kann man nicht aufrufen, nur Funktionen.

: Bearbeitet durch User
von Falk B. (falk)


Lesenswert?

Markus O. schrieb:
> Dachte, dass die oft genannten Variablen, Objekte sind, in den Variablen
> hinterlegt werden.

Was ist das denn für ein Kauderwelsch? Mach es mal nicht komplizierter 
als es sein muss! KISS!

https://de.wikipedia.org/wiki/KISS-Prinzip

von Matthias S. (mat-sche)


Lesenswert?

Nop

von Markus O. (markusjo)


Lesenswert?

Meine, dass man durch die Variable auf die Elementfunktionen zugreifen 
kann.

von Markus O. (markusjo)


Lesenswert?

OK 😄

von Tim (mski)


Lesenswert?

Ich hatte jetzt ein wenig rumprobiert...

Wieso benötige ich, scheinbar, zwei Variablen mit den speziellen 
Datenformaten?

Im Beispiel wird, zu Anfang, RTC_DS3231 rtc; und später DateTime now = 
rtc.now(); erstellt. Sowohl RTC_DS3231 als auch DateTime sind Klassen.

Gruß

: Bearbeitet durch User
von Falk B. (falk)


Lesenswert?

Tim schrieb:
> Ich hatte jetzt ein wenig rumprobiert...
>
> Wieso benötige ich, scheinbar, zwei Variablen mit den speziellen
> Datenformaten?

Weil das so ist ;-)

> Im Beispiel wird, zu Anfang, RTC_DS3231 rtc;

Da stecken alle Daten für den Zugriff auf die RTC drin.

> und später DateTime now =
> rtc.now(); erstellt.

Das ist nur eine Variable, welche Zeit und Datum enthält.

von Wilhelm M. (wimalopaan)


Lesenswert?

Tim schrieb:
> Ich hatte jetzt ein wenig rumprobiert..

Irgendwie lernst Du aus den Antworten gar nichts, oder Dir fehlt 
jegliches Wissen bzgl. Programmierung.

Nimm erst einmal ein C++ Buch, und dann meldest Du Dich wieder.

von Tim (mski)


Lesenswert?

Tatsächlich stecke ich da noch in den Kinderschuhen. Aber ich glaube, 
dass ich das jetzt nachvollziehen kann. Vielen Dank für die viele Hilfe!

Ich tue mich bei einigen Dinge sehr schwer. Kann nicht immer alles 
hinnehmen, wie es ist. Will es oft mehr verstehen, als nötig. Aber mein 
Kopf halt...

Schönen Abend noch :)

von Kilo S. (kilo_s)


Lesenswert?

Tim schrieb:
> Im Beispiel wird, zu Anfang, RTC_DS3231 rtc; und später DateTime now =
> rtc.now(); erstellt. Sowohl RTC_DS3231 als auch DateTime sind Klassen.

Richtig.
Du nimmst die Klasse RTC_DS3231 und gibst ihr die variable rtc für den 
Zugriff auf die Funktionen innerhalb der Klasse und um den Wert den die 
Funktion zurück gibt zu speichern.

Nun nimmst du die DateTime Klasse gibst ihr auch wieder eine variable 
(now) für das Speichern der Rückgabewerte der Funktion UND übergibst von 
der rtc Klasse die von der aufgerufenen Funktion rtc.now() 
zuruckgegebenen werte der Klasse DateTime, die verabeitet werden mit der 
variable now und Funktion now. now.now();

Wenn dir (beispielsweise) die Funktion rtc.now() die Unixzeit ausgibt, 
wird die Klasse DateTime mit der Funktion now.now() das ganze in ein 
lesbares Datumsformat wandeln.

Oder anders gesagt, du verwendest den Rückgabewert von rtc.now() in der 
Funktion now() der DateTime Klasse und speicherst dessen Rückgabe in der 
variable now.

Doof zu erklären, du kannst das aber veranschaulichen in dem du dir den 
Wert von rtc.now() ausgeben lässt und danach den von now.now().

von Cyblord -. (cyblord)


Lesenswert?

Tim schrieb:
> Ich tue mich bei einigen Dinge sehr schwer. Kann nicht immer alles
> hinnehmen, wie es ist. Will es oft mehr verstehen, als nötig. Aber mein
> Kopf halt...

Krasse Fehleinschätzung. Du willst eben NICHT mehr verstehen als nötig. 
Das Gegenteil trifft zu. Du willst nur so viel verstehen dass du deinen 
aktuellen Quatsch machen kannst. WENN du mehr verstehen wollen würdest, 
hättest du dich schon lange in C++ eingelesen und würdest seit Tagen 
Anfängerbeispiele zu Klassen und Objekten abarbeiten.

Kilo S. schrieb:
> Doof zu erklären, du kannst das aber veranschaulichen in dem du dir den
> Wert von rtc.now() ausgeben lässt und danach den von now.now().

Nur doof zu erklären wenn man nicht mal die Grundbegriffe von OOP 
beherrscht. Du verwechselt ständig Klasse und Objekt. Sowie Feld und 
Variable. Sowie Funktion und Methode. Unter anderem.

: Bearbeitet durch User
von Kilo S. (kilo_s)


Lesenswert?

Cyblord -. schrieb:
> Nur doof zu erklären wenn man nicht mal die Grundbegriffe von OOP
> beherrscht.

Was bringt es ihm wenn ich es ihm in den gleichen Worten Versuche zu 
erklären die der Rest von euch benutzt, die er NICHT VERSTEHT!?


Ändert nichts daran das ich mich an anfängerfreundlichen Erklärungen 
Versuche!


P.S
Ich kenne OOP bereits seit PHP4/5... Aber du hast ja den absoluten 
Durchblick. ;-)

von Cyblord -. (cyblord)


Lesenswert?

Kilo S. schrieb:
> Cyblord -. schrieb:
>> Nur doof zu erklären wenn man nicht mal die Grundbegriffe von OOP
>> beherrscht.
>
> Was bringt es ihm wenn ich es ihm in den gleichen Worten Versuche zu
> erklären die der Rest von euch benutzt, die er NICHT VERSTEHT!?

Begriffe kann man nachschlagen. Er will doch lernen. Aber erst mal mit 
falschen Begriffen loslegen hilft keinem Anfänger. Korrekte Terminologie 
ist wichtig.

> Ändert nichts daran das ich mich an anfängerfreundlichen Erklärungen
> Versuche!

Hat sich stets bemüht...

> P.S
> Ich kenne OOP bereits seit PHP4/5... Aber du hast ja den absoluten
> Durchblick. ;-)

Puh welche Relevanz soll das haben? Du erklärst es schlicht falsch.

Nur warum muss man das hier überhaupt erklären? Das sind GRUNDLAGEN! C++ 
Quellen wurden verlinkt. Wieso kann er nicht selber mal was nachlesen?

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.