headerDCF77
headerDCF77

Arduino DCF77 radio clock receiver – Hardware

| 37 Comments

(This is part 1 in a small series on using DCF77 for accurate time keeping with an Arduino. You can find post post #2 here and post #3 here)

DCF receiver Conrad Arduino DCF77 radio clock receiver   Hardware image

DCF receiver

This post deals with correctly connecting an Arduino to a DCF77 receiver, how to remove noise in the signal, in order to to decode the signal into a valid, atomic-clock-synchronized, time.

I use the “DCF-Empfänger BN 641138″ . It is relatively cheap and many others have reported good results. The connection is pretty simple, connect ground, and +5V to the Arduino and DCF output to a digital pin.

I connected the receiver to Arduino pin 2, because we can assign a flank-driven interrupt to it. It is important to connect the output to a pull-up resistor. Since I saw some spikes in the output signal (more on that later), I also added an additional bypass capacitor to decouple the power supply. Looking at the DCF board I see a capacitor that may already function as a bypass capacitor added, so feel free to leave this part out.

 

Connected DCF receiver bb1 Arduino DCF77 radio clock receiver   Hardware image

The schematic then looks like this:

Connected DCF receiver schem Arduino DCF77 radio clock receiver   Hardware image

DCF receiver connected to Arduino schematic

Note: I used Fritzing to create the breadboard and schematic view. If you want to use this DCF77 component for Fritzing, I added it to the DCF77 library, which you can download here.

next >>

37 Comments

  1. Hallo Thijs,

    Een leuk artikel over de DCF77 ontvanger. Ik heb zelf onlangs de DCF77 van de firma Pollin ontvangen maar nog niet uitgeprobeerd. Ik gebruik de Arduino 0023 versie.
    Heb je de arduino code voor deze DCF ontvanger ook in de .pde extensie beschikbaar? Ik zou graag deze versie willen uitproberen met mijn DCF77 ontvanger. Alvast bedankt!

    Mvg,
    Jack de Zeeuw

    • Hoi Jack,

      Bedankt! Je kan de voorbeelden gewoon hernoemen van .ino naar .pde. Voor de DCF77 bibliotheek ligt is dat wat lastiger, maar de Arduino 23 werkt ook prima met .cpp en .h files. Het belangrijkste is dat de files op de goede plek staan. Ik heb geen PDE of INO file gemaakt van de DCF77 van de bibliotheek, omdat ik deze op wilde zetten als een klasse. Een reden om dit te doen is dat de gebruiker van de klasse alleen de functies kan benaderen die hij nodig heeft, namelijk:

      DCF77.getTime();
      DCF77.getUTCTime();
      DCF77.Start();
      DCF77Stop();

      Je mag natuurlijk de code aanpassen als je wil, dat is het punt niet, maar bij gewoon gebruik vermindert encapsulation en datahiding de kans op fouten. Daarnaast is er er nog ander voordeel: Als ik een update van de DCF77 library doe, hoef ik alleen maar de aanroep van bovenstaande functies gelijk te houden. Je hoeft dan enkel DCF77.cpp en DCF77.h hoeven te vervangen, en je programma blijft werken. Ik laatst een dictaat hierover (Object Georiënteerd Programmeren) tegen, zie http://bd.eduweb.hhs.nl/ogoprg/pdf/Dictaat_OGPiCpp.pdf

  2. Hoi Thijs,

    Ik heb de bestanden opgeslagen naar de extensie .pde.
    Wanneer ik de InternalClockSyn.pde verify/compile krijg ik de volgende foutmelding:
    “time_t” does not name a type
    scope
    InternalClockSync:50: error: ‘year’ was not declared in this scope

    Wat doe ik verkeerd?

    Mvg,
    Jack

  3. Hoi Thijs,

    Ik krijg nog dezelfde foutmelding.
    Wat doe ik verkeerd?
    Vind je het goed als ik je een keer opbelt om mijn probleem te tekkelen.

    Mvg,
    Jack

    • Beste Thijs,
      heb hetzelfde probleem “time t does not name a type”
      Ik gebruik de laatste versie van de Arduino IDE. Mijn DCF komt ook van Pollin.
      De Arduino draait op een Rainbowduino, maar dat kan eigenlijk niet het probleem zijn. Ik vermoed dat de header file niet staat waar hij moet staan of zo, ben ook nog maar een beginner met Arduino. Zou je zo goed willen zijn even de juiste volgorde van files downloaden, unzippen en plaatsen in de IDe willen doorgeven?
      Dank,
      Jacob

  4. Hi,
    just tried out your library. Really nice work! Got my DCF-77 module working in less than 10 minutes. I waited longer for sucessfully signal synchronisation than I needed time for wiring. It’s the following very cheap module:
    http://www.pollin.de/shop/dt/NTQ5OTgxOTk-
    There is an extra pin, which allows to enable and disable the module. But attention: use the 3V3 output of Arduino. Furthermore I have added a 1k-resistor between the pins, which is not optimal for level converting, but gives me the feel of security for my DCF-module.
    Thank you!

    • Thanks, it’s always nice to hear that! I just had a look at the Pollin module and it is cheap indeed. Only half the price of the Conrad module (which wasn’t that expensive either). The extra pin seems like a good idea. What I understood is that in commercial (battery run) clocks the DCF77 module is turned on only once per day to save energy, typically during the night when reception of the DCF77 signal is typically better.

      Perhaps it would be interesting to add an example that implements this?

  5. Hello,

    thanks for your great work and thanks for sharing the code. i also have a DCF77 module from Pollin.de. On my Arduino, i don’t have free interrupts, is there a possibility to get the time via DCF77 without using interrupts?

    • Hi Thomas,

      Thanks! Unfortunately, there is no way to run the library without interrupts (although this library does not use the timer interrupt). Of course, you could change the interrupt part of the code into something that does polling. If you do this, I would suggest using one of the fast digitalRead implementations to minimize overhead. Also, if you do, could you send me the code, so I can posssible integrate it in a next version?

      Alternatively, you could try and switch the pin between the DCF receiver and the other functionality. One time DCF update per day would be enough, and signal reception is best during the night, anyways.

  6. Hi, nice work about DCF reception!

    But I do not understand what you wrote about “It is important to connect the output to a pull-up resistor.”

    If you connect some digital equipment to the Arduino which provides high and low levels of +5V and 0V on the output side, those digital outputs can go directly to an Arduino digital input pin. As far as I know.

    • Hello Thijs,
      please forget my question about hardware wiring and the pull-up resistor, meanwhile I know the answer myself: Your DCF module seems to provide an “open collector” (or “open drain”) output while my DCF module has a “push-pull” output instead.

      You will need to have a pull-up resistor to connect the DCF receivers data output to an Arduino input pin if the receiver provides an open collector data output. And you must connect it directly to the Arduino input if the DCF receiver provides a push-pull data output. My DCF1 module from Pollin provides a very weak (something > 5 µA) push-pull data output.

      • Hi Juergen,

        Indeed. My Conrad DCF receiver uses an open collector output, so a pull up resistor is needed. As a side note, the arduino can actually provide an internal pull-up (see this page), but I did not use that.

        Out of interest, what are you using your DCF clock time for?

        • Hi Thijs,

          I’m planning to use the DCF clock for two things:

          At first I’m planning to build a “visitor alert and memorising box” for a handicapped friend of mine.

          After that, I’m planning to make my own weather station with indoor and outdoor sensors, data logging and possibly transferring weather data of my home location into the Internet.

          In both cases, I’ll use a DCF clock for “low maintenance data logging with correct date/time”.

  7. hey,
    nice work! it work fine with the modules from ‘C’.
    but i have two (china?) that will need an invert input!
    it is possible, that you can quickly introduce me, how i change the setting, that your script work with an invert signal?
    best regards
    e.

    • Hi Eric,

      I send you an email with a test version of the library, supporting inverted pulses. If you instantiate it with
      DCF77(DCF_PIN,DCF_INTERRUPT, false);
      It should use inverted pulses. Let me know if it works, I could not test it with my module

      Cheers,

      Thijs

    • I think the only change needed for an inverted data logic is to invert the result of the “digitalRead” function that reads the pin where the DCF module provides the data signal.

      I have looked into the code and found only one line of source code affected:
      int sensorValue = digitalRead(dCF77Pin);

      So change that line in library file “DCF77.cpp” to a “not” result:
      int sensorValue = !digitalRead(dCF77Pin);
      and the library should work with inverted logic on the DCF77 data pin.

  8. Hallo Thijs,

    In de code wordt het verschil tussen twee tijdwaarden bepaald door ze van elkaar af te trekken.
    Wat gebeurt er als de timer in de tussentijd is overgelopen?
    Krijg je dan niet een negatief resultaat?

    Groeten, Meo

  9. Hi Thijs,
    Wishing you a good 2013!
    I’m experimenting with arduino and DCF signal. I guess I’m doing something wrong, but can’t figure it out…
    When using the arduino Uno board, I’m able to get a timesynch in a few minutes. When building the circuit on a breadboard (I just pull out the AT328 and put it on a breadboard, connected as needed), I’m not getting a synch at all. When just ‘blinking’ a LED, that’s not a problem. I connected a LED to the OUT of the DCFboard, that’s blinking also. I connected this to pin 4, that should be the equivalent of the D2 signal of the Arduino Uno. The timesynch is indicated by an LED, but it never comes. What could I be doing wrong? The only thing I could imagine is that I use a 16.4MHz crystal instead of 16.0MHz (they were out of stock). As the LED project is resulting in a blinking LED, the AT328 doesn’t seem to have a problem with that, I could imagine that the clock I want to make will run slightly fast, but as it is synchronising with DCF, that won’t be a problem either…
    If someone has an idea, please respond…
    Thanks.

    • Hmm, I would think you have interference issues again. Can you try moving the receiver a bit further away, twisting the cables going to the receiver and possibly using a different (bigger) by-pass capacitor?

      • Well, I replaced the crystal with a correct 16.000MHz type, and it works! As the DCF signal is a millisec signal, it seems that the input is not correctly read with a 16.4 crystal, while ‘only’ 2,5% difference in frequency.
        However, thanks for your reply!

  10. Thijs,

    Ik heb probleem :-( , heb de dcf van conrad, alles aangesloten zoals in je schema staat, de bib gedownload, de voorbeelden getest, weerstand weggelaten, condensator weggelaten, weerstand veranderd… nog maar eens en nog maar eens….maar het werkt niet…

    Ik krijg ergens een signaal binnen van de dcf-ontvanger, ik heb geprobeerd met een led op de uitgang en dit pulst ( wel onregelmatig maar vermoed dat dit zo moet zijn )

    als ik je voorbeeld dcf-pulslength gebruik krijg ik de volgende output in de SM

    heb je een idee, ik zit een beetje vast

    Tnx Tom

    Cycle: 117 Pulse :34
    Cycle: 205 Pulse :0
    Cycle: 2 Pulse :45
    Cycle: 48 Pulse :1
    Cycle: 2 Pulse :0
    Cycle: 3 Pulse :1
    Cycle: 325 Pulse :10
    Cycle: 30 Pulse :33
    Cycle: 34 Pulse :12
    Cycle: 107 Pulse :1
    Cycle: 111 Pulse :1
    Cycle: 4 Pulse :1
    Cycle: 2 Pulse :1
    Cycle: 3 Pulse :0
    Cycle: 89 Pulse :12
    Cycle: 43 Pulse :6
    Cycle: 522 Pulse :1
    Cycle: 2 Pulse :5
    Cycle: 14 Pulse :24
    Cycle: 147 Pulse :1
    Cycle: 2 Pulse :1
    Cycle: 6 Pulse :0
    Cycle: 2 Pulse :13
    Cycle: 213 Pulse :1
    Cycle: 73 Pulse :20
    Cycle: 421 Pulse :144
    Cycle: 155 Pulse :15
    Cycle: 96 Pulse :2
    Cycle: 3 Pulse :1
    Cycle: 2 Pulse :4
    Cycle: 42 Pulse :15
    Cycle: 21 Pulse :19
    Cycle: 242 Pulse :67
    Cycle: 877 Pulse :1
    Cycle: 2 Pulse :2

    • Ha, je hebt een uitdaging! :-) Typisch hebben de problemen te maken met stoorsignalen die binnenkomen via de voeding of via de antenne. Je kan het signaal proberen te optimaliseren terwijl je een van bovenstaande sketches draait:

      - Sluit een pull-up weerstand aan – dit heeft niet met ruis te maken, maar wordt soms vergeten
      - Gebruik een capacitieve bypass op de voeding – dit dempt stoorsignalen, zie schema
      - Pas de oriëntatie van de antenne aan – het signaal komt vanuit Duitsland
      - Gebruik 2 aard draden, twist er een met de voeding, en de ander met de signaal draad. – Dit verminderd door inductie opgepikte signalen
      - Leg je ontvanger niet te dicht bij je PC of voeding.
      - Voed je Arduino vanaf een batterij

      Succes!

      • 2 meter UTP er tussen gehangen en alles werkt!

        Tnx

      • Sorry I’m not good enough with Dutch :) , I think I’ve the same or very similar Tom’s issue.
        I use a DCF77 rec. from Conrad but I can’t get at all a valid signal.
        How can I improve reception?
        I have also an alarm clock from Oregon (afaik it use the same DCF sig)that works very well :(

        I’m in the center part of Italy on the Adriatic sea.

        Thanks in advance! :)

        • Don’t worry, my Italian isn’t that great either :-). In the comments me and others have suggested several signal improvements: better antenna, position further away from your PC, twisted wires, trying at night, etc. The signal seems to be totally random, though, not one correctly identified pulse. Are you sure everything is correctly connected and you have a pull-down resistor. What does the raw signal look like?
          Hope you can make it work!

  11. Hallo Thijs,
    Ik ben al een tijd bezig om uit het DCF signaal de meteotime data te decoderen. Als basis gebruik ik de informatie van Walter Freywald (een duidelijk blokschema) en een programma dat in C++ geschreven is . Dit laatste komt van de site “pastebin”
    Ik werk nooit met de taal C en ben een hobby programeur. Tot nu toe is het me altijd gelukt om de programma’s te schrijven in BASCOM . En de resultaten te laten draaien in ATMEL processoren. Ik heb dus alle belangrijke delen van het C-programma vertaald naar BASCOM. Als test datagebruik ik delogs van DCF die op de diverse sites beschikbaar zijn. Daar staat dan ook het gedecodeerde resultaat bij. Volgens het blokschema van Water Freywald wordt de DCF tijd informatie in twee delen van 20 bits opgesplits. Ook de gedecodeerde data staat in 42 bits.

    Het probleem is nu dat ik niet weet of mijn aanname van wat bit 0 en wat time L en H is. Van de DCF-logs maak ik test data. Ik deel de tidbits in twee. En van de data bits verwijder je eerst bit 0 en 7 (over dus 40) Ook deze 40 verdelen in twee. Ook hier is de vraag wat is Chipher LO en Chipher RO. Ik heb de data al op verschillende manieren aan mijn BASCOM programma aangeboden. Maar het resultaat is nooit het resultaat wat in de DCF-logs staat.

    Ik zal zeker ergens een programeerfout of denkfout maken, maar ik ben er nu al weken (soms 4 dagen per week) mee bezig.

    Misschien wil jij mij op weg helpen waar zit mijn denkfout

    Graag je reactie met vriendelijke groet,

    L.R

  12. Is het mogelijk om de 2 draadjes van de antenne te verlengen of heeft dit nadelige gevolgen voor het ontvangst.

    Floris

  13. Hallo Thijs,

    Ik zie dat CET en CEST is gedefinieerd, maar als private. Is er een optie om te zien vragen of het zomer of wintertijd is?

    Met vriendelijke groet,
    Erik

  14. Pingback: DS1302 Real Time Clock | Hard Copy Arduino

Leave a Reply

Required fields are marked *.