DCF77 Modul in Arduino Code einbinden nur wie?

Der chaotische Hauptfaden

Moderatoren: Heaterman, Finger, Sven, TDI, Marsupilami72, duese

Antworten
Benutzeravatar
Andreas_P
Beiträge: 1400
Registriert: Mo 12. Aug 2013, 11:35
Wohnort: Lohr am Main
Kontaktdaten:

DCF77 Modul in Arduino Code einbinden nur wie?

Beitrag von Andreas_P »

Seit vielen Jahren habe ich vor die Uhr in Turm Schaft des Reinturms nachzubauen. https://de.wikipedia.org/wiki/Rheinturm
Nun habe ich begonnen das als Projekt in die Realität umzusetzen.

Als Hirn dient ein Arduino Uno Clone, zum testen habe ich 39 Grüne 5 mm LEDs verwendet.
Die Schaltung habe ich erstmal auf ein Steckbrett zusammengesteckt.
War ein ziemliches gefummel das alles auf dem Steckbrett zu platzieren.
Ein DCF77 Funkuhr Modul von Pollin soll für die richtige Zeit sorgen.

Die Schaltung habe ich wie auf der Homepage http://www.hjberndt.de/soft/rtc.html nachgebaut.
Hier der Programm Code den es auf der Homepage auch gibt.

Code: Alles auswählen

#define A0 14 //ANALOG 0
#define A1 15
#define A2 16
#define INTERVAL 1000

//PINS SEKUNDEN MINUTEN STUNDEN
byte oneSecond[] = {0,1,2,3,4,5,6,7,8}; //No Serial on 0/1
byte tenSecond[] = {9,10,11,12,13};     //
byte theSwitch[] = {14,15,16};//SEKUNDE MINUTE STUNDE
int s10=0,s1=0; //ONESECOND TENSECOND BAND
int m10=5,m1=9; // Start mit 23:59:00 Uhr
int h10=2,h1=3; //

unsigned long t,t0; //TIMEINIT

void TIMEINIT(void){t0=millis();}
unsigned long TIMEREAD(void){return millis()-t0;}

void setup()
{int i;
 for(i=0; ipinMode(oneSecond[i],OUTPUT);
 for(i=0; ipinMode(tenSecond[i],OUTPUT);
 for(i=0; ipinMode(theSwitch[i],OUTPUT);
 digitalWrite(A0, HIGH);
 digitalWrite(A1, HIGH);
 digitalWrite(A2, HIGH);
}

void loop()
{int i;
 t=TIMEREAD();
 do
 {for(i=0;idigitalWrite(oneSecond[i],s1<=i?LOW:HIGH);
  for(i=0;idigitalWrite(tenSecond[i],s10<=i?LOW:HIGH);
  digitalWrite(A0, LOW);//Masse an Sekunden
  delay(1);             //SHOWTIME SEKUNDEN
  digitalWrite(A0, HIGH);
  for(i=0;idigitalWrite(oneSecond[i],m1<=i?LOW:HIGH);
  for(i=0;idigitalWrite(tenSecond[i],m10<=i?LOW:HIGH);
  digitalWrite(A1, LOW);//Masse an MINUTEN
  delay(1);             //SHOWTIME MINUTEN
  digitalWrite(A1, HIGH);
  for(i=0;idigitalWrite(oneSecond[i],h1<=i?LOW:HIGH); 
  for(i=0;idigitalWrite(tenSecond[i],h10<=i?LOW:HIGH); 
  digitalWrite(A2, LOW);//Masse an STUNDEN
  delay(1);             //SHOWTIME STUNDEN
  digitalWrite(A2, HIGH);
 }while(TIMEREAD()<(t+INTERVAL));
 //---------------------------------
 s1++;                   //s++;
 if(s1>=10){s1=0;s10++;} 
 if(s10>=6){s10=0;m1++;} //m1++;
 if(m1>=10){m1=0;m10++;}
 if(m10>=6){m10=0;h1++;} //h1++;
 if(h1>=10){h1=0;h10++;}
 if(h10>=2 && h1>=4){h10=0;h1=0;}
}
Um später anders farbige Leds verwenden zu können,
habe ich an die Eingänge der Ledmatrix Transistoren verbaut (BC327).
Dadurch werden die Leds invertieret angesteuert.
Kann ich das in Code ändern in dem ich

Code: Alles auswählen

digitalWrite(A0, HIGH); 
Zu

Code: Alles auswählen

digitalWrite(A0, LOW);
ändere?

Wie binde ich in dem Code das Pollin Funkuhr Modul ein?
Brauche ich dazu noch externe Bauteile und welche?
Zuletzt geändert von Andreas_P am Sa 8. Mai 2021, 13:20, insgesamt 2-mal geändert.
Benutzeravatar
Zabex
Beiträge: 632
Registriert: Di 2. Jul 2013, 08:45
Wohnort: Aldenhoven
Kontaktdaten:

Re: Lichtzeitpegel Uhr nachbauen

Beitrag von Zabex »

Invertiereter Ausgang: Genau richtig gedacht.
Falls Du nicht wirklich soo viele LEDs verdrahten willst, schau dir doch mal Leds vom Typ WS2812B an.
Das ist eine RGB-Led mit eingebautem Controller. Die Leds können einfach hintereinandergeschaltet werden. Der Adruino sendet ein serielles Signal und damit kann man Farbe und Helligkeit jeder Led einzeln einstellen.
Für den Arduino gibt's Libraries dafür von Adafruit. Du brauchst dann nur 5V, einen Ausgangsport der über einen Widerstand an die 1. Led geht und z.B. einen fertigen Streifen mit 60 LEDs, wie zum Beispiel dieses ebay Angebot.
Um Eine Funkuhr anzuschließen muss man wissen, dass es welche mit 5V und mit 3.3V gibt. Mit den Pollin Modulen hatte ich schon viel Verdruss. Die wollen in Arduino-Nähe nur seeehr unwillig Empfangen. Selbst die guten Conrad-Module (2Quarze) haben da so ihre Probleme. Wenn Du ein 3,3V Modul an einen 5V Arduino anschließen willst: Versorgung mittels 3 Dioden in Reihe (2,1V abbauen) und nachgeschaltetem Widerstand von z.B. 10K gegen Masse (Grundlast). Der Data-Ausgang ist meist ein Open-Collector. Mit 47K gegen die 3V und einfach an einen digitalen Eingangspin (der schaltet bei 2,5V). Manchmal muss man PON mitverdrahten, da der DCF-Chip eine fallende Flanke an dem Eingang sehen will. Das macht man dann mit einem Spannungsteiler: 6K8 vom Arduino über 12K an GND. Mittelabgriff an PON.

Viel Erfolg!
Zabex
Benutzeravatar
Andreas_P
Beiträge: 1400
Registriert: Mo 12. Aug 2013, 11:35
Wohnort: Lohr am Main
Kontaktdaten:

Re: Lichtzeitpegel Uhr nachbauen

Beitrag von Andreas_P »

Das mit dem Neo Pixeln ist ne gute Idee.
Benutzeravatar
Andreas_P
Beiträge: 1400
Registriert: Mo 12. Aug 2013, 11:35
Wohnort: Lohr am Main
Kontaktdaten:

Re: Lichtzeitpegel Uhr nachbauen

Beitrag von Andreas_P »

Bild->zoom

Ich habe da mal ein Lochraster Layout gezeichnet für Testzwecke.
Für die Transistoren und die Widerstände habe ich auf der Lochrasterplatine keinen Platz mehr übrig.
Diese kommen auf eine zweite Lochrasterplatine unter.
Benutzeravatar
Zabex
Beiträge: 632
Registriert: Di 2. Jul 2013, 08:45
Wohnort: Aldenhoven
Kontaktdaten:

Re: Lichtzeitpegel Uhr nachbauen

Beitrag von Zabex »

Für soviele LEDs gibt's ja noch was feines: Max7219. Habe ich in meiner Text-Uhr verbaut. Zwei Max7219 steuern dort 120 gewöhnliche weiße LEDs.
Beispiele dazu auch bei instructables.

In meiner Wort-Uhr werkelt auch ein Arduino und ein DCF-Empfänger. In dem oberen verlinkten Projekt findest Du unten auf meiner Seite einen Link auf die Software. Da kannste den DCF-Krempel abgucken/rauskopieren und dir auch ansehen, wie simpel man einen Max7219 ansteuert.

Solltest Du auf Einzelleds mit jeweils einem Transistor bestehen: Ein ULN2803 hat 8 eingebaute Transistoren und eine gemeinsame Freilaufdiode. Das spart einiges an Verdrahtung und kostet unter 2ct/Transistor.

Gruß,
Zabex
Benutzeravatar
Andreas_P
Beiträge: 1400
Registriert: Mo 12. Aug 2013, 11:35
Wohnort: Lohr am Main
Kontaktdaten:

Re: Lichtzeitpegel Uhr nachbauen

Beitrag von Andreas_P »

Ich habe doch die Transitoren und die Widerstände auf die Lochrasterleiterplatte unterbringen können. :)

Bild->zoom

So schaut das alles in Echt aus.

Bild->zoom

Bild->zoom

Das Hirn der Uhr.
Benutzeravatar
Andreas_P
Beiträge: 1400
Registriert: Mo 12. Aug 2013, 11:35
Wohnort: Lohr am Main
Kontaktdaten:

Re: Lichtzeitpegel Uhr nachbauen, DCF77 Modul einbinden nur

Beitrag von Andreas_P »

Die Uhr funktioniert bis jetzt ohne Probleme. :)
In der Original Schaltung ist keine Möglichkeit vorgesehen die Uhr manuell oder
per DCF77 auf die aktuelle Uhrzeit zustellen.

Ich habe hier ein Funkuhr Modul von Pollin, das ich für diesen Zweck verwenden möchte.
Leider wurde mir gesagt das diese Module empfindlich auf Störfelder reagieren.
Das DCF77 Modul von Pollin (Best-Nr.: 810054) will eine Betriebssspannung von 1,2 bis 3,5V haben.
Der Adruino Uno Clone gibt auf einen der Pins 3,3V raus. Kann ich an diesen
das DCF77 Modul bedenkenlos besaften :?:

Bild->zoom
Das Bild wurde bei Zabex.de ausgeliehen.

Oder muss ich diese Wandlerschaltung von Zabex verwenden :?:

Ich habe mal versucht als Adruino Anfäger dem Code anzupassen. Kann das so Funktionieren?

Code: Alles auswählen

#define A0 14 //ANALOG 0
#define A1 15
#define A2 16
#define INTERVAL 1000
//I/O Makros DCF77-Empfänger
#define   DI_DCF77 9
//#define   DO_DCF_DISABLE 8     //over 4K7 to PON. PON over 5K6 to GND
#define   DO_DCF_POWERSUPPLY 7 //over 470R to VDD. VDD over white LED (2.8V) to GND. 

//PINS SEKUNDEN MINUTEN STUNDEN
byte oneSecond[] = {0,1,2,3,4,5,6,7,8}; //No Serial on 0/1
byte tenSecond[] = {9,10,11,12,13};     //
byte theSwitch[] = {14,15,16};          //SEKUNDE MINUTE STUNDE
byte  dcfSekunde; //0..59 - wird bei ausbleibendem Signal (59. Sekunde) auf 0 gesetzt
byte  stoerung;      //Unplausibler Empfang
byte  zeitEmpfangen; //Schaltet auf Zeitanzeige statt Sekundenanzeige um
byte  uhrHH;  //Die interne Uhr (wird von DCF-Uhr gestellt)
byte  uhrMM;
byte  uhrSS;
int s10=0,s1=0; //ONESECOND TENSECOND BAND
int m10=5,m1=9;
int h10=2,h1=3;

unsigned long t,t0; //TIMEINIT

void INTITIME(void){t0=millis();}
unsigned long TIMEREAD(void){return millis()-t0;}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void decodeDCF77(void){  //Alle 5ms aufrufen
//------------------------------------------------------------------------------
static int iTic=0; 
static int iTiefpass=0; 
static bool bSteigend=0;
static byte nZeitumstellung=0;
static byte hs=0;
static byte hh=0;
static byte mm=0;
static byte ss=0;
static byte tag=0;
static byte wtag=0;
static byte monat=0;
static byte jahr=0;
static byte keinEmpfang=0;
static byte neuesDatum=0;
static bool bToggle;
static byte sommerzeit;
static byte winterzeit;
static byte startphase=1;
static byte bChecksum=0;
static byte zeitUebernehmen;    
static byte bBit[60];      //die empfangenen Bits
static byte erfolgreichdecodiert;
static byte vorHH; //Die empfangene Zeit in der letzten Minute
static byte vorMM;
static byte vorJJ;
static byte ms50;    
static long tries=0;  
byte i;

    iTic+=5;  //5ms sind rum
    if (iTic>3000){ //Kein Signal
      iTic=3000;
    }
    //Eingang abfragen und filtern
    if (digitalRead(DI_DCF77)){ //Signalabsenkung liefert High für 100ms oder 200ms
      iTiefpass+=5;
      digitalWrite(13, HIGH);
      if (iTiefpass>200) iTiefpass=200;  //auf 200ms begrenzen
    }else{
      digitalWrite(13, LOW);
      iTiefpass-=5;
      if (iTiefpass<0){
        iTiefpass=0;
        bSteigend=1;
      }
    }


    //Minutenanfang erkennen
    if (iTic > 1500){ //Minutensignal: mehr als 1s keine Absenkung
      dcfSekunde=59;
    }
    else
    //Signallänge bestimmen und im Bitfeld eintragen
    if (160==iTic){ //160ms  Tiefpass ist entweder +100-60=40 oder +100+60=160
      //pulsdauer=iTiefpass;
      if (iTiefpass > 90){      
        bBit[dcfSekunde]=1;
      }else{
        bBit[dcfSekunde]=0;
      }
    
      if ((iTiefpass < 5) ||   ((iTiefpass > 60) && (iTiefpass <100))){ //Unplausible Signaldauer
        if (stoerung <4) stoerung++;  
      }else{
        if (stoerung >0) stoerung--;  
      }
    }
    //Sekundenanfang erkennen
    if ((60==iTiefpass) && bSteigend){ //60ms seit Pulsbeginn
      bSteigend=0;
      iTic=60;
      dcfSekunde++;
      if (dcfSekunde>59){  //Jetzt ist Minutenanfang
        dcfSekunde=0;
        if (0==startphase){ //beim 1. Minutenanfang nach Einschalten ist die Zeit noch nicht übertragen
          zeitUebernehmen = 1;  
        }

        //Auswertung zum Minutenanfang
        if (zeitUebernehmen){
          if (bBit[16]){
            nZeitumstellung++;
            }else{
            if (nZeitumstellung) nZeitumstellung--;
          }
          if (bBit[17]){
            if (sommerzeit < 60) sommerzeit++;
            }else{
            if (sommerzeit) sommerzeit--;
          }
          if (bBit[18]){
            if (winterzeit < 60) winterzeit++;
            }else{
            if (winterzeit) winterzeit--;
          }
          bChecksum=bBit[21]+bBit[22]+bBit[23]+bBit[24]+bBit[25]+bBit[26]+bBit[27]+bBit[28]; //Minute 
          if (0==(bChecksum % 2)){ //P1
            bChecksum=bBit[29]+bBit[30]+bBit[31]+bBit[32]+bBit[33]+bBit[34]+bBit[35];        //Stunde  
            if (0==(bChecksum % 2)){ //P2
              if (bBit[20]){ //Startbit; immer gesetzt
                bChecksum=0;
                for (i=36; i<59; i++){ //Checksumme über Datum 
                  bChecksum+=bBit[i];
                }
                if (0==(bChecksum % 2)){ //P3
                  neuesDatum=0;
                  keinEmpfang=0;
                  tag = bBit[36]+bBit[37]*2+bBit[38]*4+bBit[39]*8+bBit[40]*10+bBit[41]*20;
                  wtag = bBit[42]+bBit[43]*2+bBit[44]*4;
                  monat = bBit[45]+bBit[46]*2+bBit[47]*4+bBit[48]*8;
                  jahr = bBit[50]+bBit[51]*2+bBit[52]*4+bBit[53]*8+bBit[54]*10+bBit[55]*20+bBit[56]*40+bBit[57]*80;
                  if (zeitUebernehmen){
                    //Übernehme Zeit
                    zeitUebernehmen = 0;
                    hh = bBit[29]+bBit[30]*2+bBit[31]*4+bBit[32]*8+bBit[33]*10+bBit[34]*20;
                    mm = bBit[21]+bBit[22]*2+bBit[23]*4+bBit[24]*8+bBit[25]*10+bBit[26]*20+bBit[27]*40;
                    ss = 0;
                    //Ist diese Zeit genau eine Minute später als vor einer Minute? (zusätzliche Plausibilitätscheck)
                    vorMM++;
                    if (vorMM>59){
                      vorMM=0;
                      vorHH++;
                      if (vorHH >23) vorHH=0;
                    }
                    if ((vorHH == hh) 
                    && (vorMM == mm) 
                    && (vorJJ == jahr) //Beim Jahreswechsel muss die Uhr ja nicht um Mitternacht verdreht werden
                    && (jahr>14)){       //Wir haben 2015 - und mehr als bis zum Jahr 2099 soll die Uhr gar nicht laufen
                      erfolgreichdecodiert=1;
                    }  
                    vorHH=hh;
                    vorMM=mm;
                    vorJJ=jahr; 
                  }
                }//P3
              }//Bit20
            }//P2
          }//P1
        }//zeitUebernehmen
        if (startphase) startphase=0;
        for (i=0; i<60; i++){
          bBit[i]=0;
        }
      }//(dcfSekunde>59)
    
      //Interne Uhr feintunen
      //Hundertstel Sekunden hs sollte auf 6 stehen , wenn die Uhr richtig läuft (60ms seit steigender Flanke)
      //Nur machen, wenn Empfang OK
      if ((keinEmpfang < 2) && (0==stoerung)){
        if ((hs > 6) && (hs < 56)) {
          hs --; //Uhr etwas zurückdrehen
        }else{
          if (hs != 6){
            hs++; //Uhr etwas vor drehen. Überlauf wird weiter unten automatisch behandelt.
          }  
        }
      }
    }//Sekundenanfang (60ms)

    //Intere Uhr weiterdrehen
    bToggle = !bToggle;
    if (bToggle){ //10ms sind rum
      hs++; //Hundertstel Sekunden
      if (hs>99){ //1s ist rum
        hs-=100; //Nicht auf 0 setzen, um Überlauf bei Uhr vordrehen (Feintuning) zu berücksichtigen
        uhrSS++;
        if (uhrSS > 59){
          uhrSS=0;
          uhrMM++;
          if (keinEmpfang < 100){ //Wird bei Empfang mit korreten Prüfsummen auf 0 gesetzt  
            keinEmpfang++;
          } 
   //       if (!zeitEmpfangen && (keinEmpfang > 5)){
   //         displayEnable(0);
   //       }
          if (zeitEmpfangen && (keinEmpfang > 15) && (uhrHH > 2) && (uhrHH < 6)) {
            displayEnable(0);
          }
          if (uhrMM > 59){
            uhrMM=0;
            uhrHH++;
            if (uhrHH > 23){
              uhrHH=0;
              neuesDatum=1; //Datum wird ja nicht angezeigt. Aber wenn ich das mal einbauen will, habe ich hiermit den Tagesbeginn.
            } 
            //Zeitumstellung?
            if ((nZeitumstellung > 45) && (uhrHH >=2) && (uhrHH <=3)){ //"nZeitumstellung" wurde in der Stunde vor der Umstellung jede Minute hochgezählt
              if (sommerzeit > winterzeit){ //MESZ->MEZ
                uhrHH--;
              }else{ //MEZ->MESZ
                uhrHH++;
              }
            }
          }//uhrMM>59
          anzeigen();
        }//uhrSS>59
        if (erfolgreichdecodiert){ //Zeit übernehmen (wenn vorhanden)
          erfolgreichdecodiert=0;
          zeitEmpfangen=1;
          uhrHH=hh;
          uhrMM=mm;
          uhrSS=0;
          displayEnable(1);
        }

      }//hs>99
      if (!zeitEmpfangen){
        ms50++;
        if (ms50 > 4){ //50 ms sind rum
            ms50 = 0;
            //scope();
        }
      }
    }//Toggle
}//decodeDCF77
//------------------------------------------------------------------------------
void displayEnable(byte en){ 
static byte  oldEn=222;
  if (oldEn != en){
    oldEn=en;
    led.shutdown(0,(en==0));
    led.shutdown(1,(en==0));
  }
  
}

void setup()
{int i;
 for(i=0; i<sizeof(oneSecond);i++)pinMode(oneSecond[i],OUTPUT);
 for(i=0; i<sizeof(tenSecond);i++)pinMode(tenSecond[i],OUTPUT);
 for(i=0; i<sizeof(theSwitch);i++)pinMode(theSwitch[i],OUTPUT);
 digitalWrite(A0, LOW);
 digitalWrite(A1, LOW);
 digitalWrite(A2, LOW);
}

void loop()
{int i;
 t=TIMEREAD();
 do
 {for(i=0;i<sizeof(oneSecond);i++)digitalWrite(oneSecond[i],s1<=i?LOW:HIGH);  //EINERBAND SEKUNDEN
  for(i=0;i<sizeof(tenSecond);i++)digitalWrite(tenSecond[i],s10<=i?LOW:HIGH); //ZEHNERBAND SEKUNDEN 
  digitalWrite(A0, HIGH);//Masse an Sekunden
  delay(1);             //SHOWTIME SEKUNDEN
  digitalWrite(A0, LOW);
  for(i=0;i<sizeof(oneSecond);i++)digitalWrite(oneSecond[i],m1<=i?LOW:HIGH);  //EINERBAND MINUTEN
  for(i=0;i<sizeof(tenSecond);i++)digitalWrite(tenSecond[i],m10<=i?LOW:HIGH); //ZEHNERBAND MINUTEN 
  digitalWrite(A1, HIGH);//Masse an MINUTEN
  delay(1);             //SHOWTIME MINUTEN
  digitalWrite(A1, LOW);
  for(i=0;i<sizeof(oneSecond);i++)digitalWrite(oneSecond[i],h1<=i?LOW:HIGH);  //EINERBAND STUNDEN
  for(i=0;i<sizeof(tenSecond);i++)digitalWrite(tenSecond[i],h10<=i?LOW:HIGH); //ZEHNERBAND STUNDEN
  digitalWrite(A2, HIGH);//Masse an STUNDEN
  delay(1);             //SHOWTIME STUNDEN
  digitalWrite(A2, LOW);
 }while(TIMEREAD()<(t+INTERVAL));
 //---------------------------------
 s1++;                   //s++;
 if(s1>=10){s1=0;s10++;} 
 if(s10>=6){s10=0;m1++;} //m1++;
 if(m1>=10){m1=0;m10++;}
 if(m10>=6){m10=0;h1++;} //h1++;
 if(h1>=10){h1=0;h10++;}
 if(h10>=2 && h1>=4){h10=0;h1=0;}
}

Benutzeravatar
Chefbastler
Beiträge: 2665
Registriert: Mo 12. Aug 2013, 20:21
Wohnort: Südbayern

Re: Lichtzeitpegel Uhr nachbauen, DCF77 Modul einbinden nur

Beitrag von Chefbastler »

Die DCF Module wollen meist ne saubere glatte Versorgung. Die 3,3V vom Arduino kanst du ausprobieren. Wenn es nicht geht kannst duch auch noch einen LC/RC Tifpassfilter dazwischenschalten. Der PON-Pegel darf nicht höher als die Versorgung vom DCF Modul sein.

Wenn dein µC mit 5v läuft und dein Empfänger mit einer kleineren Spannung, musst du aufpassen dass der Pegel vom Signal noch groß genug ist dass dein µC(Schwellwerte stehen im Datenblatt) noch zuverlässig 1/0 erkennen kann.
Benutzeravatar
xoexlepox
Beiträge: 4814
Registriert: So 11. Aug 2013, 19:28
Wohnort: So etwa in der Mitte

Re: Lichtzeitpegel Uhr nachbauen, DCF77 Modul einbinden nur

Beitrag von xoexlepox »

Andreas_P hat geschrieben:Leider wurde mir gesagt das diese Module empfindlich auf Störfelder reagieren.
Empfindlich sind fast alle DCF77-Module: Wenn du den Ferrritstab auf ein Schaltnetzteil legst, wird der Empfang ziemlich unwahrscheinlich. Das ist eben ein Langwellen-Empfänger, wobei ggf. auch die Ausrichtung des Ferrritstabes wichtig werden kann -> Zeigt die Achse des Stabes zum Sender, kann das Signal recht dünn werden. Manche DCF-Module haben einen "Open Collector"-Ausgang, und möchten demzufolge einen Widerstand (10k?) vom Ausgang zur Betriebsspannung -> ausprobieren.
plottermeier
Beiträge: 1444
Registriert: Fr 16. Aug 2013, 14:32

Re: Lichtzeitpegel Uhr nachbauen, DCF77 Modul einbinden nur

Beitrag von plottermeier »

Hallo,

cooles Projekt, hab das Pollinmodul schon erfolgreich am Arduino betrieben und mit den 3,3V gespeist.
Dazu muss man wissen, dass das Modul erst nach etwa 2 Minuten anfängt, Daten zu liefern.
Wann eine Halle weiter der Schweißroboter lief was der Empfang auch weg. Unter solchen Bedingungen koppelt
man es am beste mit ner RTC, die einfach nur gelegentlich neu gestellt wird, wenn der Empfang gut ist.
Den Pullup-Widerstand kann man auch in den Einstellungen mit INPUT_PULLUP aktivieren.

Jens
Benutzeravatar
xoexlepox
Beiträge: 4814
Registriert: So 11. Aug 2013, 19:28
Wohnort: So etwa in der Mitte

Re: Lichtzeitpegel Uhr nachbauen, DCF77 Modul einbinden nur

Beitrag von xoexlepox »

plottermeier hat geschrieben:Unter solchen Bedingungen koppelt man es am beste mit ner RTC, ...
Naja, wenn das Signal sowieso mit einem µC ausgewertet wird, hat man meinst auch einen (quarzgesteuerten) Takt, der dann über ein paar Stunden "Offline-Betrieb" ausreicht. Es sei denn, man braucht ms-genaue Zeit, oder schaltet das Ding zu einer "Nicht-Empfangszeit" ein ;)
Den Pullup-Widerstand kann man auch in den Einstellungen mit INPUT_PULLUP aktivieren.
Danke für den Hinweis! Bei meinem Decoder (mittels PIC) gab es das (noch?) nicht.
plottermeier
Beiträge: 1444
Registriert: Fr 16. Aug 2013, 14:32

Re: Lichtzeitpegel Uhr nachbauen, DCF77 Modul einbinden nur

Beitrag von plottermeier »

xoexlepox hat geschrieben:...
Naja, wenn das Signal sowieso mit einem µC ausgewertet wird, hat man meinst auch einen (quarzgesteuerten) Takt, der dann über ein paar Stunden "Offline-Betrieb" ausreicht. Es sei denn, man braucht ms-genaue Zeit, oder schaltet das Ding zu einer "Nicht-Empfangszeit" ein ...
Stimmt, sollte für die Anwendung gehen. Bei meiner hatte ich den µC zwischendurch immer Schlafen geschickt, um Strom zu sparen. Wird hier ja eher nicht nötig sein. Meine RTC ist sogar ungenauer als die im Arduino emulierte Uhr. War wohl Ausschuss.
Benutzeravatar
xoexlepox
Beiträge: 4814
Registriert: So 11. Aug 2013, 19:28
Wohnort: So etwa in der Mitte

Re: Lichtzeitpegel Uhr nachbauen, DCF77 Modul einbinden nur

Beitrag von xoexlepox »

plottermeier hat geschrieben:Bei meiner hatte ich den µC zwischendurch immer Schlafen geschickt, um Strom zu sparen.
Stimmt, die "Stromsparoption" ist auch eine weitere Variante, bei der eine RTC nützlich werden kann.
Benutzeravatar
Andreas_P
Beiträge: 1400
Registriert: Mo 12. Aug 2013, 11:35
Wohnort: Lohr am Main
Kontaktdaten:

Re: Lichtzeitpegel Uhr nachbauen, DCF77 Modul einbinden nur

Beitrag von Andreas_P »

Habe noch einen Arduino Uno Clone aus meinen Fundus hervorgeholt.
Mit diesem werde ich das Pollin DCF77 Modul mal Testen.
Programmbeispiele um Funkuhr Module am einen Adruino zu betreiben gibt es ja im Netz.
Benutzeravatar
Andreas_P
Beiträge: 1400
Registriert: Mo 12. Aug 2013, 11:35
Wohnort: Lohr am Main
Kontaktdaten:

Re: Lichtzeitpegel Uhr nachbauen, DCF77 Modul einbinden nur

Beitrag von Andreas_P »

Seit Samstag abend läuft das Funkuhr Modul von
Pollin korrekt. Ich hatte immer eine Minute Zeit Verlust. :shock:
Dank Hilfe im Fablap wurde ein Fehler in dem Herunterladenen
Code korrigiert. Und schon funktionierte das Modul wie gewünscht.

Hier der Code den ich verwende.

Code: Alles auswählen

    /**
     * Arduino DCF77 decoder v0.2
     * Copyright (C) 2006 Mathias Dalheimer (md@gonium.net)
     *
     * This program is free software; you can redistribute it and/or modify
     * it under the terms of the GNU General Public License as published by
     * the Free Software Foundation; either version 2 of the License, or
     * any later version.
     *
     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * GNU General Public License for more details.
     *
     * You should have received a copy of the GNU General Public License along
     * with this program; if not, write to the Free Software Foundation, Inc.,
     * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
     */

    /**
     * Where is the DCF receiver connected?
     */
    #define DCF77PIN 2
    /**
     * Where is the LED connected?
     */
    #define BLINKPIN 13
    /**
     * Turn debugging on or off
     */
    #define DCF_DEBUG 1
    /**
     * Number of milliseconds to elapse before we assume a "1",
     * if we receive a falling flank before - its a 0.
     */
    #define DCF_split_millis 140
    /**
     * There is no signal in second 59 - detect the beginning of
     * a new minute.
     */
    #define DCF_sync_millis 1200
    /**
     * Definitions for the timer interrupt 2 handler:
     * The Arduino runs at 16 Mhz, we use a prescaler of 64 -> We need to
     * initialize the counter with 6. This way, we have 1000 interrupts per second.
     * We use tick_counter to count the interrupts.
     */
    #define INIT_TIMER_COUNT 6
    #define RESET_TIMER2 TCNT2 = INIT_TIMER_COUNT
    int tick_counter = 0;
    int TIMSK;
    int TCCR2;
    int OCIE2;
    /**
     * DCF time format struct
     */
    struct DCF77Buffer {
      unsigned long long prefix   :21;
      unsigned long long Min   :7;   // minutes
      unsigned long long P1      :1;   // parity minutes
      unsigned long long Hour   :6;   // hours
      unsigned long long P2      :1;   // parity hours
      unsigned long long Day   :6;   // day
      unsigned long long Weekday   :3;   // day of week
      unsigned long long Month   :5;   // month
      unsigned long long Year   :8;   // year (5 -> 2005)
      unsigned long long P3      :1;   // parity
    };
    struct {
       unsigned char parity_flag   :1;
       unsigned char parity_min      :1;
       unsigned char parity_hour   :1;
       unsigned char parity_date   :1;
    } flags;
    /**
     * Clock variables
     */
    volatile unsigned char DCFSignalState = 0; 
    unsigned char previousSignalState;
    int previousFlankTime;
    int bufferPosition;
    unsigned long long dcf_rx_buffer;
    /**
     * time vars: the time is stored here!
     */
    volatile unsigned char ss;
    volatile unsigned char mm;
    volatile unsigned char hh;
    volatile unsigned char day;
    volatile unsigned char mon;
    volatile unsigned int year;
       

    /**
     * used in main loop: detect a new second...
     */
    unsigned char previousSecond;
       
    /**
     * Initialize the DCF77 routines: initialize the variables,
     * configure the interrupt behaviour.
     */
    void DCF77Init() {
      previousSignalState=0;
      previousFlankTime=0;
      bufferPosition=0;
      dcf_rx_buffer=0;
      ss=mm=hh=day=mon=year=0;
    #ifdef DCF_DEBUG
      Serial.println("Initializing DCF77 routines");
      Serial.print("Using DCF77 pin #");
      Serial.println(DCF77PIN);
      pinMode(BLINKPIN, OUTPUT);
      pinMode(DCF77PIN, INPUT);
    #endif
      pinMode(DCF77PIN, INPUT);
    #ifdef DCF_DEBUG
      Serial.println("Initializing timerinterrupt");
    #endif
      //Timer2 Settings: Timer Prescaler /64,
      TCCR2 |= (1<<CS22);    // turn on CS22 bit
      TCCR2 &= ~((1<<CS21) | (1<<CS20));    // turn off CS21 and CS20 bits   
      // Use normal mode
      TCCR2 &= ~((1<<WGM21) | (1<<WGM20));   // turn off WGM21 and WGM20 bits
      // Use internal clock - external clock not used in Arduino
      ASSR |= (0<<AS2);
      TIMSK |= (1<<TOIE2) | (0<<OCIE2);        //Timer2 Overflow Interrupt Enable 
      RESET_TIMER2;
    #ifdef DCF_DEBUG
      Serial.println("Initializing DCF77 signal listener interrupt");
    #endif 
      attachInterrupt(0, int0handler, CHANGE);
    }

    /**
     * Append a signal to the dcf_rx_buffer. Argument can be 1 or 0. An internal
     * counter shifts the writing position within the buffer. If position > 59,
     * a new minute begins -> time to call finalizeBuffer().
     */
    void appendSignal(unsigned char signal) {
    #ifdef DCF_DEBUG
      Serial.print(", appending value ");
      Serial.print(signal, DEC);
      Serial.print(" at position ");
      Serial.println(bufferPosition);
    #endif
      dcf_rx_buffer = dcf_rx_buffer | ((unsigned long long) signal << bufferPosition);
      // Update the parity bits. First: Reset when minute, hour or date starts.
      if (bufferPosition ==  21 || bufferPosition ==  29 || bufferPosition ==  36) {
       flags.parity_flag = 0;
      }
      // save the parity when the corresponding segment ends
      if (bufferPosition ==  28) {flags.parity_min = flags.parity_flag;};
      if (bufferPosition ==  35) {flags.parity_hour = flags.parity_flag;};
      if (bufferPosition ==  58) {flags.parity_date = flags.parity_flag;};
      // When we received a 1, toggle the parity flag
      if (signal == 1) {
        flags.parity_flag = flags.parity_flag ^ 1;
      }
      bufferPosition++;
      if (bufferPosition > 59) {
        finalizeBuffer();
      }
    }

    /**
     * Evaluates the information stored in the buffer. This is where the DCF77
     * signal is decoded and the internal clock is updated.
     */
    void finalizeBuffer(void) {
      if (bufferPosition == 59) {
    #ifdef DCF_DEBUG
        Serial.println("Finalizing Buffer");
    #endif
        struct DCF77Buffer *rx_buffer;
        rx_buffer = (struct DCF77Buffer *)(unsigned long long)&dcf_rx_buffer;
        if (flags.parity_min == rx_buffer->P1  &&
            flags.parity_hour == rx_buffer->P2  &&
            flags.parity_date == rx_buffer->P3)
        {
    #ifdef DCF_DEBUG
          Serial.println("Parity check OK - updating time.");
    #endif
          //convert the received bits from BCD
          mm = rx_buffer->Min-((rx_buffer->Min/16)*6);
          hh = rx_buffer->Hour-((rx_buffer->Hour/16)*6);
          day= rx_buffer->Day-((rx_buffer->Day/16)*6);
          mon= rx_buffer->Month-((rx_buffer->Month/16)*6);
          year= 2000 + rx_buffer->Year-((rx_buffer->Year/16)*6);
        }
    #ifdef DCF_DEBUG
          else {
            Serial.println("Parity check NOK - running on internal clock.");
        }
    #endif
      }
      // reset stuff
      ss = 0;
      bufferPosition = 0;
      dcf_rx_buffer=0;
    }

    /**
     * Dump the time to the serial line.
     */
    void serialDumpTime(void){
      Serial.print("Time: ");
      Serial.print(hh, DEC);
      Serial.print(":");
      Serial.print(mm, DEC);
      Serial.print(":");
      Serial.print(ss, DEC);
      Serial.print(" Date: ");
      Serial.print(day, DEC);
      Serial.print(".");
      Serial.print(mon, DEC);
      Serial.print(".");
      Serial.println(year, DEC);
    }


    /**
     * Evaluates the signal as it is received. Decides whether we received
     * a "1" or a "0" based on the
     */
    void scanSignal(void){
        if (DCFSignalState == 1) {
          int thisFlankTime=millis();
          if (thisFlankTime - previousFlankTime > DCF_sync_millis) {
    #ifdef DCF_DEBUG
            Serial.println("####");
            Serial.println("#### Begin of new Minute!!!");
            Serial.println("####");
    #endif
            finalizeBuffer();
            serialDumpTime();
          }
          previousFlankTime=thisFlankTime;
    #ifdef DCF_DEBUG
          Serial.print(previousFlankTime);
          Serial.print(": DCF77 Signal detected, ");
    #endif
        }
        else {
          /* or a falling flank */
          int difference=millis() - previousFlankTime;
    #ifdef DCF_DEBUG
          Serial.print("duration: ");
          Serial.print(difference);
    #endif
          if (difference < DCF_split_millis) {
            appendSignal(0);
          }
          else {
            appendSignal(1);
          }
        }
    }

    /**
     * The interrupt routine for counting seconds - increment hh:mm:ss.
     */
    ISR(TIMER2_OVF_vect) {
      RESET_TIMER2;
      tick_counter += 1;
      if (tick_counter == 1000) {
        ss++;
        if (ss==60) {
          ss=0;
          mm++;
          if (mm==60) {
            mm=0;
            hh++;
            if (hh==24)
              hh=0;
          }
        }
        tick_counter = 0;
      }
    };

    /**
     * Interrupthandler for INT0 - called when the signal on Pin 2 changes.
     */
    void int0handler() {
      // check the value again - since it takes some time to
      // activate the interrupt routine, we get a clear signal.
      DCFSignalState = digitalRead(DCF77PIN);
    }


    /**
     * Standard Arduino methods below.
     */

    void setup(void) {
      // We need to start serial here again,
      // for Arduino 007 (new serial code)
      Serial.begin(9600);
      DCF77Init();
    }

    void loop(void) {
      if (ss != previousSecond) {
        serialDumpTime();
        previousSecond = ss;
      }
      if (DCFSignalState != previousSignalState) {
        scanSignal();
        if (DCFSignalState) {
          digitalWrite(BLINKPIN, HIGH);
        } else {
          digitalWrite(BLINKPIN, LOW);
        }
        previousSignalState = DCFSignalState;
      }
        //delay(20);
    }
Benutzeravatar
Andreas_P
Beiträge: 1400
Registriert: Mo 12. Aug 2013, 11:35
Wohnort: Lohr am Main
Kontaktdaten:

Re: Lichtzeitpegel Uhr nachbauen, DCF77 Modul einbinden nur

Beitrag von Andreas_P »

Dem Code der Reinturmuhr und dem Code für den
DCF77 Empfang muss ich jetzt irgendwie zusammenbringen.
Dabei könnte ich etwas Hilfe gebrauchen.
Sonderlich viel habe ich mit dem Arduinos noch nicht gemacht.

Code: Alles auswählen

    #define A0 14 //ANALOG 0
    #define A1 15
    #define A2 16
    #define INTERVAL 1000

    //PINS SEKUNDEN MINUTEN STUNDEN
    byte oneSecond[] = {0,1,2,3,4,5,6,7,8}; //No Serial on 0/1
    byte tenSecond[] = {9,10,11,12,13};     //
    byte theSwitch[] = {14,15,16};//SEKUNDE MINUTE STUNDE
    int s10=0,s1=0; //ONESECOND TENSECOND BAND
    int m10=5,m1=9; // Start mit 23:59:00 Uhr
    int h10=2,h1=3; //

    unsigned long t,t0; //TIMEINIT

    void TIMEINIT(void){t0=millis();}
    unsigned long TIMEREAD(void){return millis()-t0;}

    void setup()
    {int i;
     for(i=0; ipinMode(oneSecond[i],OUTPUT);
     for(i=0; ipinMode(tenSecond[i],OUTPUT);
     for(i=0; ipinMode(theSwitch[i],OUTPUT);
     digitalWrite(A0, HIGH);
     digitalWrite(A1, HIGH);
     digitalWrite(A2, HIGH);
    }

    void loop()
    {int i;
     t=TIMEREAD();
     do
     {for(i=0;idigitalWrite(oneSecond[i],s1<=i?LOW:HIGH);
      for(i=0;idigitalWrite(tenSecond[i],s10<=i?LOW:HIGH);
      digitalWrite(A0, LOW);//Masse an Sekunden
      delay(1);             //SHOWTIME SEKUNDEN
      digitalWrite(A0, HIGH);
      for(i=0;idigitalWrite(oneSecond[i],m1<=i?LOW:HIGH);
      for(i=0;idigitalWrite(tenSecond[i],m10<=i?LOW:HIGH);
      digitalWrite(A1, LOW);//Masse an MINUTEN
      delay(1);             //SHOWTIME MINUTEN
      digitalWrite(A1, HIGH);
      for(i=0;idigitalWrite(oneSecond[i],h1<=i?LOW:HIGH);
      for(i=0;idigitalWrite(tenSecond[i],h10<=i?LOW:HIGH);
      digitalWrite(A2, LOW);//Masse an STUNDEN
      delay(1);             //SHOWTIME STUNDEN
      digitalWrite(A2, HIGH);
     }while(TIMEREAD()<(t+INTERVAL));
     //---------------------------------
     s1++;                   //s++;
     if(s1>=10){s1=0;s10++;}
     if(s10>=6){s10=0;m1++;} //m1++;
     if(m1>=10){m1=0;m10++;}
     if(m10>=6){m10=0;h1++;} //h1++;
     if(h1>=10){h1=0;h10++;}
     if(h10>=2 && h1>=4){h10=0;h1=0;}
    }
Michael1976
Beiträge: 1
Registriert: Fr 7. Feb 2020, 09:59

Re: Lichtzeitpegel Uhr nachbauen, DCF77 Modul einbinden nur wie?

Beitrag von Michael1976 »

Hi, ich bin versuche auch seit Wochen das mit dem RTC zu lösen.
Ohne Erfolg.

Hast du das Problem gelöst?

Grüße
Benutzeravatar
Andreas_P
Beiträge: 1400
Registriert: Mo 12. Aug 2013, 11:35
Wohnort: Lohr am Main
Kontaktdaten:

DCF77 Modul in Arduino Code einbinden nur wie?

Beitrag von Andreas_P »

Beim Aufräumen dieser Woche ist mir meine Ardurino LED Uhr in die Hände gefallen.
Leider hatte ich es damals nicht geschafft das DCF77 Modul in den bestehenden Arduino Code
so einzubinden das auch eine korrekte Uhrzeit angezeigt wird.

Auf der Seite https://forum.arduino.cc/t/dcf-uhr-rhei ... /382692/53
habe ich aus dem letzten Beitrag den Code kopiert und versucht diesem für den Ardurino Uno anzupassen.
Das hat mich aber auch nicht weiter gebracht, die Schaltung ist anders aufgebaut als meine.

Was muss ich in dem oben geposteten Arduino Code einfügen oder austauschen damit
die Uhr per DCF77 Signal läuft?
Benutzeravatar
Andreas_P
Beiträge: 1400
Registriert: Mo 12. Aug 2013, 11:35
Wohnort: Lohr am Main
Kontaktdaten:

Re: DCF77 Modul in Arduino Code einbinden nur wie?

Beitrag von Andreas_P »

Ich habe es mal so versucht.

Code: Alles auswählen

#include <Time.h>
#include <TimeLib.h>
#include <DCF77.h>

#define DCF_PIN A3  
#define DCF_INTERRUPT 0   

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


#define A0 14 //ANALOG 0
#define A1 15
#define A2 16
#define INTERVAL 1000

//PINS SEKUNDEN MINUTEN STUNDEN
byte oneSecond[] = {0,1,2,3,4,5,6,7,8}; //No Serial on 0/1
byte tenSecond[] = {9,10,11,12,13};     //
byte theSwitch[] = {14,15,16};          //SEKUNDE MINUTE STUNDE
int s10=0,s1=0; //ONESECOND TENSECOND BAND
int m10=2,m1=3; // Start mit 23:59:00 Uhr
int h10=1,h1=3;
#define STIME 60
int sync=STIME; //SyncSignTime

unsigned long t,t0; //TIMEINIT

void INTITIME(void){t0=millis();}
unsigned long TIMEREAD(void){return millis()-t0;}

void setup()
{int i;
 for(i=0; i<sizeof(oneSecond);i++)pinMode(oneSecond[i],OUTPUT);
 for(i=0; i<sizeof(tenSecond);i++)pinMode(tenSecond[i],OUTPUT);
 for(i=0; i<sizeof(theSwitch);i++)pinMode(theSwitch[i],OUTPUT);
 digitalWrite(A0, LOW);
 digitalWrite(A1, LOW);
 digitalWrite(A2, LOW);
 DCF.Start();
}

void loop()

{int i;
 t=TIMEREAD();
 do
 {for(i=0;i<sizeof(oneSecond);i++)digitalWrite(oneSecond[i],s1<=i?LOW:HIGH);  //EINERBAND SEKUNDEN
  for(i=0;i<sizeof(tenSecond);i++)digitalWrite(tenSecond[i],s10<=i?LOW:HIGH); //ZEHNERBAND SEKUNDEN 
  digitalWrite(A0, HIGH);//Masse an Sekunden
  delay(1);             //SHOWTIME SEKUNDEN
  digitalWrite(A0, LOW);
  for(i=0;i<sizeof(oneSecond);i++)digitalWrite(oneSecond[i],m1<=i?LOW:HIGH);  //EINERBAND MINUTEN
  for(i=0;i<sizeof(tenSecond);i++)digitalWrite(tenSecond[i],m10<=i?LOW:HIGH); //ZEHNERBAND MINUTEN 
  digitalWrite(A1, HIGH);//Masse an MINUTEN
  delay(1);             //SHOWTIME MINUTEN
  digitalWrite(A1, LOW);
  for(i=0;i<sizeof(oneSecond);i++)digitalWrite(oneSecond[i],h1<=i?LOW:HIGH);  //EINERBAND STUNDEN
  for(i=0;i<sizeof(tenSecond);i++)digitalWrite(tenSecond[i],h10<=i?LOW:HIGH); //ZEHNERBAND STUNDEN
  digitalWrite(A2, HIGH);//Masse an STUNDEN
  delay(1);             //SHOWTIME STUNDEN
  digitalWrite(A2, LOW);
 }while(TIMEREAD()<(t+INTERVAL));
 //---------------------------------
 s1++;                   //s++;
 if(s1>=10){s1=0;s10++;} 
 if(s10>=6){s10=0;m1++;} //m1++;
 if(m1>=10){m1=0;m10++;}
 if(m10>=6){m10=0;h1++;} //h1++;
 if(h1>=10){h1=0;h10++;}
 if(h10>=2 && h1>=4){h10=0;h1=0;}
}
Benutzeravatar
Hightech
Beiträge: 11306
Registriert: So 11. Aug 2013, 18:37

Re: DCF77 Modul in Arduino Code einbinden nur wie?

Beitrag von Hightech »

Um welches DCF Modul handelt es sich denn, liefert das die DCF Pulse oder das Zeitprotokoll?
Benutzeravatar
Andreas_P
Beiträge: 1400
Registriert: Mo 12. Aug 2013, 11:35
Wohnort: Lohr am Main
Kontaktdaten:

Re: DCF77 Modul in Arduino Code einbinden nur wie?

Beitrag von Andreas_P »

Ich verwende das DCF77 Modul was es mal bei Pollin gab.
Das tut glaube ich nur Pulse rausgeben.
Benutzeravatar
Finger
Administrator
Beiträge: 7392
Registriert: Di 12. Jun 2012, 20:16
Kontaktdaten:

Re: DCF77 Modul in Arduino Code einbinden nur wie?

Beitrag von Finger »

Schmeiß das weit weg! Die Dinger funktionieren manchmal bis selten und brauchen oft Stunden bis sie eingeschwungen sind! Die liefern das nackte Signal, eine LED dran verrät dir, ob es funktioniert. Wenn nicht, dann flackert die wie blöde. Die Dinger sind Müll durch und durch...
Benutzeravatar
Hightech
Beiträge: 11306
Registriert: So 11. Aug 2013, 18:37

Re: DCF77 Modul in Arduino Code einbinden nur wie?

Beitrag von Hightech »

Ja, kann ich bestätigen!!!
Benutzeravatar
Andreas_P
Beiträge: 1400
Registriert: Mo 12. Aug 2013, 11:35
Wohnort: Lohr am Main
Kontaktdaten:

Re: DCF77 Modul in Arduino Code einbinden nur wie?

Beitrag von Andreas_P »

OK, habe noch ein anderes Modul da.
Dieses habe ich mal an die Schaltung angesteckt.
Aktuelle Uhrzeit wird aber nicht angezeigt. Kann noch mal bitte jemand einen Blick auf dem Arduino Code werfen?
Benutzeravatar
Hightech
Beiträge: 11306
Registriert: So 11. Aug 2013, 18:37

Re: DCF77 Modul in Arduino Code einbinden nur wie?

Beitrag von Hightech »

Wie sieht es denn aus, funktioniert die DCF77 Uhr denn generell?
Funktioniert die Rheinturm-Uhr prinzipiell?

Also dieses Beispiel:
https://playground.arduino.cc/Code/DCF77/

Code: Alles auswählen

#include "DCF77.h"
#include "Time.h"

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

time_t time;
// Non-inverted input on pin DCF_PIN
DCF77 DCF = DCF77(DCF_PIN,DCF_INTERRUPT, true);

void setup() {
  Serial.begin(9600);
  DCF.Start();
  Serial.println("Waiting for DCF77 time ... ");
  Serial.println("It will take at least 2 minutes before a first time update.");
}

void loop() {
  delay(1000);
  time_t DCFtime = DCF.getTime(); // Check if new DCF77 time is available
  if (DCFtime!=0)
  {
    Serial.println("Time is updated");
    setTime(DCFtime);
  }    
  digitalClockDisplay();  
}

void digitalClockDisplay(){
  // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(" ");
  Serial.print(day());
  Serial.print(" ");
  Serial.print(month());
  Serial.print(" ");
  Serial.print(year());
  Serial.println();
}

void printDigits(int digits){
  // utility function for digital clock display: prints preceding colon and leading 0
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}
Benutzeravatar
Andreas_P
Beiträge: 1400
Registriert: Mo 12. Aug 2013, 11:35
Wohnort: Lohr am Main
Kontaktdaten:

Re: DCF77 Modul in Arduino Code einbinden nur wie?

Beitrag von Andreas_P »

DCF Modul und Rheinturm-Uhr Schaltung funktionieren.
Auf dem Arduino Uno habe ich nurnoch die Analogports A3 bis A5 frei.
Benutzeravatar
Hightech
Beiträge: 11306
Registriert: So 11. Aug 2013, 18:37

Re: DCF77 Modul in Arduino Code einbinden nur wie?

Beitrag von Hightech »

Welchen Port du nutzt ist ja egal, so lange es nicht Komplikationen mit den beiden Codes gibt.
Also tut die DCF77 und die Uhr auf der selben Hardware funktionieren, nur nicht beide Programme gleichzeitig?
Benutzeravatar
Andreas_P
Beiträge: 1400
Registriert: Mo 12. Aug 2013, 11:35
Wohnort: Lohr am Main
Kontaktdaten:

Re: DCF77 Modul in Arduino Code einbinden nur wie?

Beitrag von Andreas_P »

Genau beides funktioniert auf den gleichen Arduino.
Für das DCF77 benutze ich ein Testprogramm das ich weiter oben schon einmal gepostet hatte. Dort ist auch der Code für die Uhr ohne DCF77 Modul vorhanden.
Beide habe ich unabhängig voneinander laufen lassen. Beide Programme funktionieren, sowie die Hardware.
Morgen mal den Pin2 für das DCF77 Modul auf dem Analog Pin A3 umschreiben.

Update: Vorhin festgestellt das ich morgen nochmal mit dem Code von vorne anfangen darf. :(
Benutzeravatar
Andreas_P
Beiträge: 1400
Registriert: Mo 12. Aug 2013, 11:35
Wohnort: Lohr am Main
Kontaktdaten:

Re: DCF77 Modul in Arduino Code einbinden nur wie?

Beitrag von Andreas_P »

Ich habe heute Vormittag versucht den Arduino Code von der Rheinturmfunkuhr mit Arduino http://www.hjberndt.de/soft/rtctftdcf.html
auf dem Code der Rheinturmuhr mit Arduino http://www.hjberndt.de/soft/rtc.html anzupassen.

Das ist mein Arduino Code.

Code: Alles auswählen

//DCF77
#include <DCF77.h>  
#include <TimeLib.h> 

#define DCF_PIN 2  
#define DCF_INTERRUPT 0   

//time_t time;
DCF77 DCF = DCF77(DCF_PIN,DCF_INTERRUPT);
#define A0 14 //ANALOG 0
#define A1 15
#define A2 16
#define INTERVAL 1000

//PINS SEKUNDEN MINUTEN STUNDEN
byte oneSecond[] = {0,1,2,3,4,5,6,7,8}; //No Serial on 0/1
byte tenSecond[] = {9,10,11,12,13};     //
byte theSwitch[] = {14,15,16};          //SEKUNDE MINUTE STUNDE
int s10=0,s1=0; //ONESECOND TENSECOND BAND
int m10=2,m1=4;
int h10=1,h1=9;
#define STIME 60
int sync=STIME; //SyncSignTime

unsigned long t,t0; //TIMEINIT

void INTITIME(void){t0=millis();}
unsigned long TIMEREAD(void){return millis()-t0;}

void setup()
{int i;
 for(i=0; i<sizeof(oneSecond);i++)pinMode(oneSecond[i],OUTPUT);
 for(i=0; i<sizeof(tenSecond);i++)pinMode(tenSecond[i],OUTPUT);
 for(i=0; i<sizeof(theSwitch);i++)pinMode(theSwitch[i],OUTPUT);
 digitalWrite(A0, LOW);
 digitalWrite(A1, LOW);
 digitalWrite(A2, LOW);
}

void loop()
{int i;
 t=TIMEREAD();
 do
 {for(i=0;i<sizeof(oneSecond);i++)digitalWrite(oneSecond[i],s1<=i?LOW:HIGH);  //EINERBAND SEKUNDEN
  for(i=0;i<sizeof(tenSecond);i++)digitalWrite(tenSecond[i],s10<=i?LOW:HIGH); //ZEHNERBAND SEKUNDEN 
  digitalWrite(A0, HIGH);//Masse an Sekunden
  delay(1);             //SHOWTIME SEKUNDEN
  digitalWrite(A0, LOW);
  for(i=0;i<sizeof(oneSecond);i++)digitalWrite(oneSecond[i],m1<=i?LOW:HIGH);  //EINERBAND MINUTEN
  for(i=0;i<sizeof(tenSecond);i++)digitalWrite(tenSecond[i],m10<=i?LOW:HIGH); //ZEHNERBAND MINUTEN 
  digitalWrite(A1, HIGH);//Masse an MINUTEN
  delay(1);             //SHOWTIME MINUTEN
  digitalWrite(A1, LOW);
  for(i=0;i<sizeof(oneSecond);i++)digitalWrite(oneSecond[i],h1<=i?LOW:HIGH);  //EINERBAND STUNDEN
  for(i=0;i<sizeof(tenSecond);i++)digitalWrite(tenSecond[i],h10<=i?LOW:HIGH); //ZEHNERBAND STUNDEN
  digitalWrite(A2, HIGH);//Masse an STUNDEN
  delay(1);             //SHOWTIME STUNDEN
  digitalWrite(A2, LOW);
 }while(TIMEREAD()<(t+INTERVAL));
 //---------------------------------
 sync++; 
 time_t DCFtime = DCF.getTime();
 if (DCFtime!=0)
 {char n='0';
  tmElements_t tm;   
  breakTime(DCFtime, tm);
  //sprintf(s,"%02d:%02d:%02d",tm.Hour,tm.Minute,tm.Second);
  //Serial.println(s);
  h10=s[0]-n;  h01=s[1]-n;
  //m10=s[3]-n;  m01=s[4]-n;
  //s10=s[6]-n;  s01=s[7]-n;
  //tft.setCursor(3, 4);
  //sprintf(s,"%02d.%02d.%02d",tm.Day,tm.Month,
  //        tm.Year+1970-2000);
  //tft.print(s);
  sync=0;
 }
 else
 {s1++;                   //s++;
  if(s01>=10){s01=0;s10++;} 
  if(s10>=6){s10=0;m01++;} //m++;
  if(m01>=10){m01=0;m10++;}
  if(m10>=6){m10=0;h01++;} //h++;
  if(h01>=10){h01=0;h10++;}
  if(h10>=2 && h01>=4){h10=0;h01=0;}
}
 //waiting ...
 while(TIMEREAD()<(t+interval));
 //one second
 interval=analogRead(A0)==0?100:1000;
}
 
// s1++;                   //s++;
// if(s1>=10){s1=0;s10++;} 
// if(s10>=6){s10=0;m1++;} //m1++;
// if(m1>=10){m1=0;m10++;}
// if(m10>=6){m10=0;h1++;} //h1++;
// if(h1>=10){h1=0;h10++;}
// if(h10>=2 && h1>=4){h10=0;h1=0;}
//}

Habe leider keinen Plan mehr was ich im Code verändern muss, da mit es funktioniert.
Profipruckel
Beiträge: 1506
Registriert: Di 13. Aug 2013, 19:10
Wohnort: Niedersachsen Süd-Ost

Re: DCF77 Modul in Arduino Code einbinden nur wie?

Beitrag von Profipruckel »

Andreas_P hat geschrieben: Sa 8. Mai 2021, 21:49 Auf dem Arduino Uno habe ich nurnoch die Analogports A3 bis A5 frei.
Dann bemühe den Lötkolben und schaffe Pin2 frei.
Andreas_P hat geschrieben: Sa 8. Mai 2021, 14:24 Ich habe es mal so versucht.

Code: Alles auswählen

#define DCF_PIN A3
#define DCF_INTERRUPT 0
Ich bin nicht sicher, ob die Zuweisung "A3" zulässig ist, für digitalen Betrieb sind die Ports A0..5 als 14..19 ansprechbar, "#define DCF_PIN 17".

Aber, ich lese da Interrupt
https://www.arduino.cc/reference/de/lan ... interrupt/ :
Benutzbare Digitalpins für Interrupts Uno, Nano, Mini, andere 328-basierte 2, 3

Ich interpretiere das so, dass Du zwingend 2 oder 3 benutzen musst.

Es sollte doch machbar sein, in den Einsprung der DCF-Decodierung ein
Serial.print ("Routine erreicht ") reizubasteln und zu gucken?

Ich bin nicht der große Programmierkünstler, aber wenn bei mir etwas nicht laufen will, mache ich das so: Ich stricke Ausgaben dazwischen und gucke, wie weit ich komme. Anstatt seriell kann man auch ins Display schreiben, so man hat oder eine LED anknipsen.
Benutzeravatar
Andreas_P
Beiträge: 1400
Registriert: Mo 12. Aug 2013, 11:35
Wohnort: Lohr am Main
Kontaktdaten:

Re: DCF77 Modul in Arduino Code einbinden nur wie?

Beitrag von Andreas_P »

Als Eingangspin für das Funkuhrmodul habe ich als DCF_Pin 2 in verwendung.
Folgender Fehler wird von der IDE ausgegeben.

2021-05-09_19h06_00.jpg
Benutzeravatar
Sunset
Beiträge: 1498
Registriert: Fr 6. Dez 2013, 15:19

Re: DCF77 Modul in Arduino Code einbinden nur wie?

Beitrag von Sunset »

Andreas_P hat geschrieben: So 9. Mai 2021, 19:32 Folgender Fehler wird von der IDE ausgegeben.

Der Compiler sagt Dir, Deine Variable s, die Du als Array s[0] und s[1] benutzt, ist nicht definiert. Er kennt weder s noch s[0] oder s[1].
Benutzeravatar
Andreas_P
Beiträge: 1400
Registriert: Mo 12. Aug 2013, 11:35
Wohnort: Lohr am Main
Kontaktdaten:

Re: DCF77 Modul in Arduino Code einbinden nur wie?

Beitrag von Andreas_P »

So der nächste Versuch, leider bin ich kein Fachinformatiker oder Diplom-Informatiker.
Der Digitalpin des Ardruinos ist der Eingang für das DCF Modul.
Diesmal meldet Compiler keine Fehler, aber die Uhrzeit von dem DCF Modul wird nicht
über die LEDs ausgegeben. Irgendwo wird was nicht richtig verwurstet aber nur wo?

Code: Alles auswählen

//DCF77
#include <DCF77.h>  
#include <TimeLib.h> 

#define DCF_PIN 2  
#define DCF_INTERRUPT 0   

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

#define A0 14 //ANALOG 0
#define A1 15
#define A2 16
#define INTERVAL 1000

//PINS SEKUNDEN MINUTEN STUNDEN
byte oneSecond[] = {0,1,3,4,5,6,7,8}; //No Serial on 0/1
byte tenSecond[] = {9,10,11,12,13};     //
byte theSwitch[] = {14,15,16};          //SEKUNDE MINUTE STUNDE
int s10=0,s1=0; //ONESECOND TENSECOND BAND
int m10=0,m1=0;
int h10=0,h1=0;
#define STIME 60
int sync=STIME; //SyncSignTime

unsigned long t,t0,interval=1000; //TIMEINIT 
unsigned long TIMEREAD(void){return millis()-t0;}

void setup()
{int i;
 for(i=0; i<sizeof(oneSecond);i++)pinMode(oneSecond[i],OUTPUT);
 for(i=0; i<sizeof(tenSecond);i++)pinMode(tenSecond[i],OUTPUT);
 for(i=0; i<sizeof(theSwitch);i++)pinMode(theSwitch[i],OUTPUT);
 digitalWrite(A0, LOW);
 digitalWrite(A1, LOW);
 digitalWrite(A2, LOW);
 DCF.Start();
  t0=millis();
}

void loop()
{int i;
 t=TIMEREAD();
 do
 {for(i=0;i<sizeof(oneSecond);i++)digitalWrite(oneSecond[i],s1<=i?LOW:HIGH);  //EINERBAND SEKUNDEN
  for(i=0;i<sizeof(tenSecond);i++)digitalWrite(tenSecond[i],s10<=i?LOW:HIGH); //ZEHNERBAND SEKUNDEN 
  digitalWrite(A0, HIGH);//Masse an Sekunden
  delay(1);             //SHOWTIME SEKUNDEN
  digitalWrite(A0, LOW);
  for(i=0;i<sizeof(oneSecond);i++)digitalWrite(oneSecond[i],m1<=i?LOW:HIGH);  //EINERBAND MINUTEN
  for(i=0;i<sizeof(tenSecond);i++)digitalWrite(tenSecond[i],m10<=i?LOW:HIGH); //ZEHNERBAND MINUTEN 
  digitalWrite(A1, HIGH);//Masse an MINUTEN
  delay(1);             //SHOWTIME MINUTEN
  digitalWrite(A1, LOW);
  for(i=0;i<sizeof(oneSecond);i++)digitalWrite(oneSecond[i],h1<=i?LOW:HIGH);  //EINERBAND STUNDEN
  for(i=0;i<sizeof(tenSecond);i++)digitalWrite(tenSecond[i],h10<=i?LOW:HIGH); //ZEHNERBAND STUNDEN
  digitalWrite(A2, HIGH);//Masse an STUNDEN
  delay(1);             //SHOWTIME STUNDEN
  digitalWrite(A2, LOW);
 }while(TIMEREAD()<(t+INTERVAL));
 //---------------------------------


sync++; 
 time_t DCFtime = DCF.getTime();
 if (DCFtime!=0)
 {char n='0';
  tmElements_t tm;   
  breakTime(DCFtime, tm);
  sync=0;
 }
 s1++;                   //s++;
 if(s1>=10){s1=0;s10++;} 
 if(s10>=6){s10=0;m1++;} //m1++;
 if(m1>=10){m1=0;m10++;}
 if(m10>=6){m10=0;h1++;} //h1++;
 if(h1>=10){h1=0;h10++;}
 if(h10>=2 && h1>=4){h10=0;h1=0;}
}

Benutzeravatar
Hightech
Beiträge: 11306
Registriert: So 11. Aug 2013, 18:37

Re: DCF77 Modul in Arduino Code einbinden nur wie?

Beitrag von Hightech »

Naja, so grundsätzlich muss man den Code schon verstehen, sonst wird das nix.
Soweit ich das erkannt habe, wird die Rheinturmuhr aus der TIMEREAD() Funktion mit der "Uhrzeit" versorgt, und zwar wir die über die Zeitbasis millis() bebildet, was eigentlich nur ein hochlaufender Zähler ist in Millisekunden.
Die DCF-Uhr gibt die Zeit in die Variable "DCFtime"
Das heißt ja, man muss die Variable DCFtime an die Rheinturmuhr weitergeben.
Leider ist die Rheinturmuhr keine Funktion, an die man schlicht die Uhrzeit geben kann.
Man muss die DCFtime in millis umrechnen und dann in die Funktion TIMEREAD einbauen.
So, das wenn die Rheinturmuhr die Funktion TIMEREAD() aufruft, dort die DCFtime ausgelesen wird und in der richtigen Form übergeben wird.
Antworten