(This is part 3 in a small series on using DCF77 for accurate time keeping with an Arduino. You can find post #1 here and post #2 here)
Before we start to look at the library, let me start by saying that this is by no means the first Arduino DCF77 decoder. In fact, a large part of this library is based on the sketch made by Matthias Dalheimer. I did not intend to write a new library, but because of the noise spikes I was picking up, I started rewriting parts to make it work under noisy circumstances and, as these things seem to go, ending up writing a whole new library.
Because of the noise I added, besides the spike rejection, some checks on the decoded time. Furthermore I made made another major change in the code: The class library attaches an interrupt function to the DCF77 pin, which fills a buffer with the received bits. This interrupt-driven part is made to be quite lightweight, while the hard work (checking parity, calculating time, doing a few sanity checks) is done in the code called from the main loop. But because the interrupt driven loop fills the buffer (and starts filling a new buffer after that), so there is no real hurry in the main loop to re-enter the getTime function.
To use the library, first download the DCF77 library here:
and install it in the Arduino Library folder. For a tutorial on how to install new libraries for use with the Arduino development environment please refer to the following website: http://www.arduino.cc/en/Reference/Libraries. If the library is installed at the correct location, you can find the examples discussed in this and the previous post under Examples > DCF77. I also added the time library to the archiver for convenience.
Below is a demonstration of how the library processes the binary data and returns a time and date. In order for the example to give output on the binary stream make sure that logging is turned on in the DCF library. You can do this by adding the #define VERBOSE_DEBUG 1 in Utils.cpp.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
#include <Utils.h>
#include <DCF77.h>
#include <Time.h>
using namespace Utils;
#define DCF_PIN 2 // Connection pin to DCF 77 device
#define DCF_INTERRUPT 0 // Interrupt number associated with pin
time_t time;
DCF77 DCF = DCF77(DCF_PIN,DCF_INTERRUPT);
void setup() {
Serial.begin(9600);
Serial.println("1 - binary 1 corresponding to long pulse");
Serial.println("0 - binary 0 corresponding to short pulse");
Serial.println("BF - Buffer is full at end of time-sequence. This is good");
Serial.println("EoB - Buffer is full before at end of time-sequence");
Serial.println("EoM - Buffer is not yet full at end of time-sequence");
DCF.Start();
}
void loop() {
delay(1000);
time_t DCFtime = DCF.getTime();
if (DCFtime!=0) {
digitalClockDisplay(DCFtime);
}
}
void digitalClockDisplay(time_t _time){
tmElements_t tm;
breakTime(_time, tm);
Serial.println("");
Serial.print("Time: ");
Serial.print(tm.Hour);
Serial.print(":");
printDigits(tm.Minute);
Serial.print(":");
printDigits(tm.Second);
Serial.print(" Date: ");
Serial.print(tm.Day);
Serial.print(".");
Serial.print(tm.Month);
Serial.print(".");
Serial.println(tm.Year+1970);
}
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);
} |
After the first full cycle we get the feedback “time inconsistent” because:
- The difference between the DCF77 time and the internal time (still close to 0 -which translates to a date in 1970-) is too big
- The difference with there is no previous DCF77 time measurement is too big because, well, there is no previous measurement.
After the second cycle there is a previous measurement and both measurement points are consistent, and we get our first DCF77 time. Success! Note that the time queried with DCF.getTime() is compensated for the period between receiving the time from the receiver and the moment that it is queried from the library.
Now, let’s try an example that actually updates the internal clock time. For this example the output I turned logging off.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
#include "Utils.h"
#include "DCF77.h"
#include "Time.h"
using namespace Utils;
#define DCF_PIN 2 // Connection pin to DCF 77 device
#define DCF_INTERRUPT 0 // Interrupt number associated with pin
time_t time;
DCF77 DCF = DCF77(DCF_PIN,DCF_INTERRUPT);
void setup() {
Serial.begin(9600);
DCF.Start();
Serial.println("Waiting for DCF77 time ... ");
Serial.println("It will take at least 2 minutes until a first update can be processed.");
}
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);
} |
Resulting in the following output:
Finally, that kind of wraps things up. However, I want to demonstrate one last thing. I used the Time libraryquite a lot in the library, but it also has a feature that is you can nicely use in your main program.
Below is an example sketch showing how to use the syncProvider functionality to simplify the sketch code. Note that the loop code does not require any logic to maintain time sync and even the getDCFTime function could be removed to make the code even more concise. The Time library will automatically monitor DCF77 and sync the time as necessary.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
#include "Utils.h"
#include "DCF77.h"
#include "Time.h"
using namespace Utils;
#define DCF_PIN 2 // Connection pin to DCF 77 device
#define DCF_INTERRUPT 0 // Interrupt number associated with pin
time_t prevDisplay = 0; // when the digital clock was displayed
time_t time;
DCF77 DCF = DCF77(DCF_PIN,DCF_INTERRUPT);
void setup() {
Serial.begin(9600);
DCF.Start();
setSyncInterval(30);
setSyncProvider(getDCFTime);
// It is also possible to directly use DCF.getTime, but this function gives a bit of feedback
//setSyncProvider(DCF.getTime);
Serial.println("Waiting for DCF77 time ... ");
Serial.println("It will take at least 2 minutes until a first update can be processed.");
while(timeStatus()== timeNotSet) {
// wait until the time is set by the sync provider
Serial.print(".");
delay(2000);
}
}
void loop()
{
if( now() != prevDisplay) //update the display only if the time has changed
{
prevDisplay = now();
digitalClockDisplay();
}
}
void digitalClockDisplay(){
// digital clock display of the time
Serial.println("");
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);
}
unsigned long getDCFTime()
{
time_t DCFtime = DCF.getTime();
// Indicator that a time check is done
if (DCFtime!=0) {
Serial.print("X");
}
return DCFtime;
} |
ps. After writing this library I discovered another Arduino DCF77 class that is based on the code of Matthias Dalheimer at http://fiendie.net/arduino/funkuhr. I haven’t tried it, but the code looks quite clean, so give it a shot.




april 28, 2012 om 2:49 PM
Hallo Thijs,
Als ik het InternalClockSync programma viade verify toets test dan krijg ik volgende foutmeldingen.
InternalClockSync.cpp:13:19: error: DCF77.h: No such file or directory
InternalClockSync:19: error: ‘DCF77′ does not name a type
InternalClockSync.cpp: In function ‘void setup()’:
InternalClockSync:24: error: ‘DCF’ was not declared in this scope
InternalClockSync.cpp: In function ‘void loop()’:
InternalClockSync:31: error: ‘DCF’ was not declared in this scope
Ik gebruik Arduino 1.0.
Heb je enig idee wat de oorzaak kan zijn?
Alvast bedankt,
Michielsen Luc
april 29, 2012 om 9:39 PM
Hi Luc,
Het probleem is dat de DCF77 niet gevonden kan worden, en in de meeste gevallen betekent dit dat de files op de verkeerde locatie staan.
Op de Arduino site staat er dit over geschreven:
http://www.arduino.cc/en/Hacking/Libraries
Ik heb hier zelf alleen ervaring mee onder Windows (7), daar heb je 2 opties:\libraries\DCF77\DCF77.h, DCF77.cpp, etc \Documents\Arduino\DCF77\DCF77.h, DCF77.cpp, etc
- Als een standaard bibliotheek: D:\
Zo heb ik de boel geinstalleerd, maar het volgende zou ook moeten werken:
- Per gebruiker, dan zou de file hier terecht moeten komen C:\Users\
Als het goed is zie je dan in de Arduino IDE de examples onder Examples>DCF77.
Succes!
Thijs
juli 2, 2012 om 9:24 PM
Hi Thijs,
I just downloaded your DCF77 library from the Arduino Playground. It
works great, thank you very much!
Maybe you are interested to know that there is a little thing at line
94 in DCF77.cpp that prevents the user from changing the DCF input pin.
In function void DCF77::int0handler() it says:
int sensorValue = digitalRead(2);
but should be:
int sensorValue = digitalRead(dCF77Pin);
This is only for your information – I am far away to complain!
Have fun!
Regards
Sabine
juli 2, 2012 om 9:58 PM
Hi Sabine,
Thanks for caching that! I will solve this in the next release. Good luck using the library. if you have been able to use it in a project, I’m always interested to hear about it.
Thijs
juli 3, 2012 om 9:00 PM
Hi Thijs,
I am trying to build a standalone rf transmitter for the digital ham radio mode WSPR using an Arduino and a DDS. With the help of your library, I now got he time base running and will now try to set the DDS to the MFSK frequencies to transmit. Hope I will succeed!
Best regards
Sabine
augustus 8, 2012 om 12:02 AM
Hi Thijs,
when I use the library with the DCF-2 hardware ( http://www.elv.de/i-c-realtime-clock-i2c-rtc-komplettbausatz.html ), the DCFPulseLength example sketch
prints unexpected results: the cycle length is around 1000 ms, but the
Pulse length is always in a range around 900 ms (maybe 800-920).
This probably is the reason why the time is never synchronized. Do you have an
idea about the reason for this effect, and how to debug it?
Heiner
augustus 8, 2012 om 12:11 AM
Sorry, I posted the wrong URL. The correct one is as follows:
http://www.elv.de/dcf-empfangsmodul-dcf-2.html
augustus 19, 2012 om 9:49 PM
Hi Heiner,
I had a look at the specifications of the DCF-2 hardware, and they seem pretty much similar to the ones of the Conrad DCF module that I’m using. One thing I see is that the manual suggests a pull up resistor of 0.5 – 1 kOhm, rather than the 10kOhm I used in my schematic. You could also try and remove the by-pass capacitor and see what happens. Is there something interesting to see in the DCFSignal sample?
Good luck, Thijs
augustus 20, 2012 om 7:41 PM
I found the cause of the problem: the hardware delivers an inverted
signal. Taking this into account the library worked, as in more
detail pointed out in
http://arduino.cc/forum/index.php/topic,102039.0.html
Thank you for your help, and for the great library.
augustus 22, 2012 om 7:20 PM
Hey Thijs,
tried out your Libary today. It works perfect for me. The only thing I had to change was the pull-up resistor. I used 1.1kOhm insted of the proposed 10kOhm. Also I didn’t used the capacitor described in the first post.
Thank you for sharing.
augustus 31, 2012 om 12:18 PM
Great to hear! I’ll update the article mentioning the variety in pull pull up resistors
augustus 26, 2012 om 6:20 PM
Hi Thijs,
Firstly, thank you for making your excellent DCF77 library available for others to use.
I am trying to get the Symtrik MSF60 receiver to work, here in the UK, with an Arduino (that is already hooked up to a DS3232 RTC) and was looking around for some suitable code to decode the output. The MSF examples I’ve found will not compile due to dependency issues with IDE 1.0+. Your code is bang up to date, and I have been able to use the DCFSignal and DCFPulseLength sketches to look at the receiver output in raw form, though obviously the DCFBinaryStream code cannot decode the MSF protocol.
Do you have any pointers on how to modify the DCF77 library for use with MSF protocol?
I guess it should be reasonably straightforward but I have a feeling that it is going to require a lot of experimentation and a huge learning curve!
Best Regards,
Squire
augustus 30, 2012 om 8:14 AM
Hey squire, could you send me a sample of such a msf library? I could have a look at how easy it would be to make a msf library’based on the dcf library. No promises, though. Also, the debugging would have to be done by you, though, as I do t have such a receiver.
For starters, you could send me send me some screenshots of the output of dcfpulselength and dcfbinarystream?
september 7, 2012 om 10:18 PM
About length of pulses using DCFPulseLength: With my DCF1 module from Pollin I find, that short pulses are at an average of roundabout 106 ms (range 95..110) and long pules are roundabout at an average of 206 ms (range 195..210).
So pulses with my DCF module hardware seem to be much shorter than you found with your DCF hardware.
augustus 28, 2012 om 10:05 PM
Hi, Nice work
I’m looking at this MSF60 module http://www.earthshineelectronics.com/clock-modules/110-msf-60khz-time-receiver-module.html and wonder if I will need to make any changes to your code to get it working? …. any thoughts apreciated
augustus 30, 2012 om 8:17 AM
Yes, it wil definitely require significant changes: the pulse coding is different, I believe, and bit rearrange differently to a time structure.
augustus 31, 2012 om 10:50 PM
Hallo Thijs,
thanks for your library!
Unfortunately I could not make the library fully work with my DCF1 module from Pollin, most likely because of an inverted output signal and no reverse signal output available on that cheap module I have.
It seems as if your library cannot handle inverted output for decoding the time.
Only the example sketch “DCFPulseLength” works well with my module and this programming example helped me a lot to find a good place for the module: Placed directly in front of my monitor, the module only got random spikes, but no clear one second pulses. So at first I thought, that my own DCF programming is full of bugs, or the hardware is not wired correctly or maybe the module is faulty. But your example “DCFPulseLength” showed me, that I just had to place the module wide enough away from my PC and LCD monitor and then the signal becomes a strong one second pulse.
So that helped me a lot to program my own DCF decoding sketch.
The better the signal quality, the better the decoding.
I knew that DCF modules have no reception when operated near CRT (cathode ray tube) monitors and TVs, but I didn’t think about that the same happens when they are placed near LCD monitors. For my module, 1 metre is the minimum distance I have to keep the module away from LCD and PC, or the signal gets bad.
januari 3, 2013 om 1:21 PM
Hi,
I’m sorry to reply this late. The noise susceptibility of the DCF receiver is indeed very high. I’m glad to hear you got your problem solved! I’m trying to buy a bigger DCF77 antenna. I will write post if this makes a realy difference.
augustus 31, 2012 om 11:18 PM
I think that MSF60 decoding needs a slightly different decoder library as the decoding of MSF60 differs in some aspects from DCF77. Here is a link to a technical document I found:
http://www.npl.co.uk/upload/pdf/MSF_Time_Date_Code.pdf
Some things are identically, such as 60 seconds within one minute and an extra long pulse as the marker for the beginning of a new minute. And the BCD coding of the decimal values for hour, minute, day and so on is nearly the same.
But on the other side there are some strange two-bit codes at least in the first 16 seconds of each minute, so that MSF60 does not only has three different pulse lengths (short pulse, long pulse, minute marker pulse) but has one pulse length extra: short pulse, long pulse, extra long pulse, minute marker pulse
I think if you write some code that ignores the first 16 seconds which have the two-bit coding with three different pulse lengths, the coding is not so much different from DCF77. The actual time and date in MSF60 is coded with only two pulse lengths, just as DCF77. MSF60 is a bit different from DCF77, and so is the decoding.
I’m just wondering if I am in the receiving range of the MSF60 transmitter. I’m living near Hamburg, Germany.
augustus 31, 2012 om 11:50 PM
Thijs,
Thank you. I found a project by a fellow radio amateur, G7KSE, here:
http://g7kse.co.uk/projects/arduino-msf-receiver/
Which is based on this code:
http://www.jarkman.co.uk/catalog/robots/MSFTimeExample.zip
Symtrik MSF60 receiver details:
http://www.pvelectronics.co.uk/rftime/SYM-RFT-XX.pdf
MSF protocol from NPL:
http://www.pvelectronics.co.uk/rftime/msf/MSF_Time_Date_Code.pdf
I will post the serial monitor logs from my Ubuntu PC.
Thanks,
Squire
oktober 20, 2012 om 12:10 PM
Hi Thijs,
thanks a lot for your DCF77 library for arduino. It’s very easy to start with.
I wired a cheap DCF77 receiver from Pollin: http://www.pollin.de/shop/dt/NTQ5OTgxOTk-/
It works out of the box. No extra components were necessary.
Then I ran your examples bundled with the library. It turns out that SyncProvider is one minute ahead at the first sync. InternalClockSync works as expected.
Please find the output of InternalClockSync at http://pastebin.com/ZbtzWtqZ
The output of SyncProvider is here: http://pastebin.com/5DSfAkjZ
In line 4 of the output of SyncProvider it’s 12:01:00 actually. After the next sync the time is corrected (line 126).
I tried both examples a couple of times. The hardware wasn’t touched or even looked at…
The DCF77 signal is quite clear.
Any idea what’s going wrong?
Best regards
Franz
oktober 26, 2012 om 12:43 PM
Hi Franz,
Thanks for using the library! The issue you see is weird, how did you know it was a minute late? It is suspicious that the difference is precisely 1 minute. The only things I can think of now is the following: when a new time is received, a time stamp from the system clock is stored together with the dcf time. Storing both is not implemented as a atomic action, so it could be one is updated while the other is not, because the transfer was interrupted. Another option is that the internal clock is updated after the timestamp but before syncProvider is called. I will try to reproduce this when I have time. do you have some sample code that produces this issue?
oktober 26, 2012 om 11:00 PM
Hi Thijs,
I just ran your example Arduino\libraries\DCF77\examples\SyncProvider\SyncProvider.pde bundled with the library.
Another output is here: http://pastebin.com/SWJBXFSy
I calculated the time difference to a NTP synced server:
http://i50.tinypic.com/34ozg2g.png
Best regards
Franz
januari 3, 2013 om 1:32 PM
Hi Franz,
This is very strange. I have almost reached the stage in my clock project, where I start integrating the DCF77 receiver. At that time I will start getting a handle on this.
Happy New Year!
Thijs
oktober 29, 2012 om 8:12 PM
Hi again,
I enabled VERBOSE_DEBUG and recorded a video of the output:
http://dl.dropbox.com/u/87685034/SyncProvider_3_converted.avi
Maybe this helps to get a better insight…
Best regards
Franz
november 17, 2012 om 6:16 PM
Hi,
thanks for this nice DCF library. I have only one problem, tried this, but it didn’t work:
// Check DCF signal
void CP5_TBZ::checkDCF ()
{
time_t DCFtime = DCF.getTime();
if (DCFtime != 0)
{
m_bCurrDCF = true;
setTime(DCFtime);
}
else { m_bCurrDCF = false; }
}
The var “m_bCurrDCF” nerver gets true, also if my LCD displays the actual time. That isn’t logical and i think ” if (DCFtime != 0)” nerver gets true. You have any idea how i control if i have the new time, the actual one?
Best regards
Janni
november 19, 2012 om 5:44 PM
Hallo again,
i solved my problem.
best regards
november 28, 2012 om 10:21 PM
Hi Janny,
Glad to hear you got it solved!
november 30, 2012 om 11:29 PM
Hi,
Thanks for you clear postings on using the Conrad DCF receiver with an Arduino. I used as a basis for a timer that indicates to the kids that they have to sleep (red led), are allowed to wake up and play silently (yellow led) or can make noise and ask for breakfast (green led).
Two remarks:
- I found out that the combination Arduino/receiver has to be at least one meter (or about the length of a standard USB cable) away from a computer to function.
- I only managed to get the combination running using a USB cable, either from a computer or from a mobile phone charger. When I tried to use it with an AC adapter on the power supply connector, the Arduino was not able to synchronize to the DCF signal. Do you have experience in this area?
regards,
Gerrit
januari 3, 2013 om 12:09 PM
Hi Gerrit,
It nice to see the library being put to good use. I really like your idea! my daughter is now nearly 2 year old, so a little early yet for her, but I’ll try to remember it.
About the bad signal: Since the time code is transmitted in the longwave range by amplitude modulation, it can therefore be easily disturbed, resulting in erroneous peaks. A source or RF noise is indeed the PC, the level of noise may depend on the shielding by the case.
The samples I included in the package may help you to get a better grasp of the signal quality.
I have been explained that noise may also creep up through the mains, either by picking up signal in the power lines or through the power supply. The latter I tried to minimize by using a by-pass capacitor. You could try using a bigger one and see if you AC power source works better. To minimize picking up signal, you can twist the cables going the DCF receiver
Another thing you can try is buying a better antenna:
http://fpga-xilinx.blogspot.nl/2012/04/your-6-hourly-digest-for-electronics_9462.html
Meanwhile, I’m following Udo Kleins blog, he’s introducing a phase locked loop and exponential filtering (a simple moving average filter). This will make the library even more robust to noise:
http://blog.blinkenlight.net/2012/12/01/dcf77-project/
Beste wensen voor 2013!
december 9, 2012 om 6:39 PM
Hi Thijs,
I got the DCF77 module as well and got it all quite easy to run, but I experience a not so good reception. even in front of a window, whereas my casio watch receives well.
you got any tips to receive the signal better.
januari 3, 2013 om 12:15 PM
About the bad reception: I wrote this as a reply to essentially the same question by Gerrit, just below: the time code is transmitted in the longwave range by amplitude modulation, it can therefore be easily disturbed, resulting in erroneous peaks. A source or RF noise is indeed the PC, the level of noise may depend on the shielding by the case.
The samples I included in the package may help you to get a better grasp of the signal quality.
I have been explained that noise may also creep up through the mains, either by picking up signal in the power lines or through the power supply. The latter I tried to minimize by using a by-pass capacitor. You could try using a bigger one and see if you AC power source works better. To minimize picking up signal, you can twist the cables going the DCF receiver.
I wonder if your Casio is really doing that much better. I most cases it is enough to get a DCF update once a day, as long if you also have a real-time clock.
Another thing you can try is buying a better antenna:
http://fpga-xilinx.blogspot.nl/2012/04/your-6-hourly-digest-for-electronics_9462.html
Meanwhile, I’m following Udo Kleins blog, he’s introducing a phase locked loop and exponential filtering (a simple moving average filter). This will make the library even more robust to noise:
http://blog.blinkenlight.net/2012/12/01/dcf77-project/
Beste wensen voor 2013!
januari 3, 2013 om 2:14 PM
Hi Thijs,
Beste wensen too!! Thanks for this, this is very helpful!
Meanwhile I have been looking into your library and decided to make some changes for my own benefit, basically for the user interface experience as i connected a 2x16char screen to my Arduino. If you want I can post my changes, they are :
- added a boolean that is false when the pulse was rejected by the int0handler or true when the boolean was accepted, basically indicating the reception (more or less)
- indicating if a first buffer was finalized and return what the current buffer position is. this way i can display ‘Time in xx seconds’
januari 3, 2013 om 2:14 PM
Hi Thijs,
Beste wensen too!! Thanks for this, this is very helpful!
Meanwhile I have been looking into your library and decided to make some changes for my own benefit, basically for the user interface experience as i connected a 2x16char screen to my Arduino. If you want I can post my changes, they are :
- added a boolean that is false when the pulse was rejected by the int0handler or true when the boolean was accepted, basically indicating the reception (more or less)
- indicating if a first buffer was finalized and return what the current buffer position is. this way i can display ‘Time in xx seconds’
januari 21, 2013 om 1:14 AM
Yes, I’m very interested in your change suggestions. I you can send them, I will see if I can integrate them in the next version
december 21, 2012 om 11:54 PM
Hi Thijs,
Ik probeer de interne klok van mijn ‘Uno R3′ te synchen, maar geen resultaat. De ‘DCFSignal’ geeft een andere output dan ik op jouw screenshot zie.
Aangesloten zoals jouw schema.
Enig idee wat hier fout gaat?
Groet,
Casper
0000000000000
1100000000
1000000000000000
11111100000000
10
11111111100
10
1111111111000000000000
111100
1110000000
1100
100000000000
111000000000
1000
1110
111111111111111000
10000000000000000000
11111111111111111100000
111000000000000000000000
11111111111111000
december 22, 2012 om 12:16 AM
He, het lijkt erop dat de antenne flink ver van de PC af moet liggen. En mijn USB signaal is niet al te best heb ik het idee. Hij werkt nu wel. Dank voor al je voorbereidend werk!
Groet,
casper
januari 3, 2013 om 1:09 PM
Hi Casper,
Graag gedaan! De punten waar jij tegen aanloopt, RF interferentie, en ruis op de voeding, zijn bekende problemen. DCF77 is een lange golf signal met amplitude modulatie, en dat maakt hem gevoelig voor allerlei soorten ruis.
Thijs
januari 13, 2013 om 1:32 PM
Hoi Thijs ,
ik heb zojuist de ontvanger van Conrad aan mijn Arduino Mega 2560 gehangen, maar de klok wordt niet op tijd gezet. Nou had ik deze aan pin 53 gehangen (omdat de pinnen ernaast gebruikt worden voor een lcdtje, dacht alles mooi bij elkaar te zetten) en natuurlijk heb ik het pin-nummer aangepast in de sketch. Maar toen ik ‘m toch maar aan 2 hing, wat eerst in de sketch stond, gebeurde er nog steeds niets. Ik krijg nog altijd output met de tijd die nog in het jaar 1970 zit. Enig idee waarom?
januari 22, 2013 om 5:05 PM
Volgens mij is het probleem dat een ethernet Shield de pininterrupt gebruikt
januari 25, 2013 om 2:47 PM
Hi,
thanks for the library, after some troubleshooting I found out that I needed to use interrupt 1 instead of 0 (#define DCF_INTERRUPT 1) on pin 2 to get it working with my arduino leonardo! The other examples without interrupt really helped me alot, because I knew at least the dcf signal was fine!
greetz
skunkjoe
februari 20, 2013 om 12:56 PM
Great to hear!
Have fun playing with it
februari 18, 2013 om 10:37 AM
Hallo, ich habe eine Frage. Wenn ich Beispiele DCFsignal verwenden oder so DCFsyncprovider Arduino funktioniert, wenn ich mein Programm DCFsync Arbeit zu nutzen. Bitte haben Sie konsultiert. Danke
/* Verze: 18.2.2013 Martin Pihrt
SD ctecka pro LED panel…
Posilaji se ASCI znaky na seriovou linku.
Dale se posila prikaz na rolovani textu…
Pripojeni SD karty:
** CLK/SCK – pin D13
** MISO – pin D12
** MOSI – pin D11
** CS – pin D10
Pripojeni cidla DS18B20:
** pin #1 ds18b20 – gnd
** pin #2 ds18b20 – pin D9
** pin #3 ds18b20 – +5V
** rezistor 4K z +5V na pin D9
Pripojeni DCF prijimace:
** data DCF out – pin D2
*/
//knihovny
#include “DCF77.h”
#include “Time.h”
#include
#include
File myFile;
OneWire ds(9); // prirazeni cidla teploty k pinu D9
int led = 14; // prirazeni LED DCF k pinu 14 tj A0
int led2 = 15; // prirazeni LED SD k pinu 15 tj A1
// DCF
#define DCF_PIN 2 // prijimaci modul DCF 77 pripojen k pinu D2
#define DCF_INTERRUPT 0 // preruseni asociovane s pinem
time_t prevDisplay = 0;
time_t time;
DCF77 DCF = DCF77(DCF_PIN,DCF_INTERRUPT);
//prenosova rychlost serial portu
#define BAUD_RATE 115200
//pocet segmentu – zde zadat pocet panelu tj. delku textu znaku
#define SEGMENT 3
// pocet sloupcu tj zobrazovanych znaku
#define pSloupcu (SEGMENT * 4)
unsigned int znak = 0;
int ctiSd;
//teplota
byte i;
byte present = 0;
byte type_s;
byte data[12];
byte addr[8];
float celsius;
///////////////////// nastaveni ////////////////
void setup()
{
Serial.begin(BAUD_RATE);
delay(500); // pockame na desku LED po resetu
Serial.print(“C”); //vymaz bufer led panelu
delay(50);
DCF.Start();
//setTime(12,00,00,18,2,2013); //setTime(hr,min,sec,day,month,yr);
setSyncInterval(30); // Set the number of
// seconds between re-sync
setSyncProvider(getDCFTime); // Set the external time
// provider
pinMode(10, OUTPUT); // SD karta pin CS vystup
pinMode(led, OUTPUT); // kontrolni LED DCF synchronizace OK vystup
digitalWrite(led, LOW);
pinMode(led2, OUTPUT); // kontrolni LED cteni z SD OK vystup
digitalWrite(led2, LOW);
// vypis reklamy na panelu a info verze sw
// Serial.print(“\”INFO V”);
// Serial.write(0xdd); //cz znak y
// Serial.print(“PIS: \”");
// delay(1000);
// Serial.print(“11A”); //odsun vlevo
// delay(3000);
// Serial.print(“T”); //zobraz text info
// delay(30000);
// Serial.print(“21A”); //odsun vpravo
// delay(3000);
// kontrola SD karty
Serial.print(“\”KONTROLA SD:\”");
delay(1000);
Serial.print(“11A”); //odsun vlevo
delay(3000);
if (!SD.begin(10))
{
Serial.print(“\”CHYBA-KARTA!\”");
delay(2000);
Serial.print(“21A”); //odsun vpravo
delay(3000);
return;
} else {
digitalWrite(led2, HIGH);
Serial.print(“\”KARTA je OK \”");
}
delay(1000);
digitalWrite(led2, LOW);
Serial.print(“21A”); //odsun vpravo
delay(3000);
// SD overeni souboru led.txt
Serial.print(“\”KONTROLA \”");
delay(1500);
Serial.print(“\”DAT na SD…\”");
delay(1000);
Serial.print(“11A”); //odsun vlevo
delay(3000);
if (SD.exists(“LED.TXT”)) {
digitalWrite(led2, HIGH);
Serial.print(“\”SOUBOR je OK\”");
}
else {
Serial.print(“\”NA KAR”);
Serial.write(0x8d); //cz znak T
Serial.print(“E \”");
delay(1500);
Serial.print(“\”NEN”);
Serial.write(0xe5); //cz znak I
Serial.print(” SOUBOR:\”");
delay(1500);
Serial.print(“\”LED.txt! \”");
}
delay(1000);
digitalWrite(led2, LOW);
Serial.print(“21A”); //odsun vpravo
delay(3000);
//SD soubor otevreni
myFile = SD.open(“LED.TXT”);
if (myFile) {
Serial.print(“\”");
Serial.print(“START \”");
delay(1000);
digitalWrite(led2, HIGH);
Serial.print(“21A”); //odsun vpravo
delay(3000);
digitalWrite(led2, LOW);
Serial.print(“C”);
} else {
Serial.print(“\”CHYBA “);
Serial.write(0xc8); //cz znak C
Serial.print(“TEN”);
Serial.write(0xe5); //cz znak I
Serial.print(” \”");
delay(1500);
Serial.print(“\”ZE SOUBORU \”");
delay(3000);
Serial.print(“21A”); //odsun vpravo
delay(3000);
} //konec else
} //konec setup
void loop() /////////////// hlavni smycka //////////////////
{
tiskzSD();
tiskteploty();
if( now() != prevDisplay) //update the display only if the time has changed
{
prevDisplay = now();
digitalClockDisplay();
}
} /////////////// konec hlavni smycka //////////////////
//*********************************************************
unsigned long getDCFTime()
{
time_t DCFtime = DCF.getTime();
// Indicator that a time check is done
if (DCFtime!=0) {
digitalWrite(led, HIGH);
delay(100);
digitalWrite(led, LOW);
}
return DCFtime;
}
//*********************************************************
void tiskzSD()
{
myFile = SD.open(“led.txt”); // otevreme soubor na SD karte
if (myFile)
{
ctiData();
delay(10);
} // konec if
myFile.close(); // uzavereme soubor led.txt – konec prace s SD
}
//******************************************
void ctiData()
{
while (myFile.available())
{
digitalWrite(led2, HIGH);
for (int i=0; i < (pSloupcu + 2); i++) // pr: 12 znaku + 2 uvozovky = 14 znaku
{
ctiSd=(myFile.read());
if (ctiSd == '"')
{
znak = 0;
delay(10);
}
Serial.write(ctiSd); // zapiseme na vystup data z karty
if (znak == pSloupcu)
{
delay (2000); // cekáme na dalsi cteni radku z SD karty
znak = 0;
digitalWrite(led2, LOW);
}
znak++; // pocitadlo znaku
} // konec for
} // konec while
} // konec void
//*********************************************************
void digitalClockDisplay() //// vypis casu /////
{
Serial.print("\"P");
Serial.write(0xd8); //cz znak R 216
Serial.print("ESN");
Serial.write(0xdd); //cz znak Y 221
Serial.print(" ");
Serial.write(0xc8); //cz znak C 200
Serial.print("AS: \"");
delay(500);
Serial.print("21A"); //odsun vpravo
delay(3000);
Serial.print("\"");
Serial.print(hour());
printDigits(minute());
printDigits(second());
delay(3000);
Serial.print("\"");
Serial.print("C"); //smazat led panel
delay(50);
Serial.print("\"DATUM: \"");
delay(500);
Serial.print("21A"); //odsun vpravo
delay(3000);
Serial.print("C"); //smazat led panel
delay(50);
Serial.print("\"");
Serial.print(" ");
Serial.print(day());
Serial.print(".");
Serial.print(month());
Serial.print(".");
Serial.print(year());
Serial.print("\"");
delay(3000);
}
//*********************************************************
void printDigits(int digits) // pomocna funkce na zobrazeni nul pred casem
{
Serial.print(":");
if(digits < 10)
Serial.print('0');
Serial.print(digits);
}
//*********************************************************
void temp() //zpracovani teploty z cidla dallas
{
if ( !ds.search(addr)) {
ds.reset_search();
delay(250);
return;
}
if (OneWire::crc8(addr, 7) != addr[7]) {
return;
}
switch (addr[0]) {
case 0×10:
type_s = 1;
break;
case 0×28:
type_s = 0;
break;
case 0×22:
type_s = 0;
break;
default:
return;
}
ds.reset();
ds.select(addr);
ds.write(0×44,1); // start conversion, with parasite power on at the end
delay(1000); // maybe 750ms is enough, maybe not
// we might do a ds.depower() here, but the reset will take care of it.
present = ds.reset();
ds.select(addr);
ds.write(0xBE); // Read Scratchpad
for ( i = 0; i < 9; i++) { // we need 9 bytes
data[i] = ds.read();
}
// convert the data to actual temperature
unsigned int raw = (data[1] << 8) | data[0];
if (type_s) {
raw = raw << 3; // 9 bit resolution default
if (data[7] == 0×10) {
// count remain gives full 12 bit resolution
raw = (raw & 0xFFF0) + 12 – data[6];
}
} else {
byte cfg = (data[4] & 0×60);
if (cfg == 0×00) raw = raw << 3; // 9 bit resolution, 93.75 ms
else if (cfg == 0×20) raw = raw << 2; // 10 bit res, 187.5 ms
else if (cfg == 0×40) raw = raw << 1; // 11 bit res, 375 ms
// default is 12 bit resolution, 750 ms conversion time
}
celsius = (float)raw / 16.0;
}
//*********************************************************
void tiskteploty() //// vypis teploty /////
{
Serial.print("\"TEPLOTA: \"");
delay(500);
Serial.print("21A"); //odsun vpravo
delay(3000);
Serial.print("\"");
temp(); // zpracuj teplotu
Serial.print(celsius);
Serial.write(0xb0); //znak ° stupnu asci 0176
Serial.print("C");
Serial.print("\"");
delay(3000);
}
februari 20, 2013 om 12:55 PM
Hi,
I have trouble understanding your question, but I assume it is “The sample application is working, but the same code is not working in my own program. What could be the problem?”
I would investigate the following:
- Make use that none of your other libraries are using interrupt 0.
- It could be that the blinking of your led (or writing to the SD card) influences the source going to the DCF receiver. This can mess with the signal. Try turning off these and see if a time is received
Good luck,
Thijs
februari 20, 2013 om 1:27 PM
Hello, thank you for your answer. The problem really causes SD library. thank you
maart 12, 2013 om 1:49 PM
Hi,
great work thanks a lot.
Just a question is your library also exporting the weekday?
I didn’t find any information about it?
Cheers Robert
april 21, 2013 om 8:49 AM
Hi Robert,
No, the DCF77 library doesn’t, but the time library with which the DCF library interacts does, see: http://playground.arduino.cc/Code/time.
In order to have good separation of concerns, I want the DCF library just to receive and output the time, and do time-displaying, -conversion and -manipulation outside of it
april 22, 2013 om 11:50 AM
Beste Thijs,
Bedankt voor de artikel serie. Ben zeer onder de indruk. Heb een tijd geleden geprobeerd om dezelfde ontvanger aan de praat te krijgen.
Nu met de hulpprogramma’s kan ik wat zien.
Sinds kort ook een RIGO scoop.
Deze aan pin 13 gehangen nu zie ik en de resultaten van de arduino op het scherm en ook op de scoop.
Mijn vraag is; heb je enig idee hoelang de verbinding tussen de arduino en de ontvanger mag zijn?
Met vriendelijke groet,
Jan Kromhout
Hellevoetsluis
mei 23, 2013 om 8:55 AM
Hoi Jan,
Bedankt voor het compliment! Ik heb niet gekeken naar de afstand tussen de Arduino en ontvanger. De beste manier om er achter te komen, is door het te proberen. Als het niet lukt zou ik een Arduino redelijk dicht bij de ontvanger zetten en deze laten communiceren met een Arduino verder weg. Dat kan via ethernet, wifi, bluetooth, zigbee of serieel.
Succes! Thijs