#define BIT_TIME 150 // this value should be between 100 and 200, it decides between 0 and 1 #define MINUTE_UP 1400 // the minute is up #define DCF_INPUT 10 // DCF77 input pin int8_t VALUES[] = {1, 2, 4, 8, 10, 20, 40, 80}; const char *WEEKDAYS[] = {"--", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"}; const char *CEST[] = {"CET", "CEST"}; unsigned long milli = 0; // global variables uint8_t cest = 0; uint8_t minute = 0; uint8_t hour = 0; uint8_t day = 0; uint8_t weekday = 0; uint8_t month = 0; uint8_t year = 0; uint8_t position = 0; uint8_t parity = 0; // even parity in the time signal uint8_t dcfPIN = 0; // status of the DCF77 input pin void setup() { Serial.begin(115200); // init serial interface while (!Serial) delay(1); pinMode(LED_BUILTIN, OUTPUT); pinMode(DCF_INPUT, INPUT); Serial.println("Start...DCF77"); // 'Hello world' } void loop() { int _dcfPIN = digitalRead(DCF_INPUT); // read the DCF77 input if (dcfPIN != _dcfPIN) { // the input has changed dcfPIN = _dcfPIN; // remember the value digitalWrite(LED_BUILTIN, dcfPIN); // update the onboard LED unsigned long _milli = millis(); // increasing millisecond counter unsigned long len = _milli - milli; // calculates the pulse length milli = _milli; // remember the value if (dcfPIN == 0) // this means that the signal was high and is now low { // Serial.println(len); // optional to see the bit length if (len > BIT_TIME) // zero or one ? { // one ! parity += 1; if (position >= 21 && position <= 27) // minute minute += VALUES[position - 21]; else if (position >= 29 && position <= 34) // hour hour += VALUES[position - 29]; else if (position >= 36 && position <= 41) // day day += VALUES[position - 36]; else if (position >= 42 && position <= 44) // weekday weekday += VALUES[position - 42]; else if (position >= 45 && position <= 49) // month month += VALUES[position - 45]; else if (position >= 50 && position <= 57) // year year += VALUES[position - 50]; // only the year, not the century if (position == 17) cest = 1; // Central European Summer Time else if (position == 18) { if (cest == 1) // Central European Time position = 0; // Error: sets the position to 0, making the time information invalid } else if (position == 20) // start of encoded time, always 1 parity = 0; // reset parity for the following bits else if (position == 28 || position == 35 || position == 58) { if ((parity % 2) != 0) // even parity ? position = 0; // Error: sets the position to 0, making the time information invalid parity = 0; // reset parity for the following bits } } else // zero { if (position == 28 || position == 35 || position == 58) { if ((parity % 2) != 0) // even parity ? position = 0; // Error: sets the position to 0, making the time information invalid parity = 0; // reset parity for the following bits } } Serial.print("Bit: "); Serial.println(position); // optional // char buf[100]; // sprintf(buf, "Timestamp: %d-%02d-%02d %02d:%02d %s %s", (year + 2000), month, day, hour, minute, // WEEKDAYS[weekday], CEST[cest]); // Serial.println(buf); // enable the lines above to see how the date and time evolve position += 1; // increment the bit counter } else { if (len > MINUTE_UP) { // the minute is up, the parity bit does not allow error correction, // so some additional checks are performed if (position == 59 && (minute >= 0 && minute <= 59 || hour >= 0 && hour <= 23 || day >= 1 && day <= 31 || weekday >= 1 && weekday <= 7 || month >= 1 && month <= 12 || year >= 25)) { char buf[100]; sprintf(buf, "Timestamp: %d-%02d-%02d %02d:%02d %s %s", (year + 2000), month, day, hour, minute, WEEKDAYS[weekday], CEST[cest]); Serial.println(buf); } else Serial.println("No valid timestamp"); cest = 0; // reset everything, preparing for the next minute minute = 0; hour = 0; day = 0; weekday = 0; month = 0; year = 0; position = 0; parity = 0; } } } delay(1); }