• Hallo Zusammen, Aufgrund der aktuellen Situation setzten wir die Möglichkeit aus, sich mit Gmail zu registrieren. Wir bitten um Verständnis Das RCMP Team

Anleitung Arduino mit DCF77-Modul und RTC Echtzeituhr DS3231

norju

Mitglied
Voreilig, wie ich bin, habe ich das bisherige Geraffel deinstalliert/gelöscht und die Downloads von Dir aktiviert. Siehe da, gleich das erste Kompilieren und Überprüfen verlief ohne eine einzige Fehlermeldung :D. Dafür nochmals Danke für Deine Mühe :thumbsup:. Übrigens habe ich Deine Libraries direkt in das entsprechende Verzeichnis der IDE entpackt, ohne sie nochmals mit dem Bibliothekenverwalter einzubinden. Sie wurden anscheinend auch so implementiert. Im Bibliothekenverwalter hatte ich, auch im Nachhinein, keine Auswahlmöglichkeit für lokale Verzeichnisse entdecken können. Die IDE erkennt anscheinend eigenständig die zur Verfügung stehenden Libs und bindet sie ein. Den Praxistest muss ich nun doch auf später verlegen und melde mich danach wieder....
 

BAXL

Admin
Mitarbeiter
Hi norju, es freut mich, dass es jetzt so gut funktioniert hat. Leider bekomme ich nicht immer ein Rückmeldung ob und wie es gelaufen ist.

Dann noch viel Erfolg bei dem Projekt.

Vielleicht magst Du in einem eigenen Thema vorstellen, was Du daraus gemacht hast. Das muß nicht so ausführlich wie dieses Thema hier sein, wichtig ist, dass man daraus eine Anregung ziehen kann.
 

norju

Mitglied
Moin BRAXL, die ersten Praxistests sind ebenfalls erfolgreich verlaufen. Genial :D, so habe ich mich auch gleich daran gemacht und die Display-Inhalte etwas individualisiert. Darüber hinaus konnte ich durch eine PWM-gesteuerte I2C-Regelung die Hintergrundbeleuchtung des Displays an Umgebungsverhältnisse anpassen. Geplant ist, sie von der Uhrzeit oder den Lichtverhältnissen regeln zu lassen. Mal sehen, was mir sonst noch so einfällt....
 

norju

Mitglied
Moin BRAXL, vielen Dank. Da hast Du mich ja ordentlich mit Futter versorgt ;). Es wird wohl noch etwas dauern, bis ich dazu komme. Mit der vorliegenden Ausgabe möchte ich erst einmal etwas tiefer in deren Strukturen "eintauchen".
 

norju

Mitglied
Moin BAXL, bevor ich mit der Helligkeitssteuerung für das LCD fortfahre, habe ich noch etwas mit der RTC experimentiert. Im Verlauf der Experiment war die RTC ohne Auffälligkeiten mit Voreinstellungen zu versehen. Bei den Fortsetzungen mit der DCF-Funkuhr habe ich mit gleicher Syntax und gleichen Werten ebenfalls eine Voreinstellung vorgenommen. Dabei fiel mir auf, dass die RTC lediglich das Datum jedoch nicht die Uhrzeit übernommen hat. Die beginnt jedesmal abweichend mit 00:00:00 Uhr.
Meine Frage nur so zum Verständnis: Warum verhält sich die selbe RTC im anderen Sketch so diferenziert? Ich kann damit leben, da sich die Funkuhr ja sehr schnell mit DCF synchronisiert. Es geht nur darum, das Verhalten der RTC zu verstehen......
 

BAXL

Admin
Mitarbeiter
Moin BAXL, bevor ich mit der Helligkeitssteuerung für das LCD fortfahre, habe ich noch etwas mit der RTC experimentiert. Im Verlauf der Experiment war die RTC ohne Auffälligkeiten mit Voreinstellungen zu versehen. Bei den Fortsetzungen mit der DCF-Funkuhr habe ich mit gleicher Syntax und gleichen Werten ebenfalls eine Voreinstellung vorgenommen. Dabei fiel mir auf, dass die RTC lediglich das Datum jedoch nicht die Uhrzeit übernommen hat. Die beginnt jedesmal abweichend mit 00:00:00 Uhr.
Meine Frage nur so zum Verständnis: Warum verhält sich die selbe RTC im anderen Sketch so diferenziert? Ich kann damit leben, da sich die Funkuhr ja sehr schnell mit DCF synchronisiert. Es geht nur darum, das Verhalten der RTC zu verstehen......
dazu müsste ich den Code sehen... Das kann ich so nicht beantworten. :)
 

norju

Mitglied
Moin BAXL, sorry bin jetzt erst wieder online. Anliegend der Code, den ich kürzlich von Dir bekam und nur in Nuancen verändert habe. In Zeile 78 erhält die RTC eine fiktive Zeit, um den Unterschied zum tatsächlichen Wert erkennen zu können. Im Sketch für meine RTC-Experiment steht die gleiche Zeile.
 

Anhänge

BAXL

Admin
Mitarbeiter
Du kannst Code auch direkt in den Post packen. Dazu auf die drei Punkte klicken. Und dann auf </>Code. Da kannst Du das Listing reinkopieren.
ich gucke viel am Smartphone, da ist es mit einer Zip etwas umständlicher. :)
 

norju

Mitglied
Sorry, das kannte ich noch nicht.
Code:
//  https://www.rc-modellbau-portal.de/index.php?threads/arduino-mit-dcf77-modul-und-rtc-echtzeituhr-ds3231.8278/

//  ################################
//  kein Antennensymbol, neue Aufteilung der Zeilen
//  ################################


//Code um einen Arduino Nano Clone mit DCF77 Modul von ELV zu verbinden und Zeit auszulesen.
//Zur Überbrückung von Empfangsstörungen, bzw. wenn die DCF-Signalauswertung deaktiviert wird,
//steht eine RTC DS3231 parat, die parallel läuft

//DCF77.h und TimeLib.h wurden ohne Anpassungen verwendet.
//DCF77 Bibliothek wurde von hier erhalten: http://thijs.elenbaas.net/downloads/?did=1
//TimeLib.h Bibliothek wurde von hier erhalten: https://github.com/PaulStoffregen/Time
//Die Sketch-Vorlage wurde von hier geladen (hier werden auch andere Module behandelt): https://www.issb.de/mw/index.php/Test_elektronischer_Funkuhren-Module_(DCF77)_am_Mikroconcroller


// Librarys für DCF77 Funkuhrmodul
#include "DCF77.h" //Alle DCF77 Funktionen laufen ueber diese Bibliothek.
#include "TimeLib.h" //Time.h hat bei mir nie funktioniert, habe TimeLib.h eingebunden, dann gehts.
//#include <DS1307RTC.h>
#include "RTClib.h"
// Librarys für LCD-Display
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

#define DCF_PIN 2 // Verbindung zum DCF77 Arduino UNO PIN
#define DCF_INTERRUPT 0 // Interrupt number associated with pin
#define PIN_LED 13 // Status von der Verbindung an LED-PIN 13

bool g_bDCFTimeFound = false; // wurde ein gueltiges DCF77 Signal gefunden?

/*uint8_t ant[]  = { 
  B00100,
  B01010,
  B10001,
  B00100,
  B00100,
  B00100,
  B00100,
  B00100
};
*/ //####################### kann entfallen

// Variablen für die Auswertung und den Abgleich der Zeiten
byte ErstStart = 1;
byte DCFaktiv = 0;
byte DCFZeitOK = 0;
long Intervall = 120000; // Abfrageintervall 2 Minuten
long UpdateTimer = 0; // Zwischenspeicher für die Wartezeit
int belpin=9; // Pin für die PWM-Steuerung der Hintergrundbeleuchtung
int zeichenPos = 11;
int laengeWochentag;
int laengeMonat;
char nameMonat[10];

DCF77 DCF = DCF77(DCF_PIN, DCF_INTERRUPT); // Dieser Eintrag sollte für andere Module aktiviert werden...
// für das DCF-Modul von ELV muss das Signal invertiert werden, deshalb so:
//  DCF77 DCF = DCF77(DCF_PIN, DCF_INTERRUPT, false); // false für invertiertes Signal

LiquidCrystal_I2C lcd(0x27, 20, 4); //Hier wird festgelegt um was für einen Display es sich handelt.

//  RTC_DS3231 rtc; // Es wird eine Objekt rtc aus der Klasse RTC_3231 der RTClib.h erstellt
RTC_DS1307 rtc;

void setup()
{
pinMode(belpin, OUTPUT); // PWM Pin ist ein Ausgang
pinMode(PIN_LED, OUTPUT);

//Serial.begin(9600); // Seriellen Monitor starten

DCF.Start(); // DCF Uhr starten
DCFaktiv=1; // Merker, dass das DCF77 Signal ausgerwetet wird, man kann das mit DCF.Stop(); anhalten

rtc.begin(); // RTC starten
//  Voreinstellung von RTC
rtc.adjust(DateTime(2020, 10, 28, 13, 26, 30));

lcd.init(); //Im Setup wird der LCD gestartet
lcd.backlight(); //Hintergrundbeleuchtung einschalten (lcd.noBacklight(); schaltet die Beleuchtung aus).
//  lcd.createChar(0, ant);//####################### kann entfallen

lcd.setCursor(0, 3); // Spalte, Zeile,  0, 0 entspricht 1. Spalte oder 1. Zeile
lcd.print("DCF77 V2.6  aktiv: "); lcd.print(DCFaktiv);
}

void loop()
{
// das Signal wird nur alle 5 Sekunden abgefragt
delay(1000);

digitalWrite(PIN_LED, HIGH);
delay(50);
digitalWrite(PIN_LED, LOW);

DCFZeitOK = 0; // noch kein gültiges DCF-Telegramm empfangen
time_t DCFtime = DCF.getTime(); // Prüfen ob eine neue DCF77 Zeit verfügbar ist

  if (DCFtime != 0)
  {
//    Serial.println("Aktuelle Zeit wurde empfangen!");
    setTime(DCFtime);
    g_bDCFTimeFound = true;
    DCFZeitOK=1;
  }

  // die Uhrzeit wurde gesetzt, also LED nach kurzer Zeit ein
  if (g_bDCFTimeFound)
  {
    delay(50);
    digitalWrite(PIN_LED, HIGH);
  }

if ((DCFZeitOK=1)&&(year()>2019)&&(((millis()-UpdateTimer) > Intervall)) )
{
  ErstStart = 0;
  // Wenn eine gültige DCF77 Zeit vorliegt, das DCF Jahr > 2019 und Intervall vergangen ist, die RTC aktualisieren
  RTCUpdate();
  UpdateTimer = millis();

//  LCD-Zeile 3 vollständig löschen
  int neuZeile = 0;
  lcd.setCursor(0, 3);
  while (neuZeile <= 20){
  lcd.print(" ");
  neuZeile++;
  }
//  Zeitpunkt des letzten Sync anzeigen
  lcd.setCursor(2, 3); // Spalte, Zeile,  0, 0 entspricht 1. Spalte oder 1. Zeile
  lcd.print("Last Sync: ");
  DateTime aktuell = rtc.now();
  //Stunde = (aktuell.hour()); Minute = (aktuell.minute()); Sekunde = (aktuell.second());
  if (aktuell.hour() <10){lcd.print("0");} lcd.print(aktuell.hour()); lcd.print(":");
  if (aktuell.minute() <10){lcd.print("0");} lcd.print(aktuell.minute());// lcd.print(":");
//  if (aktuell.second() <10){lcd.print("0");} lcd.print(aktuell.second());  lcd.print("    ");
}

//  Hintergrundbeleuchtung in Abhängigkeit der Uhrzeit (Stunde)
//  Zwischen 21 Uhr abends und 7 Uhr morgens abdunkeln
  if(hour() > 21 || hour() < 7)
  { 
    analogWrite(belpin, 10); // Beleuchtung 255(hell) - 0(dunkel)
  }
  else
  {
    analogWrite(belpin, 250); // Beleuchtung 255(hell) - 0(dunkel)
  }
//  Ende Dimmersteuerung

digitalClockDisplay(); // DCF77 Zeit anzeigen
RTCClockDisplay(); // DCF77-Zeit für RTC- Zeit übernehmen
}

void RTCUpdate()
{
// Datum und Uhrzeit der DCF77 in RTC übertragen
rtc.adjust(DateTime(year(), month(), day(), hour(), minute(), second()));
}

void RTCClockDisplay()
{
  // Anzeigen der RTC-Zeit auf dem 20x4 LCD-Display
  int Stunde; int Minute; int Sekunde;
  int Tag; int Monat; int Jahr;

  DateTime aktuell = rtc.now();
  Stunde = (aktuell.hour()); Minute = (aktuell.minute()); Sekunde = (aktuell.second());
  Jahr = (aktuell.year()); Monat = (aktuell.month()); Tag = (aktuell.day());
  //  LCD-Zeile 2 vollständig löschen
  int neuZeile = 0;
  lcd.setCursor(0, 1);
  while (neuZeile <= 20){
  lcd.print(" ");
  neuZeile++;
  }
  char dayName[7][12] = {"Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"};
  //  Textlänge für zentrierte Anzeige des Wochentags
  laengeWochentag = strlen(dayName[aktuell.dayOfTheWeek()]);
  lcd.setCursor(9 - laengeWochentag / 2, 1);
  lcd.print(dayName[aktuell.dayOfTheWeek()]);

char nameMonat[13][10] = {"k.a.", "Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"};
//  Textlänge des Monatsnamens für zentrierte Anzeige des Datums mit ausgeschriebenen Monatsnamen
laengeMonat = strlen(nameMonat[Monat]);
lcd.setCursor(5 - laengeMonat / 2, 2);
  if (Tag <10){lcd.print("0");} lcd.print(Tag); lcd.print(". ");
lcd.print(nameMonat[Monat]);
lcd.print(" ");
lcd.print(Jahr);
}

void digitalClockDisplay()
{
// Anzeigen der Zeit auf dem 20x4 LCD-Display

lcd.setCursor(6, 0);
  if (hour()<10){lcd.print("0");} lcd.print(hour()); lcd.print(":");
  if (minute()<10){lcd.print("0");} lcd.print(minute()); lcd.print(":");
  if (second()<10){lcd.print("0");}lcd.print(second()); lcd.print(" ");

}
 

norju

Mitglied
Ja, genau die meinte ich. In dem Sketch für meine RTC-Experimente hatte ich sie mit gleichen Werten verwendet und die RTC stellte sich auf die gewünschten Werte ein. Der DCF77-Sketch übernimmt nur das Datum und nicht die Uhrzeit. An der Stelle stellt sich die gleiche RTC auf 00:00:00 Uhr ein.
 

BAXL

Admin
Mitarbeiter
Stellt sich die Uhr denn nach einer gewissen Zeit richtig nach DCF77 Zeit ein, oder bleibt die Uhrzeit bei 00:00:00?
 

norju

Mitglied
Sobald sie vom DCF-Modul eine gültige Zeit bekommt, dann wird diese auch übernommen. Wie gesagt, das war auch nicht das Problem. Mir ging es lediglich darum, warum die RTC nicht die vorgegebene Voreinstellung vollständig übernimmt. Alles Andere ist fein und sehr zufriedenstellend.
 

BAXL

Admin
Mitarbeiter
Dann bleibt als Ursache nur noch das Zahlenformat in dem Funktionsaufruf. Das müsste ich mir dann aber auch erst im Quellcode der Library, oder mindestend im Vereinbarungsteil ansehen.

Edit:
Ist sehr mysteriös, weil ich das genau so in einem anderen Sketch mache.
Was sagtest Du, was Du für ein RTC-Modul jetzt im Einsatz hast?
 
Zuletzt bearbeitet:

norju

Mitglied
Es handelt sich um eine DS1307 von Reichelt, die bisher ohne Mucken ihren Dienst absolviert. Bei meinen RTC-Experimenten habe ich damit Weckfunktion, Weckwiederholungen, automatisches Beenden der Weckfunktion usw. erfolgreich einrichten können.
 

BAXL

Admin
Mitarbeiter
In der Lib für den RTC1307 gibt es keine Funktion adjust, darum wird das auch nicht funktioniert haben.

Edit:
Beim RTC1307 wird das etwa so aussehen müssen (habe ich aus einem Beispielprogramm der Lib
Code:
void setup() {
  bool parse=false;
  bool config=false;

  // get the date and time the compiler was run
  if (getDate(__DATE__) && getTime(__TIME__)) {
    parse = true;
    // and configure the RTC with this info
    if (RTC.write(tm)) {
      config = true;
    }
  }
 
Zuletzt bearbeitet:

norju

Mitglied
Darüber hinaus muss ich einen groben Denkfehler eingestehen. Am Ende des Sketches wird die DCF-Zeit geholt und angezeigt:
Code:
void digitalClockDisplay()
{
// Anzeigen der Zeit auf dem 20x4 LCD-Display

lcd.setCursor(6, 0);
  if (hour()<10){lcd.print("0");} lcd.print(hour()); lcd.print(":");
  if (minute()<10){lcd.print("0");} lcd.print(minute()); lcd.print(":");
  if (second()<10){lcd.print("0");}lcd.print(second()); lcd.print(" ");

}
Damit ignoriere ich die RTC-Zeit und bin auf die selbstverständlich mit 00:00:00 beginnende DCF-Zeit hereingefallen. Sorry, dass ich Dich damit vergeblich bemüht habe :sneaky:.
 

BAXL

Admin
Mitarbeiter
Darüber hinaus muss ich einen groben Denkfehler eingestehen. Am Ende des Sketches wird die DCF-Zeit geholt und angezeigt:
Code:
void digitalClockDisplay()
{
// Anzeigen der Zeit auf dem 20x4 LCD-Display

lcd.setCursor(6, 0);
  if (hour()<10){lcd.print("0");} lcd.print(hour()); lcd.print(":");
  if (minute()<10){lcd.print("0");} lcd.print(minute()); lcd.print(":");
  if (second()<10){lcd.print("0");}lcd.print(second()); lcd.print(" ");

}
Damit ignoriere ich die RTC-Zeit und bin auf die selbstverständlich mit 00:00:00 beginnende DCF-Zeit hereingefallen. Sorry, dass ich Dich damit vergeblich bemüht habe :sneaky:.
:D kein Problem. Das Wichtigste ist, dass Du den Fehler gefunden und auch hier im Thema kommuniziert hast. :thumbsup: Vielleicht hilft das jemand anderes noch.

Leider erhalte ich nicht von jedem eine Rückmeldung ob es geklappt, oder auch nicht geklappt hat, darum Dir vielen Dank für das feedback.
 
Top Bottom