Pages: 1 [2] 3   Go Down
Author Topic: DCF77 über Digitalpin?  (Read 3304 times)
0 Members and 1 Guest are viewing this topic.
Munich/Germany
Offline Offline
God Member
*****
Karma: 11
Posts: 643
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Jedes Element im struct DCF77Buffer ist 64 bit groß, damit ist eine Instanz des struct fast 1KB groß. Ist das nicht ein wenig übertrieben für die 59 Bit die das Signal eigentlich hat?
Eben nicht, dafür sorgt ja eben die Bitdefinition. Es wird nur ein einziges longlong verwendet, die Struktur ist somit nur 64 Bit groß.
Durch diese Definition kann man sich aber die ganze Bitschieberei sparen.
Ist einfach nur die Schmankerl von C ausgenutzt.
Logged

_______
Manfred

Munich/Germany
Offline Offline
God Member
*****
Karma: 11
Posts: 643
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

MaFu:
Ich habe mich heute mal an deine Bibliothek drangesetzt.

Code:
    /**
    * Should be called every 15 ms in order to sample the DCF signal.
    * Returns the current state of the signal: 1 for HIGH, 0 for LOW.
    */
    bool readTime(unsigned char retries);
    int scanSignal(void);
Wie ist das zu Verstehen? Muss ich wirklich alle 15ms einmal die Funktion aufrufen?

Kann man das irgendwie in der Bibliothek automatisieren? Vielleicht mit einem Timer Interrupt?

Und gibt es irgendeine Möglichkeit, zu prüfen, ob erfolgreich synchronisiert wurde?
Ehrlich gesagt, weiß ich nicht mehr was diese Anmerkung mit den 15ms zu bedeuten hat. Ist vermutlich noch ein Überbleibsel aus der Originalversion.

Schau Dir einfach mal das beiliegende Beispiel an.
Du brauchst nur einmal die Funktion scanSignal() aufrufen und kannst dann anschließend aus den Variablen der Klasse die Werte entnehmen.
Allerdings kann das natürlich auch in die Hose gehen. Daher ist die Funktion readTime() sinnvoller. Der Parameter von readTime() ist die Anzahl der Versuche, mit readTime(5) wird z.B. bis zu 5x versucht die Zeit zu ermitteln. Bei Erfolg wird true zurückgeliefert, ansonsten false.
Logged

_______
Manfred

Offline Offline
Edison Member
*
Karma: 21
Posts: 1419
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Danke für die Aufklärung. Das wusste ich nicht (mehr), falls es mir jemals untergekommen ist/war.
Und wieder was gelernt....
Logged

Germany
Offline Offline
Edison Member
*
Karma: 48
Posts: 2346
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Das beiliegende Beispiel (reduziert auf das wesentliche) sieht so aus:
Code:
#include <DCF77.h>

int DCF77Pin=11;
int seconds=0;
int previousSecond=0;
int minutes=0;
int hours=0;
DCF77 myDCF=DCF77(DCF77Pin);

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

void loop() {
  int DCFsignal = myDCF.scanSignal();
  hours=myDCF.hh;
  minutes=myDCF.mm;
  seconds=myDCF.ss;
  if (seconds != previousSecond)
    myDCF.serialDumpTime();
  delay(20);       
  previousSecond = seconds;
}

scanSignal wird eben nicht nur einmal aufgerufen, sondern permanent in der Loop, allerdings verzögert durch ein delay(). Das ist im Prinzip die gleiche Herangehensweise, wie ich sie in meinem Sketch auf Seite 1 wählte. Das Signal wird gepollt, also in einem regelmäßigen Abstand abgefragt.
Logged

Mein Arduino-Blog: http://www.sth77.de/ - letzte Einträge: Teensy 3.0 - Teensyduino unter Window 7 - Teensyduino unter Windows 8

Munich/Germany
Offline Offline
God Member
*****
Karma: 11
Posts: 643
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Natürlich wirds in den Beispielsketch immer wieder aufgerufen. Aber doch nur, weil das Beispiel sonst nichts anderes macht.

Ich würds so machen wie jede normale Funkuhr auch:
Einmal am Tag (sinnvollerweise in den Nachtstunden) mit readTime(5) die Uhrzeit ermitteln und wenn true zurückkommt die ermittelte Zeit übernehmen. Bei false kann man es ja ein paar mal alle 15 Minuten wiederholen bis es passt.
Logged

_______
Manfred

Germany
Offline Offline
Jr. Member
**
Karma: 0
Posts: 95
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

OK, dann verstehe ich jetzt auch, was die einzelnen Funktionen so machen. Was mir an readTime() nicht so gefällt, ist dass sie den kompletten Programmablauf unterbricht. Die Uhr sollte aber eigentlich kontinuierlich weiterlaufen, dafür habe ich den DS1307 ja schließlich eingebaut.
Wenn ich diese Woche Zeit habe, werde ich mal sehen, ob sich eine Funktion einbauen lässt, die wie scanSignal() ständig aufgerufen wird und zurückgibt, ob die Uhrzeit korrekt empfangen wurde. (Und die Veränderungen natürlich auch hier reinstellen)
Logged

NRW
Offline Offline
Sr. Member
****
Karma: 2
Posts: 372
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ich weiss garnicht mehr genau wie ich das gemacht hatte bei meiner Uhr.
Soweit ich mich erinnern kann hatte ich auch das Problem das dimyDCF.scanSignal(); regelmäßig aufgerufen werden musste.
Je nach dem was ich drum herum noch so gemacht hatte (z.B. Serial.prints) wurde das zu langsam.
Ich hatte dann noch in der Lib was verändert um festzustellen ob das Signal richtig war.
Über myDCF.valid konnte ich das auslesen
-1 = Empfangsfehler
1 = OK
Musste dann aber noch mal zusätzlich ne abfrage machen ob die Werte für Sekunden usw. auch Plausibel sind.
Weil ab und zu kam von der Auswertung ein OK aber die Werte waren völlig falsch.

Und soweit ich mich erinnern kann hat das ganz gut funktioniert.
Leider nur auf dem Breadboard, nachher in meiner Holzuhr nicht mehr.
Aber das hatte auch andere Gründe.
Logged

Munich/Germany
Offline Offline
God Member
*****
Karma: 11
Posts: 643
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

OK, dann verstehe ich jetzt auch, was die einzelnen Funktionen so machen. Was mir an readTime() nicht so gefällt, ist dass sie den kompletten Programmablauf unterbricht. Die Uhr sollte aber eigentlich kontinuierlich weiterlaufen, dafür habe ich den DS1307 ja schließlich eingebaut.
Wenn ich diese Woche Zeit habe, werde ich mal sehen, ob sich eine Funktion einbauen lässt, die wie scanSignal() ständig aufgerufen wird und zurückgibt, ob die Uhrzeit korrekt empfangen wurde. (Und die Veränderungen natürlich auch hier reinstellen)
Hast Du eine Funkuhr?
Die ermitteln das DCF Signal in der Regel (mag durchaus Ausnahmen geben) Nachts zwischen 2 und 4 Uhr. Und was machen die Zeiger in dieser Zeit? Sie bleiben stehen.
Ich will damit sagen: es ist im Prinzip wurscht, ob mitten in der Nacht für ein paar Minuten die Uhr stehenbleibt.
Logged

_______
Manfred

Germany
Offline Offline
Edison Member
*
Karma: 48
Posts: 2346
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

@MaFu: Ich denke, das kann man nicht so verallgemeinern. Ich habe mich ja in letzter Zeit etwas ausführlicher mit dem DCF77-Empfang und dessen Auswertung beschäftigt. Im Prinzip könnte jede Funkuhr das Signal kontinuierlich einlesen und auswerten. Ist die Uhr jedoch auf Stromsparen ausgelegt, trifft deine Aussage durchaus zu. Funkuhren mit Wetteranzeige (Auswertung der Bits 1-14), Bahnhofsuhren und viele Uhren mit "dicken" Batterien smiley-wink lesen aber das Signal kontinuierlich ein.
Wenn man jetzt nur einmal am Tag das DCF-Signal aufschnappt, muss im Hintergrund die Zeit mitlaufen, das über die verstrichenen Millisekunden zu machen wäre über 24 Stunden reichlich ungenau, ohne eine RTC würde ich das nicht machen. Da bleibt dann nur das permanente Einlesen.

Logged

Mein Arduino-Blog: http://www.sth77.de/ - letzte Einträge: Teensy 3.0 - Teensyduino unter Window 7 - Teensyduino unter Windows 8

Munich/Germany
Offline Offline
God Member
*****
Karma: 11
Posts: 643
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

And1G hat geschrieben, dass er eine DS1307 dranhängen hat. Und da reicht es ja wohl, wenn einmalig in der Nacht aktualisiert wird.

Ansonsten geb ich Dir recht.
Aber selbst wenn ich das weiterzählen ausschließlich über millis() machen würde brauche ich nicht permanent auslesen. Einmal pro Stunde würde reichen, so ungenau ist der ATmega nun auch wieder nicht.
Logged

_______
Manfred

Offline Offline
Newbie
*
Karma: 0
Posts: 33
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo wie kann ich die Stunden in 12 stunden ausgeben.
Analoge anzeige in 24 stunden ist etwas doof.
Gruß


Code:
#include <DCF77.h>

int DCF77Pin=2;
int blinkPin=13;
int seconds=0;
int previousSecond=0;
int minutes=0;
int hours=0;
DCF77 myDCF=DCF77(DCF77Pin);
int SZ;
//int stdPin=10;
//int minuPin=12;
float value;
float value1;
float value3;
//int std1;
//int minu1;



void setup(void)
{
  pinMode(blinkPin, OUTPUT);
  pinMode(4, OUTPUT);
  digitalWrite(2, LOW);
  // open the serial port at 9600 bps:
  Serial.begin(57600);
}

void loop(void)
{
  int DCFsignal = myDCF.scanSignal();
  if (DCFsignal) {
    digitalWrite(blinkPin, HIGH);
  } else {
    digitalWrite(blinkPin, LOW);
  }
  hours=myDCF.hh;
  minutes=myDCF.mm;
  seconds=myDCF.ss;
  if (seconds != previousSecond)
    myDCF.serialDumpTime();
  delay(20);
  previousSecond = seconds;
  {
 //   minu1=minutes;
   // std1=hours;
    value = hours;//std1;
    value1 =minutes;//minu1;
    value3=seconds;
   analogWrite(9, value*10);//Stunden 24*10 = 240
  analogWrite(10, value1*4);//Minuten 60*4 = 240
 analogWrite(11, value3*4); //Sekunden 60*4 = 240
 // Serial.println(value*10);
 // Serial.println(value1*4);
  }
  {
     SZ = hours*60+minutes;

 if (SZ >= 1095 && SZ <= 1200 )
{pinMode(4, OUTPUT);
  digitalWrite(4, HIGH);}
else
  {digitalWrite(4, LOW);}
  }
}

Logged

Germany
Offline Offline
Jr. Member
**
Karma: 0
Posts: 95
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
hours = hours - (hours > 11)?11:0;
Zieht, wenn hours>11 ist 12  ab, ansonsten 0, sollte funktionieren, wenn ich da nicht noch etwas übersehen hab smiley-grin

An der Erkennung, ob die Zeit richtig ermittelt wurde bin ich gerade noch am tüfteln.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 33
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

And1G wenn ich denn code nehme wird mir immer die Zeit angezeigt die nach dem ? steht.
Logged

Munich/Germany
Offline Offline
God Member
*****
Karma: 11
Posts: 643
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

hours = hours % 12;  // Mudulo Division durch 12, Ergebnis ist der Rest und liegt somit immer zwischen 0 und 11
Logged

_______
Manfred

Offline Offline
Newbie
*
Karma: 0
Posts: 33
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Danke MaFU werde es gleich probieren
Logged

Pages: 1 [2] 3   Go Up
Jump to: