DS3231 Zeit String in einzelne Integer umwandeln

Moin zusammen,

ich versuche aus einer RTC DS3231 die Zeit als String herauszulesen und die Stunden, Minuten und Sekunden in Integer Werte umzuwandeln damit ich mit denen weiterarbeiten kann.

Nur funktioniert das alles nicht wie erhofft und ich hoffe hier kann mir wer weiterhelfen.

Die lib die ich für die RTC benutze ist diese hier: DS3231 - Rinky-Dink Electronics

Das Problem ist das die mir ausgegebenen Werte alle 0 sind und nicht der von der RTC ausgegebenen Uhrzeit entsprechen.

#include <LiquidCrystal.h>
#include <DS3231.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
DS3231  rtc(SDA, SCL);

String time;

int hour;
int min;
int sec;





void setup() {
  Serial.begin(115200);
  
  lcd.begin(16, 2);
  

  rtc.begin();

  rtc.setDOW(SUNDAY);
  rtc.setTime(22, 18, 13);
  rtc.setDate(21, 8, 2016);

  pinMode(10, OUTPUT);
}

void loop() {
  lcd.setCursor(0, 0);
  lcd.print(rtc.getDateStr());
  lcd.setCursor(0, 1);
  
  time = rtc.getTimeStr();

  char const *ca1 = time.substring(0, 1).c_str();
  hour = atoi(ca1);
  
  Serial.print(hour);
  Serial.print(":");
  
  char const *ca2 = time.substring(3, 4).c_str();
  min = atoi(ca2);
  
  Serial.print(min);
  Serial.print(":");

  char const *ca3 = time.substring(6, 7).c_str();
  sec = atoi(ca3);
  
  Serial.print(sec);
  
  lcd.print(rtc.getTimeStr());
  lcd.setCursor(10, 1);
  lcd.print(rtc.getTemp());
  lcd.setCursor(14, 1);
  lcd.print("c");

  if (15 >= min >= 20){
    digitalWrite(10, HIGH);
  }
  else{
    digitalWrite(10, LOW);
  }
  

}

lg

Auch wenn Du das fälschlich aus dem Namen vermutet hast, liefern beide Funktionen keinen String sondern einen char * zurück.

Was Du suchst ist getTime(), den Rest findest Du, wie auch das, im Datenblatt auf der von Dir verlinkten Website.

Edit: Danach kannst Du gern konkrete Fragen dazu stellen.

Gruß Tommy

Also bekomme ich aus der Funktion rtc.getTimeStr keine String Variable?

Wie auch immer, dann bleibt mir immer noch die Frage wie ich aus der RTC Integer Werte zum rechnen und vergleichen bekomme.

lg fxln

Fxln: Also bekomme ich aus der Funktion rtc.getTimeStr keine String Variable?

Wie auch immer, dann bleibt mir immer noch die Frage wie ich aus der RTC Integer Werte zum rechnen und vergleichen bekomme.

Ich kenne die Library nicht, aber den meisten Libraries sind Beispiele beigelegt, denen man die Daten einzeln entnehmen kann und diese entsprechend in "int" wandeln kann.

Aber warum must du "int" haben ? Was genau möchtest du mit den Daten machen ?

Fxln: Wie auch immer, dann bleibt mir immer noch die Frage wie ich aus der RTC Integer Werte zum rechnen und vergleichen bekomme.

Das habe ich Dir in Posting #2 bereits geschrieben. Lesen musst Du die Beschreibung von getTime() schon selbst. Hinweis: Schau Dir auch den Typ Time in der DS3231.h Deiner Lib an.

Gruß Tommy

Kleines Testprogramm, abgeleitet aus dem Beispiel DS3231_Serial_Hard, als Anregung:

#include <DS3231.h>
DS3231  rtc(SDA, SCL);  // Init the DS3231 using the hardware interface
Time  t;				// Init a Time-data structure

void setup()
{
  Serial.begin(9600);	// Setup Serial connection
  rtc.begin();			// Initialize the rtc object
}

void loop()
{
  t = rtc.getTime();	// Get data from the DS3231
  int stunden = t.hour;
  int minuten = t.min;
  int sekunden = t.sec;
  int sekseitmit = sekunden + (minuten * 60) + (stunden * 60 * 60);
  long unixzeit = rtc.getUnixTime(t);


  Serial.print(stunden);
  Serial.print(" Stunden\t");
  Serial.print(minuten);
  Serial.print(" Minuten\t");
  Serial.print(sekunden);
  Serial.print(" Sekunden\t");
  Serial.print(sekseitmit);
  Serial.print(" Sekunden seit Mitternacht\t");
  Serial.print(unixzeit);
  Serial.println(" Sekunden seit 1970");

  // Wait one second before repeating :)
  delay (1000);
}

Die Zeit bekommst du mittels getDateStr() als String wieder. Dann einfach den String mittels string.substing(anfang, ende) splitten und um aus diesem String dann einen Integer zu machen, bietet die String klasse toInt() an.

  String time = rtc.getTimeStr();
  
  int hour = time.substring(0,2).toInt();
  Serial.print("Stunde:");
  Serial.println(hour);
  int minute = time.substring(3,5).toInt();
  Serial.print("Minute: ");
  Serial.println(minute);
  int second = time.substring(6,8).toInt();
  Serial.print("Sekunde: ");
  Serial.println(second);

LG Paister

Paister: Die Zeit bekommst du mittels getDateStr() als String wieder. Dann einfach den String mittels string.substing(anfang, ende) splitten und um aus diesem String dann einen Integer zu machen, bietet die String klasse toInt() an.

LG Paister

Wenn man Ratschläge zu einer Lib gibt, sollte man in deren Doku rein geschaut haben. Du hast die Doku zu seiner Lib nicht gelesen und meinen Beitrag #2 auch nicht.

Gruß Tommy

Mein Ziel ist es eigentlich grob gesagt einen Wecker zu bauen, die Werte als int brauche ich um die vergleichen zu können, damit der dann zur richtigen Zeit angeht. So mein Gedankengang.

Beide Codes funktionieren wunderbar, wobei ich den von agmue nicht verstehe, wie das ganze funktioniert:?

@Paister: Willkommen im Forum :)

Fxln: Beide Codes funktionieren wunderbar, wobei ich den von agmue nicht verstehe, wie das ganze funktioniert:?

Was nicht?

Grobe Erklärung zu agmue:

Eine Funktion kann nur 1 Wert zurück geben. Der hat hier mehrere Bestandteile.

Die Funktion getTime liefert ein struct (Struktur aus mehreren Werten) zurück, in der die einzelnen int drin stehen.

Wenn t die Struktur vom Typ Time ist, ist t.min der Bestandteil min aus der Strukturvariable t.

Man lernt jeden Tag was neues :D, danke für die Erklärung.

Also wäre die Lösung von agmue auch die unklompliziertere?

Fxln:
Mein Ziel ist es eigentlich grob gesagt einen Wecker zu bauen, die Werte als int brauche ich um die vergleichen zu können, damit der dann zur richtigen Zeit angeht.

Dafür bietet sich die Unixzeit an, mit der man schön Zeitdifferenzen ausrechnen kann. Ich habe mein Beispiel in #5 entsprechend erweitert.

Fxln:
Also wäre die Lösung von agmue auch die unklompliziertere?

Das ist die in der Bibliothek eingebaute Lösung. Ich bin faul, habe die genommen. Was Dir besser gefällt, ist Geschmackssache :slight_smile:

Danke @agmue,

@Tommy56 nur weil ich nicht genauer auf deinen Post eingegangen bin, heißt es nicht dass ich ihn nicht gelesen habe. Richtig ist dass ich die Dokumentation der Library nicht gelesen habe. Seine Anforderung war jedoch die Zeit als String herauszulesen, was mit diesem indirekten Cast exakt das ist was er wollte oder nicht? Es lässt sich auch erkennen, dass Grundlagenwissen vorhanden ist, jedoch nicht unbedingt, dass klar ist, was ein char pointer ist (wenn man das * nach dem Zeilenumbruch überhaupt sieht).

@Fxln, wenn du lediglich die einzelnen Komponenten der Zeit und des Datums haben willst, dann ist die Lösung von agmue sicherlich die zu bevorzugende Variante, wobei halt beide gehen.

Paister: @Tommy56 nur weil ich nicht genauer auf deinen Post eingegangen bin, heißt es nicht dass ich ihn nicht gelesen habe. Richtig ist dass ich die Dokumentation der Library nicht gelesen habe. Seine Anforderung war jedoch die Zeit als String herauszulesen, was mit diesem indirekten Cast exakt das ist was er wollte oder nicht? Es lässt sich auch erkennen, dass Grundlagenwissen vorhanden ist, jedoch nicht unbedingt, dass klar ist, was ein char pointer ist (wenn man das * nach dem Zeilenumbruch überhaupt sieht).

Ok, den impliziten cast habe ich übersehen, da hast Du recht. Sorry, mein Fehler. Ob das wirklich verständlicher ist, sei dahin gestellt.

Wobei ich den Umweg über die Klasse String schon aus Speichergründen als den schlechteren sehe, wenn es die int schon direkt gibt. Selbst wenn es die nicht gibt, ist die Verarbeitung als char * ressourchenschonender.

Gruß Tommy

Danke an alle Beteiligten!