Mega 2560, DS3231 mit DCF77 stellen

Hallo Leute,
bin der Neue, hier im Forum. Ich komme aus der BASCOM-Welt und möchte gerne über die Arduino Szene in die C/C++ Sprache rein kommen. Einige Sachen habe ich auch schon mit dem Arduino umgesetzt.

Aber ich würde natürlich kein Topic aufmachen wenn ich nicht auch ein Problem hätte.
Nach zwei Wochen Fehlersuche habe ich nun schon meinen ganzen Tisch rund gebissen und meinen Arduino das Fliegen gelehrt. :slight_smile: Aber eins nach dem anderen.

Projekt:
Mit dem Arduino Mega 2560, möchte ich die Uhrzeit vom DS3231 (Echtzeituhr) holen und auf einem Nextion Display darstellen. Zeitgleich möchte ich das DCF77 Modul (von reichelt) dazu nutzen das DS3231 zustellen. Klingt erstmal nicht schwer, aber:

Problem:

  1. Das DS3231 geht in 24h um 2 Minuten nach, (Abblock Kondensator VCC/GND, 220nF Keramik, ist vorhanden, das Modul wird von der Arduino Spannungsversorgung gespeist)
  2. Das Auslesen vom DCF77 mit der Library (DCF77.h) funktioniert wunderbar, ich bekomme die Zeit über tm.elements (TimeLib.h) wunderbar angezeigt.
    Da die tm.elements das Gleiche sind wie Byte, (glaube ich, uint8_t = Byte ?) wandle ich diese um in BCD um sie dann zum DS3231 zuschicken. Doch leider ändert sich die Uhrzeit nicht, die Daten werden komplett ignoriert vom Modul.
    Wenn ich aber das DS3231 mit vorgegeben Byte Variablen füttere funktioniert es nur halt nicht über tm.elements. Deshalb geht meine Vermutung eher in Richtung tm.element (von der TimeLib.h) oder in dem Ablauf meines Sketches .
#include <Wire.h>
#include <DCF77.h>       
#include <TimeLib.h>        

#define DCF_PIN 2           // Connection pin to DCF 77 device
#define DCF_INTERRUPT 0    // Interrupt number associated with pin
#define DS3231_ADDRESSE 0x68

time_t time;
DCF77 DCF = DCF77(DCF_PIN,DCF_INTERRUPT);

//##################################
void setup() {
 Serial.begin(9600); 
 DCF.Start();
 Serial.print("Start");
}
//##################################
void loop() {
  delay(100);
  time_t DCFtime = DCF.getTime();
  if (DCFtime!=0) {
    digitalClockDisplay(DCFtime);
    Serial.print("Time is updated");  
  } 
}
//###################################

void digitalClockDisplay(time_t _time){
  tmElements_t tm;   
  breakTime(_time, tm);

//DCF Zeit, funktioniert
  Serial.println("");
  Serial.print("Time: ");
  if((tm.Hour)<10){Serial.print("0");}
  Serial.print(tm.Hour);
  Serial.print(":");
  if((tm.Minute)<10){Serial.print("0");}
  Serial.print(tm.Minute);
  Serial.print(":");
  if((tm.Second)<10){Serial.print("0");}
  Serial.print(tm.Second);
  
  Serial.print(" Date: ");
  Serial.print(tm.Day);
  Serial.print(".");
  Serial.print(tm.Month);
  Serial.print(".");
  Serial.println(tm.Year+1970);

  Serial.println("DCF77 works");

DCF.Stop(); // interrupt stoppen

  //DS3231 stellen, funktioniert noch nicht
    Wire.beginTransmission(DS3231_ADDRESSE);
    Wire.write(0);
    Wire.write(decToBcd(tm.Second)); // Sekunden einstellen
    Wire.write(decToBcd(tm.Minute)); // Minuten einstellen
    Wire.write(decToBcd(tm.Hour));
    Wire.write(decToBcd(2)); // 1=Sonntag ... 7=Samstag
    Wire.write(decToBcd(tm.Day));
    Wire.write(decToBcd(tm.Month));
    Wire.write(decToBcd(18)); // 0...99
    Wire.endTransmission();

    Serial.print("DS32131 updated");

 DCF.Start(); // interrupt wieder Starten
}


// Umrechnung BCD <--> Byte

byte decToBcd(byte val) {
// Dezimal Zahl zu binary coded decimal (BCD) umwandeln
  return((val/10*16) + (val%10));
}


byte bcdToDec(byte val) {
// BCD (binary coded decimal) in Dezimal Zahl umwandeln
  return((val/16*10) + (val%16));
}

Das Auslesen vom DS3231 und die Wiedergabe auf dem Display habe ich noch in einem extra Sketch, das funktioniert schon.

Vielleicht könnt Ihr mir helfen, wie ich das DS3231 über die TimeLib.h stellen kann.
Danke schon mal. :slight_smile:

Serial.println (tm.minute, DEC);
int m = tm.minute;
Serial.println (m);
Serial.println ( decToBcd (m), HEX);
Serial.println ( decToBcd (tm.minute), HEX);

sollte vier mal dasselbe ausgeben. Und beide decToBcd Varianten sollten gleich geeignet sein, deine Uhr zu stellen.

  1. Das DS3231 geht in 24h um 2 Minuten nach, (Abblock Kondensator VCC/GND, 220nF Keramik, ist vorhanden, das Modul wird von der Arduino Spannungsversorgung gespeist)

Das wundert mich stark. Diese Abweichung habe ich nicht mal in einem Jahr. Da ist die PC Uhr die ich zum Vergleich benutzte ungenauer und nach einer Netzsynchronisation stimmte dann die PC Uhr mit dem DS3231 überein.

Nimm eine Ds3231 Bibliothek.

Grüße Uwe

Okay, hat vielleicht einer eine Idee wie ich mit der DS3231.h über die tm.elements das Modul stellen kann?

Indem Du Dir in [u]Deiner[/u] DS3231.h (es gibt mehrere unterschiedliche Libs) die Methode setDateTime anschaust.

Gruß Tommy

Lösung: Ich habe mir mal die DS3231 Library angeschaut und mit

DS3231 clock; ... clock.setDateTime(2018,tm.Month,tm.Day,tm.Hour,tm.Minute,tm.Second); ...

funktioniert es!

Nur für das Jahr muss ich mir noch was einfallen lassen, da die DS3231.h mit dem Jahr 2000 rechnet und die TimeLib.h mit 1970, aber das bekomme wohl noch gerade gerechnet :)

Das Problem mit der Ungenauigkeit vom DS3231 habe ich auch gelöst, habe mir einfach ein neues Modul gekauft und das funktioniert wunderbar, also lag der Fehler wohl nicht zwischen meinen Ohren sondern an einem fehlerhaften Modul.

Vielen Dank, bis zum nächsten Problem ;-)

Fein!

Donz92: Das Problem mit der Ungenauigkeit vom DS3231 habe ich auch gelöst, habe mir einfach ein neues Modul gekauft und das funktioniert wunderbar, also lag der Fehler wohl nicht zwischen meinen Ohren sondern an einem fehlerhaften Modul.

War also möglicherweise die Temperaturmessung bzw Kompensation durch die Temperatur fehlerhaft. Grüße Uwe

Hallo Uwe, du hast recht, ich habe gerade die Temperatur ausgelesen, über die DS3231.h,

Bei dem defekten Modul bekomme ich keine Temperatur raus. Bei dem funktionierenden Modul bekomme ich 17Grad raus, das passt.

Grüße, Donz