RTC PCF8523 12 statt 0 Uhr und 32 statt 12 Uhr

Hi,
ich habe auf meinem Uno R3 einen Adafruit Data Logging Shield verbaut, welcher eine PCF8523 Uhr hat.
Die Uhr funktioniert an sich, aber beim Wechsel von 11:59:59 auf eigentlich 12:00:00 wird die Uhrzeit “32:00:00” ausgegeben.
Außerdem wird statt 0 Uhr 12 Uhr angezeigt.

Bisher konnte ich rein gar nix dazu finden. Es betrifft sowohl serial.print als auch das Schreiben in eine Datei auf der SD Karte.

Bibliotheken:

/* TOC Daten-Logger programmiert von Jan Schröder, RMH KM-TE */

//Bibliotheken einbinden
#include <Wire.h>
#include "RTClib.h"
//#include <SD.h>
#include <SdFat.h> //SdFat.h wird verwendet, da längere Dateinamen und Zeitstempel möglich sind, bei SD.h nicht
SdFat SD; //Umwandeln von alten SD.h Befehle für SdFat.h
#include <SPI.h>
#include <string.h>
#include <avr/pgmspace.h>

#define SYNC_INTERVAL 1000 //Synchronisierungsintervall für SD-Karte auf 1000ms

Uhr-Typ:

//Uhr-Typ festlegen
RTC_PCF8523 RTC;
//uint32_t syncTime = 0;

//SD-Karten CS Pin festlegen
const int chipSelect = 10;
//Länge des Dateinamen festlegen
char filename[30]; 
//Datei-Variable festlegen
File logfile;

Setup (Teil):

void setup() {
  Serial.begin(57600);
  Wire.begin();
  RTC.begin();
  // Überprüfe, ob RTC die Zeit beibehält
  if (! RTC.initialized()) {
    Serial.println("RTC läuft nicht!");    
  }
  RTC.adjust(DateTime(F(__DATE__), F(__TIME__))); //Stelle Uhrzeit nach Systemzeit, als der Sketch kompilliert wurde

Zeitstempel für Dateien:

void dateTime(uint16_t* date, uint16_t* time) { //Zeitstempel für Dateien definieren
  DateTime now = RTC.now();
  *date = FAT_DATE(now.year(), now.month(), now.day());
  *time = FAT_TIME(now.hour(), now.minute(), now.day());
  
}

Der Loop, inkl. Serial.print und logfile.print - beides vom Problem betroffen:

void loop() {
  //Interpretiere Eingänge 'bits' als Array mit Werten wie 'wert'
  byte index = 0;
  static byte alt_index = 0;
  static byte alt_index2 = 0;
  for (byte i = 0; i < 8; i++) {
    //@Forum: DELAY HABE ICH HIER EINGEFÜGT - delay(100);
    /*digitalWrite(led[i], */digitalRead(bits[i]);  //'digitalWrite(led[i],' bei Bedarf aktivieren, wenn LEDs benötigt werden, siehe Pinbelegung oben 
    if (!digitalRead(bits[i])) {
      
      index += wert[i];
    }
  }
  if ((alt_index != alt_index2)&&(index == alt_index)) {
    DateTime now = RTC.now(); //Setze now Variable
    SdFile::dateTimeCallback(dateTime); //Zeitstempel für Dateien setzen
    sprintf(filename, "TOC-Log %02d-%02d-%02d.txt", now.year(), now.month(), now.day()); //Setze 'filename' Variable - TOC-Log JJJJ-MM-TT.txt
    logfile = SD.open(filename, FILE_WRITE); //Öffne Datei mit variable 'filenname' als Name  
    strcpy_P(buffer, (char*)pgm_read_word(&(meldung[index]))); //Lege Variable 'buffer' fest, Ausgabe für 'buffer' besteht aus Variable 'meldung' + 'wert'-index
    //Serielle Ausgabe ab hier - kann auskommentiert werden
    Serial.print(F("\nEs wird in Datei geschrieben: "));
    Serial.println(filename);
/*    if(now.day()<10) //Wenn Tag kleiner als 10 ist, schreibe eine 0 vorweg
      Serial.print('0'); */
    Serial.print(now.day(), DEC);
    Serial.print('.');
/*    if(now.month()<10) //Wenn Monat kleiner als 10 ist, schreibe eine 0 vorweg
      Serial.print('0'); */
    Serial.print(now.month(), DEC);
    Serial.print('.');
    Serial.print(now.year(), DEC);
    Serial.print(' ');
    Serial.print('-');
    Serial.print(' ');
/*    if(now.hour()<10) //Wenn Stunde kleiner als 10 ist, schreibe eine 0 vorweg
      Serial.print('0'); */
    Serial.print(now.hour(), DEC);
    Serial.print(':');
/*    if(now.minute()<10) //Wenn Minute kleiner als 10 ist, schreibe eine 0 vorweg
      Serial.print('0'); */
    Serial.print(now.minute(), DEC);
    Serial.print(':');
/*    if(now.second()<10) //Wenn Sekunde kleiner als 10 ist, schreibe eine 0 vorweg
      Serial.print('0'); */
    Serial.print(now.second(), DEC);
    Serial.print(' ');
    Serial.print("(UTC)");
    Serial.print("\r\n ");
    Serial.print(buffer); //Meldung Nr. [index] ausgeben
    Serial.print("\r\n\r\n");
    //Serielle Ausgabe Ende
    
    //Schreiben in Logdatei
/*    if(now.day()<10) //Wenn Tag kleiner als 10 ist, schreibe eine 0 vorweg
      Serial.print('0'); */
    logfile.print(now.day(), DEC);
    logfile.print('.');
/*    if(now.month()<10) //Wenn Monat kleiner als 10 ist, schreibe eine 0 vorweg
      logfile.print('0'); */
    logfile.print(now.month(), DEC);
    logfile.print('.');
    logfile.print(now.year(), DEC);
    logfile.print(' ');
    logfile.print('-');
    logfile.print(' ');
/*    if(now.hour()<10) //Wenn Stunde kleiner als 10 ist, schreibe eine 0 vorweg
      logfile.print('0');*/
    logfile.print(now.hour(), DEC);
    logfile.print(':');
/*    if(now.minute()<10) //Wenn Minute kleiner als 10 ist, schreibe eine 0 vorweg
      logfile.print('0');*/
    logfile.print(now.minute(), DEC);
    logfile.print(':');
/*    if(now.second()<10) //Wenn Sekunde kleiner als 10 ist, schreibe eine 0 vorweg
      logfile.print('0');*/
    logfile.print(now.second(), DEC);
    logfile.print(' ');
    logfile.print("(UTC)");
    logfile.print("\r\n ");
    logfile.print(buffer);
    logfile.print("-------------------------------------------");
    logfile.print("\r\n\r\n"); //Absätze
    logfile.close(); //Schließe die Datei
    //Schreiben Ende
  }
  delay(5);
  alt_index2 = alt_index;
  alt_index = index;
}

Hat jemand eine Idee, wie ich das beheben kann?

Gruß,
Jannomag

Setze Deinen Code bitte in Codetags (</>-Button oben links im Forumseditor oder [code] davor und [/code] dahinter ohne *).

Gruß Tommy

Tommy56:
Setze Deinen Code bitte in Codetags (</>-Button oben links im Forumseditor oder [code] davor und [/code] dahinter ohne *).

Gruß Tommy

Sorry, wusste ich nicht - hielt es bei Pastebin für einfacher zu lesen wegen Highlighting…zumal mein Sketch eigentlich zu groß ist, hab ihn Abgekürzt.

Kannst Du Deinen Sketch noch weiter kürzen, dass nur das eigentliche Problem als kompilierbarer Sketch übrig bleibt?
Da ist noch viel drin, was nicht zum Problem gehört.

Gruß Tommy

Habs geteilt und gekürzt...sollte jetzt besser lesbar sein.

Wenn Du das Datenblatt der RTC schaust zB: https://www.nxp.com/docs/en/data-sheet/PCF8523.pdf dann ist Bit 5 des Registers Hours das angibt ob 12 oder 24 Format.
So ist wahrscheinlch daß die Bibliothek dies nicht richtig decodiert. Hast Du versucht eine andere Bibliothek zu suchen?
Grüße Uwe

Es ist die Bibliothek von Adafruit. Sie hat sogar ein Beispiel für genau diese Uhr.
Ich werde mal eine andere testen, geht aber erst Donnerstag, da das Gerät auf Arbeit steht.

Jannomag:
Es ist die Bibliothek von Adafruit. Sie hat sogar ein Beispiel für genau diese Uhr.

Wenn Du RTClib/examples/pcf8523/pcf8523.ino meinst, was gibt das Beispiel denn aus?

Die viel genaueren DS3231 sind günstiger und hätte ich hier zum Testen rumliegen. Warum nur verwendest Du einen teuren Exoten? (rhetorische Frage!)

Wie ist das Bit 12_24 in Control_1 gesetzt?

agmue:
Wenn Du RTClib/examples/pcf8523/pcf8523.ino meinst, was gibt das Beispiel denn aus?

Die viel genaueren DS3231 sind günstiger und hätte ich hier zum Testen rumliegen. Warum nur verwendest Du einen teuren Exoten? (rhetorische Frage!)

Das gleiche Problem - beim Wechsel auf 12 Uhr erscheint 32 Uhr und 0 Uhr wird als 12 Uhr angezeigt.

Es war das einzige Modul mit SD und Uhr, was ich bestellen konnte - musste Reichelt sein, ich habs schließlich nicht bezahlt. Meine China-Logger sind alle mit DS3231 oder DS1307, aber die wollte ich wegen eventueller Kurzlebigkeit nicht benutzen. Da es sich um ein Projekt für eine Abteilung meiner Firma handelt, haben die das bezahlt, nicht ich. Ich bin auch davon ausgegangen, dass ein Adafruit-Modul solche Probleme nicht kennt...

Rintin:
Wie ist das Bit 12_24 in Control_1 gesetzt?

Das weiß ich nicht, wie finde ich das heraus? Die Dokumentation ist zwar für den PCF8523, aber der ist verbaut auf dem Logger Shield...wie ich da irgendwelche Bits, setzen kann, steht auch in der Doku von Adafruit nicht.

32 ist 0h+32 vom AM/PM Bit (Bit 12_24 ) im gleichen Register der RTC.
Bit 12_24 ist das Bit 5 im Register Hours. lies das Register aus und schau wie das Bit gesetzt ist.
Lies Dir mal das Datenblatt durch. Den Link hatte ich Dir berets gegeben.

Grüße Uwe

Jannomag:
Ich bin auch davon ausgegangen, dass ein Adafruit-Modul solche Probleme nicht kennt...

Ich auch, daher vermute ich, es ist der Typ, den Du im Spiegel siehst ;D

Meine Vermutung deckt sich mit der der Vorredner: Bit 12_24 wurde bei irgendwelchen Aktionen gesetzt, die Adafruit-Bibliothek setzt aber das Bit nicht zurück, da es normal nicht gesetzt ist.

Pragmatischer Vorschlag: Batterie raus, warten, bis sich die Kondensatoren entladen haben, Batterie wieder rein und hoffen, daß beim Reset der Uhr die Bits auf den Standardwert zurückgesetzt werden.

Hacker - Vorschlag:
Programm schreiben das Bit auf 0 setzt.

Grüße Uwe

Oder die Bibliothek pimpen, damit alle Standardwerte mit der Methode begin geschrieben werden.

uwefed:
32 ist 0h+32 vom AM/PM Bit

Nicht ganz… die RTC läuft im BCD-modus → also 20+12

(Bit 12_24 ) im gleichen Register der RTC. Bit 12_24 ist das Bit 5 im Register Hours.

Das bit heißt AMPM. 12_24 dient zum Konfigurieren des 12/24h-modus.

lies das Register aus und schau wie das Bit gesetzt ist.
Lies Dir mal das Datenblatt durch. Den Link hatte ich Dir berets gegeben.

Grüße Uwe

12_24 ist im Control_1

Hab die RTC nicht zum testen. Ich hoffe mal das der Code zum Auslesen der Register des PCF8523 funktioniert:

#include <Wire.h>

#define RTC_ADDR 0b1101000
#define RTC_REGISTER_COUNT 20

void setup() {
  Wire.begin();
  Serial.begin(9600);


  Wire.beginTransmission(RTC_ADDR);
  Wire.write(0x00); // Internen Adresspointer der RTC auf 0 setzen
  Wire.endTransmission();

  Wire.requestFrom(RTC_ADDR, RTC_REGISTER_COUNT);
  for(int x=0; x<RTC_REGISTER_COUNT; x++){
    byte val = Wire.read();
    Serial.print(val, HEX);
    Serial.print(" ");
  }

  Serial.println("");
}

void loop() {
  // put your main code here, to run repeatedly:

}

Nach requestFrom() kommt kein endTransmission()! Letzeres ist nur zum Senden da, nicht zum Empfangen.

Serenifly:
Nach requestFrom() kommt kein endTransmission()! Letzeres ist nur zum Senden da, nicht zum Empfangen.

und weg ist es

Rintin:
Nicht ganz... die RTC läuft im BCD-modus -> also 20+12
Das bit heißt AMPM. 12_24 dient zum Konfigurieren des 12/24h-modus.
12_24 ist im Control_1

Hab die RTC nicht zum testen. Ich hoffe mal das der Code zum Auslesen der Register des PCF8523 funktioniert:

Hier die Ausgabe deines Codes:
9 7 0 18 0 32 2 0 10 18 80 80 80 80 0 0 7 0 7 6E .

So wirklich verstanden habe ich das mit dem Register noch nicht, vor allem nicht, wie ich das ändern kann.

Jannomag:
... vor allem nicht, wie ich das ändern kann.

Hast Du schon meinen Vorschlag aus #11 versucht?

Sonst mußt Du Control_1 mit 0x1 anstelle 0x9 (= 0b00001001) beschreiben.

agmue:
Hast Du schon meinen Vorschlag aus #11 versucht?

Sonst mußt Du Control_1 mit 0x1 anstelle 0x9 (= 0b00001001) beschreiben.

Die Batterie war jetzt 10 Minuten draußen, ohne Ergebnis.
Dieses Control_1 verstehe ich nicht so ganz - also wie ich das beschreiben soll.