DCF77 Library

This library collects the hard part of The Clock into a reusable library. With this library you can have the same extraordinary noise tolerance for your own clock projects. In case you wonder what exactly “extraordinary noise tolerance” means read on here.

Before we go into the details have a look at the architecture overview picture. It is somewhat similar to the architecture of “The Clock”.


The differences are mainly due to the fact that I only wanted the decoder stuff in the library. Unlike other DCF77 libraries this library is not bound to any specific means of signal acquisition. Especially it is not bound to any pin at all. Instead it executes the inputprovider callback each millisecond. The input provider must be of type typedef uint8_t (*input_provider_t)(void);. That is it must have no arguments and return either 0 or 1 depending on the current state of the DCF77 signal.

Once per second it will execute the output handler callback and pass the current time to it. The output handler if of type typedef void (*output_handler_t)(const time_t &decoded_time);

These callbacks can be set with the functions




The input provider is mandatory the output handler is optional. If you do not set the output handler the clock will work anyway. However the output handler is very convenient in order to set a display in sync no matter what the main loop of your sketch is currently processing.

Alternatively you can retrieve the current time by calling the functions

DCF77_Clock::void get_current_time(time_t &now); // blocking till start of next second


DCF77_Clock::void read_current_time(time_t &now); // non-blocking, reads current second.

This sounds slightly complicated but it is very simple in practice. In order to illustrate the concept I included some examples with the library. You can download everything from github.


The library includes some examples to get you started.

DCF77 Scope

The DCF77 Scope does not rely on the library at all. It is an analysis and troubleshooting tool. If this tool does not give reasonable results the library will not work.

Swiss Army Debug Helper

The Swiss Army Debug Helber is the advanced version of the DCF77 Scope. It relies on the library and gives you lots of internal information. If the DCF77 Scope works correctly but the debug helper does not then you most probably have compiler issue. See the Software Incompatibilities below.

Simple Clock

The Simple Clock implements a rudimentary DCF77 clock to exhibit the basic functionality of the library.

The Clock – Library Version

The Clock – Library Version is the library based version of The Clock. This is the code that started it all.

Meinberg Emulator

The Meinberg Emulator emulates a Meinberg DCF77 Clock. I implemented it because it was easy and because there are some NTPD Meinberg Drivers out there.

Super Filter

The Super Filter is intended as a drop in enhancement for existing DCF77 projects. Just put the Super Filter between the DCF77 module and your existing gadget and you will have all the benefits of my library without touching your code. It basically decodes the signal and re-synthesize it. Thus you will get a 100% clean signal.


You can download the library and the examples from github.


Brett Oliver uses my Library for his incredible DCF77 master clock as well as for his Binary Clock.

Eric de Euiter uses my Library and the Super Filter for his DCF77 clocks. See the results of his first tests here.


The key to the outstandind noise tolerance of this library is the phase detection algorithm. Of course I added a stack of complex algorithms on top of it. If you understand this algorithm (or at least the implications of my analysis) you know why my library is so much better than a naive straightforward implementation.

Hardware Incompatibilities

My library will not work with a “modern” Arduino Uno. The Uno utilizes a resonator instead of a crystal. Since a resonator has a less stable clock this in turn would decrease the noise tolerance significantly. It also would require different constants for the phase lock. Since my goal is to push the noise tolerance to the limits I will offer no support for this platform. You have several options:

  1. get hold of an “old style” Arduino like e.g. the Blinkenlighty (which would also help to fund my blog).
  2. replace the Uno’s resonator with a crystal or a crystal oscialltor (requires some soldering skills)
  3. dig into my library and modify the time constants (possible, but gives poorer results, I neither recommend nor support this approach)

Software Incompatibilities

The initilization code for this library will stop timer 0 interrupts. Thus the Arduino’s millis() function will not work properly anymore. This is usually not an issue since my library is already keeping time, thus there should be no need for a redundant time keeping mechanism. If you absolutely require the Arduino’s standard time keeping you may activate it by setting TIMSK0 accordingly. However you need to understand that I never tested this setup, thus it might decrease the library decoder performance. Only reactivate this if you understand the implications of race conditions.

The library also reprograms timer2. Thus anything that relies on control of timer2 (e.g. msTimer2) will interfere with my library.

The library works fine with my Arduino 1.0 installations on Ubuntu. However for standard versions of Arduino (1.0 – 1.0.6) it compiles but fails to acquire a signal lock. The nasty reason for this is that the Arduino guys bundled an outdated version of avr-gcc with the newer versions of Arduino.

The simplest solution is to upgrade to Arduino 1.5.8 Beta or above. This is because with 1.5.7 Beta Arduino is bundled with a brand new version of AVR-GCC.

Pin Mappings

Some readers wondered to which pins my library maps. The answer is: none. This library was designed to be completely pin agnostic. This of course rises the question how this library learns about the signal. The answer is that YOU have to provide the code for sampling the desired input pin. An example of how to do this is in the simple clock implementation. Watch out for the function “sample_input_pin()”.

Some readers also wondered what the meanings of the constants in my examples are. Of course I described them somehwere in my blog. But if you do not want to go through all of my articles here is the list of some standard constants that I use.

If these constants do not suit your needs, just change them. The library has no implicit dependency to any pin at all. So you can use any pin as long as it is not in use for something different.

name typical value comment
dcf77_analog_sample_pin 5 input pin for analog sampling
dcf77_sample_pin 19 input pin for digital sampling, notice D19 == A5
dcf77_inverted_samples 1 0 or 1 depending on your DCF77 module
dcf77_analog_samples 1 1 => analog sampling, 0 => digital sampling, Blinkenlighty needs analog samples see comment below
dcf77_monitor_pin 18 displays the signal the software received, common Arduinos might want to use 13 because this is connected to the only LED

With regard to the analog vs. digital sampling. Analog mode will work with any Arduino I know. However it consumes slightly more resources. For the Blinkenlighty it is the only admissible mode if you do not want to disconnect the LED bar. So set this to 1 for the Blinkenlighty. For all others you may want to set this to 0.

Depending on this mode either the sample pin or the analog sample pin will be evaluated. Of course these constants may point to the SAME pin. In digital mode the digial sampling pin is used in analog mode the analog sampling pin is used. The choice of the mode has absolutely no effect on the noise tolerance. In the end it only controls the threshhold between a “low” and a “high” signal.

If you are unsure about the pin mappings use the DCF77 scope with your pin mappings to verify if you got them right.

47 Responses to DCF77 Library

  1. I’m currently looking into adopting the library in one way or another. More specifically I want to improve the decoding robustness for a Wordclock project [1]. However, I’m not sure as to whether your library is suitable for our situation, because we use the internal RC oscillator of an Atmel ATmega168/328.

    If it shouldn’t be possible to adopt your library directly, it would be great to get some advice for implementing a solid and robust filter on our own. Knowing what you know now (after having spent a couple of months dealing with all of this), what would you personally suggest is a good compromise between spent effort (time, code size) and actual improvements. Personally I’m of the opinion that the exponential filter approach looks the most promising, because it is relatively straight forward to implement and according to your blog entry improves the decoding capability by a lot.

    I have another couple of questions, which are more subjective and I’m asking them just out of interest:

    – Have you ever dealt with DCF77 modules that would only return a low level in cases they are interfering with some PWM signal? I’ve two modules that are permanently low in some instances, so filtering in software won’t even work. What can be done about this?

    – Do you know about the capacitor mod for Conrad DCF77 modules proposed in the current “c’t Hardware Hacks”? They suggest to add a decoupling capacitor parallel to a diode on the module, which seems to improve the quality of the signal. Personally I haven’t observed any improvement, so I’m not sure as to whether this makes any difference at all.

    – Have you noticed any difference in the modules from Pollin, Conrad and Reichelt? Only recently I’ve made the experience that the ones from Pollin seem to be more robust. Given that they only cast half as much as both of the other options, I’m really confused. Unfortunately they don’t work with TTL (5 V) logic, so you need some external components for the level shifting. What are your thoughts on this? I’m not talking about the industrial receiver(s) you have worked with here ;).

    [1]: https://www.mikrocontroller.net/topic/156661

    • The *best* solution regarding time and spent effort is to use an out of the box solution. For example HKW sells modules with internal clock. Taking opportunity cost into account this is the most efficient solution.

      Now if you want to follow the diy path the next best thing is to get a reasonable receiver module and a big antenna. I compared several DCF77 receiver modules. Again the professional solution wins. Especially because it will work with a bigger antenna (bigger is better here).

      The HKW module (like most of the professional modules) has a wider bandwidth. The cheap modules have a narrower bandwidth. The reasons why are intricate but this has the implication that the professional modul will pick up more (sic!) interference. I suspect that this is the reason why the professional modules seem to have better automatic gain control. The AGC seems to be the reason why the cheaper modules will flatten out if there is to much noise.

      Now with regard to the optimal filter approach. I would suggest to add a crystal oscillator. They come out of the box as complete modules and will cost you only one pin. Then you can use my super noise resistant library. In the last test I laid an active Smartphone on the Antenna. The HKW module’s signal went mad but the module continued to demodulate the crap. The library decoded the signal within ~30 minutes although there was no minute with at least 10 bit errors.

      If you do not want to go for a crystal and not for a smarter DCF module then I see only two more options:

      1) Use the exponential filter approach . But remember that the libary can deal with 15 dB worse SNR.

      2) Use a diy smart module. That is use another 328 with my library in it and use it to locally synthesize DCF77 again. I am very sure that this would even beat the HKW smart decoder module. If you are interested in this approach I would publish a sketch for it.

      With regard to filtering of powerline noise forget about the magic capacitor approach. The only reliable solution is to nail down the root cause. Get an oscilloscope or find one who owns an oscilloscope and determine what is going on. Once this is understood fix the root cause (e.g. add suitable caps or inductors or replace the power supply or whatever else might fix it). Then measure again and verify that you solved it. Anything else is just searching in the dark == a big waste of time.

  2. Unfortunately, adding an oscillator to the existing circuit is not really an option. Building a secondary board and connecting it via SPI / I2C on the other hand might be worthwhile. On the other hand the most annoying problem for me is that the modules won’t return anything when they are in a high noise environment, so a secondary circuit will not necessarily help with that. However, I’m not sure what exactly is going on, because looking at the powerline with an oscilloscope does not look suspicious. Maybe some EMF issues, but I neither have the capability to examine this, nor do I know how to fix it.

    Have you planned (or are you interested in) building a module (based on AVRs) hosting your code? I think this might be a good idea after all, so other projects could simply ask for the decoded time (and some status information) via SPI / I2C and/or any other arbitrary protocol (1-Wire).

    • Yes I put some thought into it but due to EEW regulations in Europe this would be prohibitive expensive, so I ditched this idea.

      • Do these regulations really apply if you sell a PCB for other hobbyists? Maybe you could sell it as a kit? It seems to work fine for other projects …

      • Unfortunately they apply. I have registered for business (because that way I can order stuff that I would not get otherwise). However this also implies that authorities can assume that I know what I am doing. I already analyzed the issue and EEW definitely applies to me. This was the reason why the Blinkenlight Kit was first sold in the US. It was also the reason why I teamed with Franzis to sell the shield in Germany. I would have to check if Franzis or some other distributor would be willing to pick up my DCF stuff. IMHO the easiest way would be to take some prefabricated Atmel board that features a crystal. These are available for 15 Euro or less. Then just flash my code to it and connect whatever DCF77 module you want. I suggest HKW modules which are around 20 Euro. Pollin modules are also OK for their price but I will always go for quality. Now suppose I would sell this as a kit. Then we would end up around 50-60 Euro because I also have to account for the associated risk. Would there be any demand at this price point? I doubt this. Reason: IMHO the only demand is from people at some expert level. These people could easily source the stuff wherever they want and just flash my library to it.

  3. Karl says:

    I’m trying to get your DCF-77 Library working with a “Freaduino MEGA2560 White Color” Board, which features a crystal and has a reasonable clock deveation of about 200ms every 3600 seconds resulting in a shift of 888 Hz. I use an EM2S-DCF Module and the AFET100-77,5-DD antenna from HKW-Elektronik.

    I’m on a Mac and tried with the available Arduino IDEs. With Arduino 1.0.0 and Arduino 1.0.5 (with avr-gcc version 4.3.2) i can compile and run the DCF77_Scope example which shows the beforementioned clock deveation.

    The “Simple_Clock” and “The_Clock” sketches also compile and run on the board, but i never get the time output.

    When i use Arduino 1.5.7 beta with “Simple_Clock” i get the following error when compiling:

    /Users/karl/Documents/Arduino/libraries/dcf77_library/dcf77.cpp: In function ‘void DCF77_Encoder::_ZN13DCF77_Encoder14advance_minuteERN5DCF7711time_data_tE.part.4(DCF77::time_data_t&)’:
    /Users/karl/Documents/Arduino/libraries/dcf77_library/dcf77.cpp:3142:1: internal compiler error: Bus error: 10
    libbacktrace could not find executable to open
    Please submit a full bug report,
    with preprocessed source if appropriate.
    See for instructions.

    The revisions.txt of Arduino 1.5.7 beta says “Upgraded AVR toolchain: gcc 4.8.1, avr-libc 1.8.0”.

    I read your post on the arduino-forum regarding the avr-gcc issues on linux, but couln’t figure out if i have the same problem:

    Any ideas how i can get this working?

    (The Hardware works flawlessly with the DFC-77 library of Thijs Elenbaas, but not in the specific place where i need it to be working, because of bad signal quality)

    • 4.3.2 is definitely outdated. I never tried 4.8.1. I use 4.5.3. I suggest you give 4.5.3 a try and see how if it compiles.

      • ZT says:

        I’m doing some tests using Arduino 1.5.7 Beta, beacuse avr-gcc 4.7.0 crash compiling everything for mega2560 and I can’t find 4.5.3 for windows. I get this error:

        Arduino:1.5.7 (Windows XP), Scheda:”Arduino Mega or Mega 2560, ATmega2560 (Mega 2560)”

        \Arduino\libraries\dcf77_library\dcf77.cpp: In function ‘void DCF77_Frequency_Control::process_1_Hz_tick(const DCF77::time_data_t&)’:
        \Arduino\libraries\dcf77_library\dcf77.cpp:2971:70: error: using temporary as lvalue [-fpermissive]
        ((DCF77::time_data_t)decoded_time).leap_second_scheduled = true;
        \Arduino\libraries\dcf77_library\dcf77.cpp:2979:70: error: using temporary as lvalue [-fpermissive]
        ((DCF77::time_data_t)decoded_time).leap_second_scheduled = leap_second_scheduled;

        Searching arount internet I’ve found some indication to add -fpermissive to compiler flags. Adding this flag the compiler crash and tell to report the crash as gcc bug.

      • I have no idea why avr-gcc 4.7.0 crashes. But it is definitely a compiler issue. Arduino ships by default with an outdated compiler. I am currently using avr-gcc 4.5.3 Would you mind to try 4.5.3? If you tell me the settings for the “inverted mode” I could compile a “debug helper” for you board. Did you need to modify anything for the timer setup or did it work? I am asking because I have no Atmega 2560 around. So if some modifications are needed for the timing I would need this piece of code.

        If there is no 4.5.3 for windows I can only recommend to boot Linux from an USB stick. Although Linux might be unfamiliar to you the Arudino IDE looks exactly the same.

      • ZT says:

        I can not try on the real card at the moment (failure of power supply and failure of all attached devices ….. But replacements are coming.), So I’m just compiling the code. I’ve never tested the library on Mega2560 Because I was never able to complete the scketch.I think that could be nice modify the library to use automatically timer4 or 5 or 6 if the target is Mega2560 (so standard arduino funtions aren’t compromised). I’m also looking for a way to compile using beta arduino ide. The error “using temporary as lvalue” is not really a compiler issue but a new working mode of gcc that need some code changes.

      • I agree that it would be nice. However I do not have a 2560 board, so I can not test this. I suggest that you check out my code from github here. Then add the necessary stuff. Once you tested it issue a pull request and I will integrate it into the code base. The only stuff that you need to change is the implementation of void init_timer_2(). In addition the ISR(TIMER2_COMPA_vect) has to be replaced by a vector that is suitable for your timer. Both reside close to the end of dcf77.cpp. You do not need to deal with macros to find out which board you are on, I would add this part of the code.

  4. karlkliem says:

    I followed Andy Browns instructions and installed avr-gcc 4.7.0 with Arduino 1.0.0 on Windows, which you were refering to as well. With the Scope sketch the serial monitor shows the following:

    1, +———+———+———+———+———+———+———+———+———+———
    2, 52——–+———42——–+———42——–+———42——–+———42——–+———
    3, 42——–+———42——–+———42——–+———42——–+———42——–+———
    4, 42——–+———42——–+———42——–+———42——–+———42——–+———
    5, 42——–+———42——–+———42——–+———42——–+———42——–+———
    6, 42——–+———42——–+———42——–+———42——–+———42——–+———


    And the Simple_Clock sketch still does not sync.

    As i also didn’t find any information about how to install avr-gcc 4.5.3 (or a similar version) with the Mac Arduino IDE (and my attempt with Ubuntu 14.04. also installed the latest version of avr-gcc) i’m about to give up and order a HKW-Elektronik FUM1 FSK module, which would do the decoding for me.

    Though it would be great if you could provide information about how to get a setup for compiling your DCF77 library on Mac, Windows and Linux. Greetings and thanks!

    • Of The scope shows that you are NOT picking up any DCF77 signal. There are several possible reasons.

      • There is something close to the antenna that interferes with DCF77
      • The module has an open collector output and you are missing a pullup
      • The wiring of the module is wrong, e.g. missing ground connection

      Hence I would be more than surprised if it would pick up anything at all.

  5. karlkliem says:

    Finally i get the sync! Thanks!

    Although it’s strange. I had the same circuit connected to the same computer and uploaded the same sketch. At first with the Mac Arduino IDE and then with the Windows Arduino IDE (inside a Parallels Desktop VM), and it didn’t work. Now i tried again copy/pasting the sketch from one IDE to the other and it worked. Finally!

    If i find the time i will try to get avr-gcc 4.5.3 running with the Mac Arduino IDE. In case i succeed i’ll make a post.

  6. karlkliem says:

    It’s going to be in a building in Vienna, which i haven’t seen myself yet. Until now i just sent a test setup with the Conrad Elektronik DCF module and the 100mm HKW antenna and an Arduino sketch building upon the library of Thijs Elenbaas. They could get a signal in one floor of the building which has windows, but not in the floor where the clock will be installed. The walls in that floor seem to be made out of reinforced concrete. My plan is to deliver another test setup with your library and the HKW module now.

  7. Andreas says:


    I started to test your DCF77 lib with the noise reduction algorithm.
    Works fine!. But it uses the Pin A5 and I want to use this pin for I2C.
    All tries to connect to another pin failed…. Does it work with a different pin and how?

    Thanks, Danke. Andreas

    • The library has no intrinsic pin binding. All binding happens by the calling program. It can be bound to any pin as long as this pin is not in use otherwise. Just change the constants accordingly. I will make the section “pin mappings” a little bit more explicit on this topic.

  8. ZT says:

    Hi, I’m playing round your library to develope a clock. I need to play tones on a piezio speaker, but all library use millis(), and this funtion was compromised by your library. I’m not a good programmer bue I see that the library has an internal function called 1000 times as second, so is simple to add a method that do the same thing as original millis(). Are there a way to override millis() in a transparent way so all libraries that use this function still work?

    • Hi, as far as I know there is no such way. To achieve this it would be necessary to somehow write to the variable volatile unsigned long timer0_millis = 0 of wiring.c Alternatively it would be necessary to replace unsigned long millis() from wiring.c.
      I am not aware of any way to achieve this “transparently” without actually patching wiring.c. If you would give more details on what you are actually trying to achieve (more details means CODE) then maybe I can find a better solution.

      • ZT says:

        I haven’t the code here but the example is simple to explain.
        I have to use this library: http://playground.arduino.cc/Code/ToneAC
        This library generate a tone (note), forever or for a specific time. To track the note duration it use millis(). I could use the funcitons toneAC()/noToneAC() to start/stop the notes and generate the melody, but I need some calls that give me a time with at least 5ms of resolution, better if 1ms. So a function, on your library, that return a values as millis() do or that return current time with 1/1000s resoultion can be a good workaround.

  9. Have a look at the http://blog.blinkenlight.net/experiments/dcf77/simple-clock/ example. The sample_input_pin method is called once per millisecond. Thus if you could define a global counter
    volatile unsigned long my_millis;
    Then increment this counter in sample_input_pin, e.g. put
    ++my_millis; as the first line into sample_input_pin
    Then use something like

    unsigned long read_my_millis() {
    const uint8_t oldSREG = SREG;
    const unsigned long m = my_millis;
    SREG = oldSREG;
    return m;

    To read the desired milliseconds. Do not use my_millis, otherwise you will get some nasty race condition.

  10. Paul says:

    Do you have any thoughts on where/what changes would be required to adapt your filtering methods and library to other time code formats such as used by MSF, JJY, or WWVB? For example, DCF uses .1S and .2S carrier reductions for 0s and 1s except the last second while WWVB uses .2S and .5S for 0 and 1, but also has a .8S marker every 10S. There are also MSB/LSB first differences but I think I can handle that. Any pointers would be appreciated!

  11. Sorry for the late answer but I was two weeks on vacation without ANY internet access. Seems you have been reading my mind. This is exactly what I was asking for with my http://blog.blinkenlight.net/2014/11/01/wouldnt-it-be-nice/ article :)

    I suggest to proceed as follows:

    0) Ensure you have version control in place. This is going to be a somewhat longer project. I recommend GIT http://blog.blinkenlight.net/2013/11/01/all-you-can-git/ but if you are familiar with a different version control systems it will be just as good.

    1) Ensure that you have suitable hardware. “See hardware incompatibilities” for the details. I suggest two Arduinos with crystal oscillators for reasons that will become apparent soon.

    2) Ensure that my library compiles properly. That is ensure that your installation has a suitable compiler. See the “software incompatibilites”. The simplest way is to ask gcc for its version. The recommended way is to run the “swiss army debug helper” http://blog.blinkenlight.net/experiments/dcf77/swiss-army-debug-helper/ vs any module DCF77, WWVB or MSB/LSB and see if it drifts. If not everything is fine.

    3) As a first implementation step I suggest to implement a [WWVB|MSB|LSB]_ENCODER. Instead of the DCF77_ENCODER. This namespace can then be used to implement an emulator to create arbitrary time signals (similar to the way I implemented for the superfilter: http://blog.blinkenlight.net/experiments/dcf77/super-filter/). This step is needed sooner or later as the encoder is used in the decoder logic as well. I would implement it as early as possible since this is one of the easiest parts and it established test capabilities. Now it should be obvious why I recommended two Arduinos in step 1.

    4) Then I suggest to proceed with an implementation of the phase lock logic. Instead of modifying the library I would first reimplement the standalone version http://blog.blinkenlight.net/experiments/dcf77/phase-detection/. What you need to do is to figure out a proper filter kernel and tweek the summation logic accordingly. This is by far one of the trickiest parts. Therefore it should be implemented and tested in a standalone version. Once this works as desired move it into your library. Do not forget to test if this can deal with a noisy signal. If the phase lock fails the rest of the decoder will fail.

    5) The next step is the second decoder. Again I suggest to reimplement the standalone version http://blog.blinkenlight.net/experiments/dcf77/second-decoder/ first. Here you need to figure out where there are suitable markers in your signal and how to deal with them.

    6) Once the second decoder is implemented the minute / hour / month / year decodes can be ported. This can be done stepwise. But you have to start with the minute decoders and go on to the hour / month / day / year decoders as they are cascaded. All of them are implemented in a similar fashion so once you are through with the minute decoder the others should be somehwat easy.

    7) Then you need to take care of the summer / winter time and leap seconds flags. Use text search to find where this stuff is located and adapt it.

    8) Adapt the convolution binning. Until you adapt this you should search for the string “convolution_binning_not_ready” and ensure that the corresponding if condition will always go for “sync_mark_binning”.

    9) After each step test your stuff. I am willing to help review the implementations but I may not have enough time to debug your code. If you have any questions just ask.

  12. Paul says:

    Thanks for the detailed reply. It will be a bit of work for me (I still have to grock the whole C++/OO thing forgetting my decades of procedural thinking and then more fully understand your code). I’ve forked your github library and will work from that. If I get anything useful completed I’ll contribute back of course. Thanks for documenting and sharing everything. It’s appreciated.

  13. Aido says:

    Hi Paul,

    I was also considering adapting the DCF77 library for use with MSF and am wondering if you have made any progress with this over the past couple of months?


  14. Paul says:

    Sadly, no. “RealLife” has interrupted things. However… I did just pickup again on another part of this project. I also have some basic WWVB encoder routines but they do not encode all possible bits yet. And by the way, it was just announced that we will be having a leap-second this year, so this will be a chance to check libraries against these rare occurances. I have not yet begun the DCF77 library porting though.

  15. Aido says:

    Hi Paul,

    Thanks for the speedy response.

    OK, I’m going to fork the DCF77 library in github and start working on an MSF library.

    I’ve only just started looking at the code but my initial thoughts are to maybe split the DCF77 library up into generic radio time signal code and DCF77 specific code. Then add some MSF specific code also. This will make the library a bit more modular so that other modules (WWVB etc.) may be added later. Hopefully I’ll find out quick enough if this is a good approach or not.

  16. Aido says:

    Hi Udo/Paul,

    I have done some work on adding MSF functionality to the DCF77 Library. It can be found on github at:

    It is currently untested but, as mentioned above, what I’ve done so far is first split the existing code into generic RadioClock functionality and DCF77 specific functionality. I then added MSF specific functionality.

    It’s a first draft and still a bit rough and untested. I would still appreciate your comments or suggestions.

    Amongst other things, in sync_mark_binning() I am currently not sure how best to use the fact that with an MSF signal bit A positions 52 to 59 are always 01111110. These 6 consecutive 1 bits thus uniquely identify the end of the minute.

    If you have any comment on the code maybe create issues on the github page rather than flood the blog here.

  17. Jochen Bruening says:

    Hi Udo,
    thanks for pulishing extreme usefull dcf77 lib. With DCF_Simple_Clock example as a starting point and minor modification DCF_Simple_Clock now runs with the cheap Pollin receiver displaying date and time on a 16*2 LCD-display.
    However beeing a newbee I wonder how to display weekday. It might be a silly question so pls add a hint where to find information on this issue.
    Thanks Jochen

  18. Jochen says:

    serial.println(now.weekday) works fine however I didn’t managed to use now.weekday as an index of a character array (containing “Mon”, “Thu”,…)
    Stupid question I know but beeing a C++ newbee …

    btw: weekday is not highlighted in the listing as all the other now.xxx items

  19. André says:


    I´m using your lib for the first time and yes, i´m happy that i found it.

    I have a little Problem, might be located between my ears ;-)

    This is my init Code:
    pinMode(dcf77_sample_pin, INPUT);
    digitalWrite(dcf77_sample_pin, dcf77_pull_up);

    I´m using it on a DUE and tried different input PINs.

    As long as the Clock was not synced or locked i call “DCF77_Clock::get_current_time(now);” once a minute. After the Clock was in sync only once a hour.

    My Problem was that after the Clock was in sync or locked i can´t use my Touchpanel anymore. It reacts only from time to time.
    Can this caused by the output_handler? If i´m right, this function was called every second – right? I didn’t use this function and didn´t declare it. As long as the Clock was not in sync everything was running smoth.

    Thanks in advance for any help or hint.

    Best Regards // André

  20. André says:

    I am on a bussines Trip for the next two or three Weeks and have nothing with me.
    I only can say that i´m using the actual Version 3 of the Lib.

    I will come back to you as soon as i´m back @home.

    Many thanks and best Regards

  21. Victor says:

    Hello, i was trying to use this library for some kind of wall clock at home, using the
    radio module as time/sync source.

    I’m not able to get time with it, even if it seems to receive a signal
    well, and i’m not really sure about what can be wrong.

    This is the module i am using
    http://www.mas-oy.com/uploads/Data%20sheets/DAEV6181B1COB.pdf , since
    it is dualband it has two control pins in order to turn off, and use 77
    or 60khz bands.

    I’m using an atmega328p, with the 3.3v and 8mhz bootloader (it works
    fine per-se on other things)

    On the example sketches i add:

    pinMode(4, OUTPUT);
    digitalWrite(4, HIGH);
    pinMode(2, OUTPUT);
    digitalWrite(2, LOW);

    on the setup section (just at the start), that sets the module to use
    the 77khz band (or should), i use pin3 (interrupt 1) as the input for
    the time signal (i attach some pics of the wiring)

    On the DCF77_Scope i get:

    22, X73——-+———+37XXXXXXXXXXXXXXXXXX73——-+———+37XXXXXXXXXXXXXXXXXX73——-+———
    24, X73——-+———+37XXXXXXXXXXXXXXXXXX73——-+———+37XXXXXXXXXXXXXXXXXX73——-+———
    26, X73——-+———+37XXXXXXXXXXXXXXXXXX73——-+———+37XXXXXXXXXXXXXXXXXX73——-+———
    28, X73——-+———+37XXXXXXXXXXXXXXXXXX73——-+———+37XXXXXXXXXXXXXXXXXX73——-+———
    30, X73——-+———+37XXXXXXXXXXXXXXXXXX73——-+———+37XXXXXXXXXXXXXXXXXX73——-+———

    I use:
    const uint8_t dcf77_sample_pin = 3;
    const uint8_t dcf77_inverted_samples = 1;
    const uint8_t dcf77_analog_samples = 0;
    const uint8_t dcf77_pull_up = 0;

    Using the sync examples i can leave it running for 30min and it only
    shows “Initializing……………” all the time, no date or time

    Do you know what could be wrong or where could i look? (i’m not really a programmer so i’m
    limited on the code side).


  22. Victor says:

    Hello, i was trying to use this library for some kind of wall clock at home, using the
    radio module as time/sync source.

    I’m not able to get time with it, even if it seems to receive a signal
    well, and i’m not really sure about what can be wrong.

    This is the module i am using
    http://www.mas-oy.com/uploads/Data%20sheets/DAEV6181B1COB.pdf , since
    it is dualband it has two control pins in order to turn off, and use 77
    or 60khz bands.

    I’m using an atmega328p, with the 3.3v and 8mhz bootloader (it works
    fine per-se on other things)

    On the example sketches i add:

    pinMode(4, OUTPUT);
    digitalWrite(4, HIGH);
    pinMode(2, OUTPUT);
    digitalWrite(2, LOW);

    on the setup section (just at the start), that sets the module to use
    the 77khz band (or should), i use pin3 (interrupt 1) as the input for
    the time signal (i attach some pics of the wiring)

    On the DCF77_Scope i get:

    22, X73——-+———+37XXXXXXXXXXXXXXXXXX73——-+———+37XXXXXXXXXXXXXXXXXX73——-+———
    24, X73——-+———+37XXXXXXXXXXXXXXXXXX73——-+———+37XXXXXXXXXXXXXXXXXX73——-+———
    26, X73——-+———+37XXXXXXXXXXXXXXXXXX73——-+———+37XXXXXXXXXXXXXXXXXX73——-+———
    28, X73——-+———+37XXXXXXXXXXXXXXXXXX73——-+———+37XXXXXXXXXXXXXXXXXX73——-+———
    30, X73——-+———+37XXXXXXXXXXXXXXXXXX73——-+———+37XXXXXXXXXXXXXXXXXX73——-+———

    I use:
    const uint8_t dcf77_sample_pin = 3;
    const uint8_t dcf77_inverted_samples = 1;
    const uint8_t dcf77_analog_samples = 0;
    const uint8_t dcf77_pull_up = 0;

    Using the sync examples i can leave it running for 30min and it only
    shows “Initializing……………” all the time, no date or time

    Do you know what could be wrong or where could i look? (i’m not really a programmer so i’m
    limited on the code side).

    • Hi Victor thanks for the detailed description. There are (at least) two issues why this fails.

      • You are running at 8 MHz instead of 16 MHz, thus the timing is completely wrong.
      • The output of your module looks like an unmodulated square wave. There is nothing that even faintly resembles a DCF77 signal.

      I suggest to first find a module that actually delivers DCF77 output. Then I suggest to go on with a 16 MHz setup.

      • Victor says:

        Hello, the output must be dcf77, i asked the manufacturer and that’s what they say, also running a simple sketch to measure the pulses i see 100 and 200 ms pulses (not exactly but close to the ranges you’d expect i think) like this:
        60s # 65ms
        60s # 119ms
        61s # 74ms
        61s # 11ms
        61s # 120ms
        61s # 187ms
        61s # 49ms
        61s # 9ms
        61s # 9ms
        61s # 35ms
        62s # 40ms
        62s # 3ms

        120s # 16ms
        120s # 124ms
        120s # 63ms
        120s # 31ms
        120s # 10ms
        120s # 48ms
        120s # 1ms
        120s # 60ms
        120s # 80ms
        121s # 48ms
        121s # 235ms
        121s # 14ms
        121s # 13ms
        121s # 22ms

      • This output looks OK. But the output of my scope code did not look OK. So probably you have some issues with your pin setup.

  23. Jochen says:

    As Arduino now supports the ESP8266 module (cheap and impressive features) pls have a look at the board dependencies of the library. Maybe/hopfully you can remove them :-)
    Have a look at the compiler messages here:
    Arduino: 1.6.5 (Windows 8.1), Platine: “Generic ESP8266 Module, Serial, 80 MHz, 40MHz, DIO, 115200, 512K (64K SPIFFS)”

    Build-Optionen wurden verändert, alles wird neu gebaut

    In file included from Simple_Clock.ino:19:0:
    C:\Users\Jochen\Documents\Arduino\libraries\dcf77-development/dcf77.h:621:10: error: #error Unsupported controller architecture
    #error Unsupported controller architecture
    C:\Users\Jochen\Documents\Arduino\libraries\dcf77-development/dcf77.h: In member function ‘void Internal::Binning::bins_t::get_quality(Internal::Binning::bins_t::lock_quality_t&)’:
    C:\Users\Jochen\Documents\Arduino\libraries\dcf77-development/dcf77.h:686:17: error: ‘CRITICAL_SECTION’ was not declared in this scope
    C:\Users\Jochen\Documents\Arduino\libraries\dcf77-development/dcf77.h:686:34: error: expected ‘;’ before ‘{‘ token
    C:\Users\Jochen\Documents\Arduino\libraries\dcf77-development/dcf77.h: In member function ‘uint8_t Internal::Binning::bins_t::get_quality_factor()’:
    C:\Users\Jochen\Documents\Arduino\libraries\dcf77-development/dcf77.h:696:17: error: ‘CRITICAL_SECTION’ was not declared in this scope
    C:\Users\Jochen\Documents\Arduino\libraries\dcf77-development/dcf77.h:696:34: error: expected ‘;’ before ‘{‘ token
    C:\Users\Jochen\Documents\Arduino\libraries\dcf77-development/dcf77.h:796:13: error: expected ‘}’ at end of input
    C:\Users\Jochen\Documents\Arduino\libraries\dcf77-development/dcf77.h: In member function ‘void Internal::DCF77_Local_Clock::read_current_time(Internal::DCF77_Encoder&)’:
    C:\Users\Jochen\Documents\Arduino\libraries\dcf77-development/dcf77.h:1720:13: error: ‘CRITICAL_SECTION’ was not declared in this scope
    C:\Users\Jochen\Documents\Arduino\libraries\dcf77-development/dcf77.h:1720:30: error: expected ‘;’ before ‘{‘ token
    Fehler beim Kompilieren.

    Dieser Report hätte mehr Informationen mit
    “Ausführliche Ausgabe während der Kompilierung”
    aktiviert in Datei > Einstellungen
    Thank you!

    • This is open source. See my standard comment here: http://blog.blinkenlight.net/2014/11/. If you want support for this board you have to provide 3 things:

      1. Provide a board specific implementation for the “critical section” macro.
      2. Provide a board specific implementation for the 1 kHz generator incl. the tuning factor.
      3. Test that it actually tunes (this step takes most of the time).

      If you are not willing to provide the work why should I? The issue is that I am not that interested in these boards. In particular I have no clue if it is even possible with them. As soon as their is network activity this might interfere with the timers –> testing is much more tricky than with standard boards.
      If you provide tested code and others confirm that it works I will integrated it. But do not expect that I work for free on request.

  24. Victor says:

    Hello again Udo (it won’t let me answer to your last message so i write this separately), this is the sketch i use for the signal example:

    unsigned long duration;
    void setup() {
    pinMode(3, INPUT);
    //needed to select 77Khz band –>
    pinMode(4, OUTPUT);
    pinMode(2, OUTPUT)
    digitalWrite(4, HIGH);
    digitalWrite(2, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(2, LOW);

    void loop() {
    duration = pulseIn(3, LOW); //datassheet says signal on = low
    Serial.print(“s # “);

    Do you know how would i need to translate it for the library? I mean, i was using the same setup() part on the library scope so the only difference could he how it is listening for the input, no?


    • How do you expect me to find any issues if you just give me partial pieces of the code. Upload your code as a whole to some site (e.g. Arduino Forum or as Github Gist or some dropbox) and tell me which version of the library you use. Otherwise I have not even a tiny chance to figure out what you did. Also I would need you exact setup, which version of Arduino are you running and which controller do you use? How did you wire it, what happened, what should have happened and why do you think my code is to blame?

      Looking at the logs the issue appears to be with your wiring / pin assignments.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s