DCF77 – macht keinen Spaß

Hallo,

ich versuche mit einem UNO, einem DHT22 und einem DCF1 von Pollin mir eine Textzeile zu bauen, die vielleicht etwa so aussehen soll:

hh:mm:ss - XX°C - XX %

Später soll das ganze mit einem GSM Modul per SMS übertragen werden.

Also ich bekomme es hin, dass mir die Messwerte angezeigt werden. Das war einfach!

Mit der Funkzeit ist das schon schwieriger. Finde erst mal einen Sketch und eine Library die sich fehlerlos laden lassen...
Zum Teil funktionieren die Links nicht mehr, usw. Hab dann was gefunden, was funktioniert.

Als ich dann beide Programmmodule kombinieren wollte, habe ich gemerkt, dass der Serial.print in der CPP Datei und nicht in meiner ino Datei.

Ich würde gerne einfach nur die Uhrzeit und das Datum auslesen. Gibt es nicht eine einfache Möglichkeit sich mit ein paar Grundbefehlen was zusammenzubauen?

Ach so, noch was: bin erst seit einer Woche mit dem Arduino-Thema dran, also ein Neuling…

Grüße

colmans

Hallo,
das schon probiert?
http://playground.arduino.cc/Code/DCF77
Gruß und Spaß
Andreas

Hallo Andreas,

danke für Deine Antwort!!!

Ja, die Library habe ich runtergeladen und installiert.
Wenn ich mir den Code auf der Seite (Example sketch) kopiere und kompiliere, bekomme ich wie so oft auch mit anderen Sketches eine Fehlermeldung:

'time_t' does not name a type

sketch_aug27a.ino:1:19: error: DCF77.h: No such file or directory
sketch_aug27a.ino:2:18: error: Time.h: No such file or directory
sketch_aug27a:7: error: 'time_t' does not name a type
sketch_aug27a:9: error: 'DCF77' does not name a type
sketch_aug27a.ino: In function 'void setup()':
sketch_aug27a:13: error: 'DCF' was not declared in this scope
sketch_aug27a.ino: In function 'void loop()':
sketch_aug27a:20: error: 'time_t' was not declared in this scope
sketch_aug27a:20: error: expected `;' before 'DCFtime'
sketch_aug27a:21: error: 'DCFtime' was not declared in this scope
sketch_aug27a:24: error: 'setTime' was not declared in this scope
sketch_aug27a.ino: In function 'void digitalClockDisplay()':
sketch_aug27a:31: error: 'hour' was not declared in this scope
sketch_aug27a:32: error: 'minute' was not declared in this scope
sketch_aug27a:33: error: 'second' was not declared in this scope
sketch_aug27a:35: error: 'day' was not declared in this scope
sketch_aug27a:37: error: 'month' was not declared in this scope
sketch_aug27a:39: error: 'year' was not declared in this scope

Leider habe ich keinen blassen Schimmer was ich tun soll!

Hallo,
ah, MacUser- guter Junge...
Mache aus Deinen 2en DCF77 Ordner mal einen. Da sind die Lib´s falsch installiert.
Gruß und Spaß
Andreas

Hallo,
in Deinem LibOrdner kopierst Du die Ordner
DCF77
Time
Timezone
einzeln.
D.h. Du fügst Deinem LibOrdner 3 Ordner hinzu.
Gruß und Spaß
Andreas

Bildschirmfoto 2014-08-27 um 21.45.png

hab gerade gesehen, dass der Pfad im Library Ordner falsch war... Das Kompilieren klappt. Danke!

Dass ich seit 5 Minuten so etwas erhalte liegt am schlechten Empfang:
0:04:51 1.1.1970

Hallo,
wenn die Sekunden laufen ja. Versuche einmal die Antenne auszurichten. z.B. waagerecht.
Gruß und Spaß
Andreas

colmans:
Dass ich seit 5 Minuten so etwas erhalte liegt am schlechten Empfang:
0:04:51 1.1.1970

Was für störende Geräte Du im Umkreis des DCF-Empfängers vermeiden mußt, hatte ich hier erst vor zwei Tagen in einem anderen Thread gepostet, aber ich kopiere es Dir gerne nochmal heraus:

Falls Du DCF verwendest, dann achte bitte darauf, dass Du ALLE FUNK-STÖRQUELLEN IN ZWEI METER UMKREIS um das DCF-Modul entfernst. Also alles dies muß mindestens zwei Meter entfernt vom DCF-Modul sein, wenn Du Empfang haben möchtest (unvollständige Liste):

  • GSM Handys und Smartphones
  • UMTS Handys und Smartphones
  • Schnurlose Telefone mit DECT oder anderen Funkstandards
  • 433 und 868 MHz Short Range Devices (z.B. Funk-Wettersensoren, Babyphones, schnurlose Kopfhörer)
  • alles mit WLAN (Handy, mobile Computer, Router)
  • alles mit Bluetooth
  • alle Monitore
  • alle Computer
  • alle Leuchtstoffröhren
  • alle Energiesparlampen
  • alle Schaltnetzteile
    All das (und anderes mehr) darf in zwei Metern Umkreis um das DCF-Modul nicht betrieben werden, sonst stört es.

der empfänger hängt innen am fenster verbunden mit einem langen usb-kabel 1,5 bis 2 m lang. das fenster ist richtung westen mainflingen liegt aber auf der anderen seite... :wink:

im zimmer ist alles vorhanden, handy, notebook, wlan, etc. also volles programm. mein alter 80er jahre junghans funkwecker funktioniert aber.

colmans:
der empfänger hängt innen am fenster verbunden mit einem langen usb-kabel 1,5 bis 2 m lang. das fenster ist richtung westen mainflingen liegt aber auf der anderen seite... :wink:

Zwei Meter USB-Kabel sind schon mal schön, um damit aus dem Funk-Störnebel von PC und Monitor herauszukommen. Fensternähe muss bei DCF-Empfängern nicht sein (ist dagegen bei GPS-Empfängern vorteilhaft), aber vorteilhaft wäre in einem Gebäude die oberste Etage für besten Empfang, mindestens aber ein Mindestabstand von 2m zu allen potentiellen Störquellen sollte sein.

colmans:
im zimmer ist alles vorhanden, handy, notebook, wlan, etc. also volles programm. mein alter 80er jahre junghans funkwecker funktioniert aber.

Dein DCF-Wecker hat insofern bessere Empfangsbedingungen als er nicht an einem USB-Kabel angeschlossen ist: Auf USB-Kabeln laufen Signale mit hohen Megabit-Raten und alleine deshalb geben auch USB-Kabel einen Funk-Störnebel ab, der das Signal-Rauschverhältnis und den Empfang auf Langwelle verschlechtern.

Das Pollin-Modul ist hin bis zu mittleren Störpegeln eigentlich keine schlechte Wahl, wenn Du eine Library mit Schwächen bei der Signalauswertung verwendest (so wie es eigentlich bei fast allen Arduino-DCF-Libraries der Fall ist). Denn das Pollin-Modul hat einen eingebauten Tiefpassfilter, der dafür sorgt, dass von kleinen bis hin zu mittleren Störpegeln ein sauber gefiltertes Signal am Ende herauskommt.

Schau Dich nochmal in Fensternähe um, ob da nicht doch noch ein Störer herumliegt: Vielleicht liegt das DECT-Schnurlostelefon auf der Fensterbank? Eine Energiesparlampe oder ein Schaltnetzteil in der Nähe? Zwei Meter Mindestabstand sollten reichen.

Ansonsten kann ich Dir mal anbieten, ein "DCF-Testprogramm" hier zu posten, das ich vor kurzem mal gemacht habe, speziell für Empfänger, die kein sauberes Signal ausgeben, sondern bei denen der Ausgang etwas "zappelig" ist.

hi jurs, dein angebot würde ich dankend annehmen!

colmans:
hi jurs, dein angebot würde ich dankend annehmen!

Ich hänge das Testprogramm mal als ZIP-Archiv zum Downloaden dran.

Installation:
Den in der ZIP-Datei enthaltenen Ordner "DCF_PulseTest" in den Arduino-Sketchordner kopieren.
Dann kann ein Arduino-Sketch mit gleichem Namen geöffnet werden, der drei Tab-Fenster enthält.

Konfiguration:

Für DCF-Module mit Push-Pull Ausgang wie das Pollin-Modul:
#define DCFPULLUP false

Für DCF-Module, die einen aktiven PullUp-Widerstand benötigen wie das Conrad-Modul:
#define DCFPULLUP true

Es können bis zu zwei LEDs angesteuert werden, auf denen das DCF-Signal zur optischen Signalkontrolle ausgegeben wird. Auf dem mit DCFLEDRAW konfigurierten LED-Pin wird das Rohdaten-Signal ausgegeben und auf dem mit DCFLEDFILTERED konfigurierten Pin wird das gefilterte Signal ausgegeben. Vorkonfiguriert ist die Ausgabe des Rohdatensignals auf der Board-LED an Pin-13:
#define DCFLEDRAW 13

Der Empfängerpin ist frei wählbar.

Die Testausgabe erfolgt auf Serial. Und zwar wird einmal pro Sekunde eine Zeit ausgegeben. Falls die Zeit noch nicht synchronisiert wurde, ist ein Sternchen vorangestellt, z.B. acht Sekunden nach Programmstart, nicht synchronisiert:
*00:00:08

Die Synchronisierung auf die aktuelle Zeit dauert 1 bis 2 Minuten bei ungestörtem Signal. Bei gestörtem Signal ist es nicht vorhersehbar. Nach der ersten Synchronisierung wird die Zeit ohne führendes Sternchen angezeigt, z.B:
08:52:13

Das Kalenderdatum wird bei diesem Testprogramm derzeitig nicht ausgewertet und nicht angezeigt.

Wenn DCF-Impuise empfangen werden, werden diese wie folgt angezeigt (Beispiel), immer im Wechsel die aktuelle Zeit und die Information zum empfangenen Sekunden-Impuls:

H 115	L 886	P 1001	14
08:52:14
H 205	L 794	P 999	15
08:52:15
H 113	L 880	P 993	16
08:52:16
H 114	L 880	P 994	17
08:52:17
H 230	L 777	P 1007	18
08:52:18

H - Signaldauer HIGH in Millisekunden (typisch 100 oder 200ms)
L - Signaldauer LOW in Millisekunden
P - Impulsdauer (Summe der beiden vorstehenden)
Bitnummer (zählt bei korrekt erkannten Signal-Bits hoch bis 59, und springt bei der Minutenmarke auf 1)

Wenn die Bitnummer nicht bis 59 zählt, sondern vorher zurück auf 1 springt, konnte ein Bit nicht korrekt ausgewertet werden oder es wurde eine Minutenmarke erkannt.

Probier's mal aus!

Ist wie gesagt nur ein Testprogramm. Allerdings eins, das aufgrund einer speziellen Signalfilterung gestörte DCF-Signale vom DCF-Empfänger besonders gut auswerten kann. Allerdings bringt das bei "schnellen" DCF-Modulen wie dem Conrad-DCF-Empfänger mehr als bei den bereits "tiefpassgefilterten" Empfängern wie dem Pollin-Modul.

Für reale Anwendungen muß das Konzept noch umgestellt werden: Das Testprogramm sampelt das Signal einmal pro Millisekunde und synchronisiert dazu die loop-Funktion so, dass diese einmal pro Millisekunde läuft. Du kannst daher in der loop nur Code einfügen, der unter 1ms läuft, sonst bricht der Empfang zusammen. Falls Du vorhast, eine reale Anwendung mit Code dranzustricken, der länger braucht, bitte Bescheidgeben, ich kann dann mal überlegen, wie ich das am besten dranstricke.

(Angehängte Datei wegen inzwischen erkannten Programmfehlern entfernt,
Fehler- und Korrekturhinweise siehe Reply #16.)

@ jurs: super, danke ich probier es heute abend mal aus…

Hi,
wenn du zufällig ein Ethernetanschluss an deinem Board hast, kannst du dir die Zeit auch ziemlich einfach aus dem Internet ziehen.
Das ist dann auch unabhängig und störungsresistent.

Gruß
Miller

Schon der Testsketch von jurs ist wieder mal schon sehr gut gemacht.
Baue gerade eine DCF Lib für ein Nucleo Board der auch funktioniert,nur zum Sammeln der Bits habe ich ein unsigned char rawdata[60] genommen und schreibe dort 0 ..1 rein.
Ist natürlich eine Verschwendung mir ist aber nichts bessers eingefallen, was nimmt jurs: long long 8) "again what learned" würde Lothar Mathäus sagen.

Zum Thema DCF77 macht keinen Spaß:
Ich habe auch schlechte Erfahrungen gemacht, die Störquellen sind wie schon angesprochen vielfältig.
Ein gutes Empfangmodul und eine gut ausgerichtete Feritantenne bringt schon viel.
Es sind auch optimierte Bauanleitungen im Web zu finden.
Wenn man dann noch hinnimmt das DCF nicht immer möglich ist, sondern nur zum Gelegentlichen Abgleich der time_t dient kann man damit ganz gut leben.

NTP oder GPS wäre eine stabilere Alternative, bei letzterem ist im nmea Protokoll u.a auch die genaue Zeit enthalten

rudirabbit:
Schon der Testsketch von jurs ist wieder mal schon sehr gut gemacht.
Baue gerade eine DCF Lib für ein Nucleo Board der auch funktioniert,nur zum Sammeln der Bits habe ich ein unsigned char rawdata[60] genommen und schreibe dort 0 ..1 rein.
Ist natürlich eine Verschwendung mir ist aber nichts bessers eingefallen, was nimmt jurs: long long 8) "again what learned" würde Lothar Mathäus sagen.

Tja, warum 60 Bytes für etwas verschwenden, das man auch in 8 Bytes (=64 Bits) unterbringen kann, habe ich mir gesagt.

Aber Vorsicht mit den Arduino Bit-Makros (bitRead, bitSet, bitWrite etc.), diese Makros funktionieren mit "long long" nicht für die oberen 32 Bits!

Eben gerade habe ich auch noch zwei Fehler in meinem Code entdeckt,

Erstens werden wohl die Parity-Bits im DCF-Zeittelegramm nicht korrekt ausgewertet.

Und der Beispiel-Sketch funktioniert leider nur täglich zwischen Mitternacht und 18:12 Uhr.

In meinem Bestreben, ein paar Bytes zu sparen, ist mir wohl irgendwie eingefallen, die "Sekunden seit Mitternacht" in einer unsigned int Variablen zu übergeben. Das reicht leider nicht, denn es müssen bis 23:59 Uhr Zahlen übergeben bis hoch zu:
233600+5960 = 86340
Das passt natürlich nicht mit unsigned int, wo bei 65535 Schluss ist.

Korrekterweise müßte die Callback-Funktion in meinem Test-Sketch also auf "unsigned long" statt "unsigned int" umgeschrieben werden:

int dcfCallback(byte result, unsigned long param1, unsigned long param2, byte param3)

Sonst funktioniert der Code nur täglich von Mitternacht bis vor 18:12 Uhr am Abend.

Irgendwas ist ja immer, wenn man etwas neu programmiert hat.
:cold_sweat:

Es ist auch kein Problem sich eine Bitset Klasse aus Arrays zu schreiben

class Bitset
{
public:
  union { unsigned long asLong[2]; byte asByte[8]; } bits;

  Bitset()
  {
    this->clear();
  }

  void clear()
  {
    bits.asLong[0] = 0;
    bits.asLong[1] = 0;
  }

  byte getAt(byte index)
  {
    return bits.asByte[index / 8] & (byte)(1 << index % 8) ? 1 : 0;
  }

  void writeBit(byte value, byte index)
  {
    if(value == 0)
	bits.asByte[index / 8] &= (byte)~(1 << index % 8);
    else
	bits.asByte[index / 8] |= (byte)(1 << index % 8);
  }

  void operator <<= (byte count)
  {
    for(byte i = 0; i < count; i++)
    {
      byte msb = bits.asByte[3] & (byte)0x80 ? 1 : 0;
      bits.asLong[0] <<= 1;
      bits.asLong[1] <<= 1;
      bits.asByte[4] |= (byte)msb;
    }
  }

  void operator >>= (byte count)
  {
    for(byte i = 0; i < count; i++)
    {
      byte lsb = bits.asByte[4] & (byte)0x01 ? 0x80 : 0;
      bits.asLong[0] >>= 1;
      bits.asLong[1] >>= 1;
      bits.asByte[3] |= lsb;
    }
  }
};

Das mit der Union ist nicht unbedingt nötig. Aber es gibt auch Anwendungen wo man die einzelnen Bytes braucht. Man kann auch direkt mit einem long Array arbeiten wenn man die Indizes und Modulo-Divisoren entsprechend anpasst.

@ Miller411:
ich hab leider kein ethernet shield…
ich hab mal nach einem wlan shield geschaut. das kostete aber ein vielfachen von meinem gsm-shield, aber jetzt fummel ich rum!

@ jurs:
leider sehe ich bei deinem script nur "sterne". ich habe gerade aber das script wiedergefunden, das mal funktioniert hat:
http://www.arduinoclub.de/2013/11/15/dcf77-dcf1-arduino-pollin/3/

das problem dabei war, dass ich serial.print befehle – wenn ich es richtig verstanden habe – nicht im sketch sind sondern in der library:

/*
 * DCF77_SerialTimeOutput
 * Ralf Bohnen, 2013
 * This example code is in the public domain.
 */
 
#include "DCF77.h"
#include "Time.h"
 
char time_s[9];
char date_s[11];
 
#define DCF_PIN 2            // Connection pin to DCF 77 device
#define DCF_INTERRUPT 0      // Interrupt number associated with pin
 
time_t time;
DCF77 DCF = DCF77(DCF_PIN,DCF_INTERRUPT);
 
void setup() {
  Serial.begin(9600); 
  DCF.Start();
  Serial.println("Warte auf Zeitsignal ... ");
  Serial.println("Dies kann 2 oder mehr Minuten dauern.");
}
 
void loop() {
 
  delay(1000);
  time_t DCFtime = DCF.getTime(); // Nachschauen ob eine neue DCF77 Zeit vorhanden ist
  if (DCFtime!=0)
  {
    setTime(DCFtime); //Neue Systemzeit setzen
    Serial.print("Neue Zeit erhalten : "); //Ausgabe an seriell
    Serial.print(sprintTime()); 
    Serial.print("  "); 
    Serial.println(sprintDate());   
  } 
  //---> hier könnte man die Ausgabe auch auf ein LCD schicken.
}
 
char* sprintTime() {
    snprintf(time_s,sizeof(time_s),"%.2d:%.2d:%.2d" , hour(), minute(), second());
    time_s[strlen(time_s)] = '\0';
    return time_s;
}
 
char* sprintDate() {
    snprintf(date_s,sizeof(date_s),"%.2d.%.2d.%.4d" , day(), month(), year());
    date_s[strlen(date_s)] = '\0';
    return date_s;
}

wie kann ich mir denn die zeitinformation mit den temperatur-daten verknüpfen und per sms versenden?

ach, ich glaube langsam fällt der groschen! sprintTime und sprintDate...