Problem beim auslesen des aktuellen Datums

Hallo Arduino Gemeinde,

ich habe in meinem Terrariumprogramm ein eigentlich kleines Problem festgestellt, welches mich aber einfach nervt. Ich habe festgestellt, dass mir das aktuelle Datum nicht angezeigt bzw. ausgelesen wird, sondern nur das, welches ich über den Seriellen Monitor eingebe. Ich habe mein Code schon soweit reduziert das nur noch das Auslesen der aktuellen Uhrzeit + Datum und anzeige im LCD drin ist, aber ich weiss einfach nicht wo der Fehler liegt.
Kann mir da eventuell jemand helfen?

A//Bibliotheken laden
#include <Wire.h> // Wire Bibliothek laden (Echtzeit/Ethernet)
#include <LiquidCrystal_I2C.h> // LiquidCrystal Bibliothek laden (LCD-Display)
#include <CombieTimer.h>  // Combie Timer Bibliothek laden (Brunnen/Display)

//Definierungen
#define RTC_I2C_ADDRESS 0x68 // I2C Adresse der RTC ist 0x68 für DS1307 und DS3231
#define Taster 4 // Der Taster wird an Pin 4 angeschlossen

//Benennungen
LiquidCrystal_I2C lcd(0x27,20, 4); // Hier wird das Display benannt (Adresse/Zeichen pro Zeile/Anzahl Zeilen).
Combie::SimpleTimer timerDisplay; // Hier wird der Timer des Displays benannt

//Globale Variablen
int jahre,monate,tage,stunden,minuten,sekunden;

//schalten der Hindergrundbeleuchtung des Displays nach Zeit
void schalteHintergrundbeleuchtung()
{
  if(digitalRead(Taster) == HIGH)
  {
    lcd.backlight();
    timerDisplay.start(); // Timer des Displays starten
  }
}

//auslesen der Uhrzeit + Datum
// Wochentag bleibt in diesem Sketch unberuecksichtigt
void rtcReadTime(int &jahre, int &monate, int &tage, int &stunden, int &minuten, int &sekunden)
// aktuelle Zeit aus RTC auslesen
{
// Reset the register pointer
  Wire.beginTransmission(RTC_I2C_ADDRESS);
  Wire.write(0);
  Wire.endTransmission();
  Wire.requestFrom(RTC_I2C_ADDRESS, 7);
  // A few of these need masks because certain bits are control bits
  sekunden    = bcdToDec(Wire.read() & 0x7f);
  minuten     = bcdToDec(Wire.read());
  stunden     = bcdToDec(Wire.read() & 0x3f);  // Need to change this if 12 hour am/pm
  /*wochentag   = */bcdToDec(Wire.read());
  tage        = bcdToDec(Wire.read());
  monate      = bcdToDec(Wire.read());
  jahre       = bcdToDec(Wire.read())+2000;  
}

//schreiben der aktuellen Uhrzeit + Datum
// Wochentag bleibt in diesem Sketch unberuecksichtigt
void rtcWriteTime(int jahre, int monate, int tage, int stunden, int minuten, int sekunden)
// aktuelle Zeit in der RTC speichern
{
  Wire.beginTransmission(RTC_I2C_ADDRESS);
  Wire.write(0);
  Wire.write(decToBcd(sekunden));    // 0 to bit 7 starts the clock
  Wire.write(decToBcd(minuten));
  Wire.write(decToBcd(stunden));      // If you want 12 hour am/pm you need to set
                                   // bit 6 (also need to change readDateDs1307)
  Wire.write(decToBcd(0)); // Wochentag unberuecksichtigt
  Wire.write(decToBcd(tage));
  Wire.write(decToBcd(monate));
  Wire.write(decToBcd(jahre-2000));
  Wire.endTransmission();  
}

//Hilfsfunktionen zum lesen und schreiben der aktuellen Uhrzeit + Datum
byte bcdToDec(byte val)  // Hilfsfunktion zum Lesen/Schreiben der RTC
// Convert binary coded decimal to decimal number
// Hilfsfunktion für die Echtzeituhr
{
  return ( (val/16*10) + (val%16) );
}

byte decToBcd(byte val) // Hilfsfunktion zum Lesen/Schreiben der RTC
// Convert decimal number to binary coded decimal
// Hilfsfunktion für die Echtzeituhr
{
  return ( (val/10*16) + (val%10) );
}

//schreiben der aktuellen Uhrzeit + Datum über Seriellen Monitor
void behandleSerielleBefehle()
{
  char linebuf[30];
  byte counter;
  if (Serial.available())
  {
    delay(100); // warte auf das Eintreffen aller Zeichen vom seriellen Monitor
    memset(linebuf,0,sizeof(linebuf)); // Zeilenpuffer loeschen
    counter=0; // Zaehler auf Null
    while (Serial.available())
    {
      linebuf[counter]=Serial.read(); // Zeichen in den Zeilenpuffer einfuegen
      if (counter<sizeof(linebuf)-1) counter++; // Zeichenzaehler erhoehen
    }
    // ab hier ist die Zeile eingelesen
    if (strstr(linebuf,"set")==linebuf) // pruefe auf Befehl "set" zum Setzen der Zeit
    { // alle uebermittelten Zahlen im String auslesen
      tage=getIntFromString (linebuf,1);
      monate=getIntFromString (linebuf,2);
      jahre=getIntFromString (linebuf,3);
      stunden=getIntFromString (linebuf,4);
      minuten=getIntFromString (linebuf,5);
      sekunden=getIntFromString (linebuf,6);
    }
    else
    {
      Serial.println("Befehl unbekannt.");
      return;
    }
    // ausgelesene Werte einer groben Plausibilitaetspruefung unterziehen:
    if (jahre<2000 || monate<1 || monate>12 || tage<1 || tage>31 || (stunden+minuten)==0)
    {
      Serial.println(linebuf);
      Serial.println("\r\nFehlerhafte Zeitangabe im 'set' Befehl");
      Serial.println("\r\nBeispiel:");
      Serial.println("set 28.08.2013 10:54\r\n");
      return;
    }
    rtcWriteTime(jahre, monate, tage, stunden, minuten, sekunden);
    Serial.println("Zeit und Datum wurden auf neue Werte gesetzt.");
  }
}

//////////////////
int getIntFromString (char *stringWithInt, byte num)
// input: pointer to a char array
// returns an integer number from the string (positive numbers only!)
// num=1, returns 1st number from the string
// num=2, returns 2nd number from the string, and so on
{
  char *tail; 
  while (num>0)
  {
    num--;
    // skip non-digits
    while ((!isdigit (*stringWithInt))&&(*stringWithInt!=0)) stringWithInt++;
    tail=stringWithInt;
    // find digits
    while ((isdigit(*tail))&&(*tail!=0)) tail++;
    if (num>0) stringWithInt=tail; // new search string is the string after that number
  }  
  return(strtol(stringWithInt, &tail, 10));
}

//Setup-Teil (alles wird nur einmal ausgefuehrt)
void setup()
{
  // Geräte Setup
  Wire.begin();       // initialisiert die Wire-Library

  // Serial Setup
  Serial.begin(9600); // Serielle Kommunikation starten
  while (!Serial);    // wait for serial port to connect. Needed for Leonardo only
  Serial.println("Jede Minute wird die aktuelle Zeit im 'Seriellen Monitor' angezeigt.");
  Serial.println();
  Serial.println("Du kannst die Zeit mit einem 'set' Befehl im 'Serial Monitor' neu setzen.");
  Serial.println("\r\nBeispiel:");
  Serial.println("set 28.08.2013 10:54\r\n");

  // LCD Setup
  lcd.init(); // LCD wird gestartet
  lcd.backlight();  // Hintergrundbeleuchtung einschalten
  delay(2000);
  lcd.noBacklight(); // Hintergrundbeleuchtung ausschalten

  // Pin Setup
  pinMode(13,OUTPUT);
  pinMode(Taster,INPUT);
  digitalWrite(13,LOW); // dauerhaftes Ausschalten der OnboardLED
}
//Loop-Teil (laeuft immer wieder durch)
void loop()
{
  // Steuerung nach Zeit (Minute/Sekunde)
  char buffer[30];
  static unsigned long lastMillis;
  static int lastMinute;
  int stunden, minuten, sekunden, dummy;
  if (millis()-lastMillis>1000) // nur einmal pro Sekunde
  {
    lastMillis=millis();
    rtcReadTime(dummy, dummy, dummy, stunden, minuten, sekunden);
    if (minuten!=lastMinute) // die aktuelle Minute hat gewechselt
    {
      lastMinute=minuten;
      snprintf(buffer,sizeof(buffer),"%02d:%02d Uhr",stunden,minuten);
      Serial.println(buffer);
    }
    // schreiben des Datums + Uhrzeit ins LCD-Display
    lcd.setCursor(1,0); // Text soll beim zweiten Zeichen in der ersten Reihe beginnen.
    lcd.print(tage); // In der ersten Zeile soll das Datum angezeigt werden
    lcd.print(".");
    lcd.print(monate);
    lcd.print(".");
    lcd.print(jahre);
    lcd.setCursor(2,1); // Text soll beim dritten Zeichen in der zweiten Reihe beginnen.
    lcd.print(stunden); // In der zweiten Zeile soll die Uhrzeit angezeigt werden
    lcd.print(":");
    lcd.print(minuten);
    lcd.print(":");
    lcd.print(sekunden);   
  }

  // Steuerung außerhalb der Zeit
  behandleSerielleBefehle();
  schalteHintergrundbeleuchtung();

  // zuruecksetzen der Hintergrundbeleuchtung des Displays nach 10 Sekunden
  if(timerDisplay(10 * 1000L)) // wenn abgelaufen
  {
    lcd.noBacklight();
  }
}

Ich habe mein Code schon soweit reduziert das nur noch das Auslesen der aktuellen Uhrzeit + Datum und anzeige im LCD drin ist

Ausserdem ist noch drin, dass du deine RTC Uhr über Serial stellen kannst.

Was passiert denn genau?

  • Wird jede Minute eine neue Zeit angezeigt?
  • Wenn nicht, ist deine RTC (richtig) angeschlossen?

Ja das stimmt, wenn ich über den Seriellen Monitor das Datum und die Uhrzeit einstelle, gehts auch, aber das Datum aktualisiert sich am nächsten Tag nicht, es bleibt das alte.
Ja jede Sekunde ändert sich die Zeit im LCD und dementsprechend dann auch jede Minute.
Uhrzeit passt alles, Datum nur halt nicht.
Angeschlossen ist auch alles richtig.

Hallo,

wenn ich das recht sehe ist das die Stelle wo die RTC ausgelesen werden soll, nur was macht das Dummy da ?

D.h du bekommst immmer das datum der Eingabe angezeigt , nie das von der Uhr

Gruß Heinz

lastMillis=millis();
    rtcReadTime(dummy, dummy, dummy, stunden, minuten, sekunden);
    if (minuten!=lastMinute) // die aktuelle Minute hat gewechselt
    {

Ah, alles klar, ich glaube ich weiss wo der Fehler ist. Das heißt ich darf nicht dummy schreiben, sondern da muss Tage, Monate, Jahre rein, richtig?

Shane93:
Ah, alles klar, ich glaube ich weiss wo der Fehler ist. Das heißt ich darf nicht dummy schreiben, sondern da muss Tage, Monate, Jahre rein, richtig?

Das siehst du genau richtig, sollte genau dein Problem sein.

Alles klar, dann vielen Dank für die schnelle Hilfe an alle.