### Start DCF77FreeRTOS Receiver Task Source: https://context7.com/szilvasyz/dcf77freertos/llms.txt Call begin() inside setup() to allocate FreeRTOS resources, configure the input pin, optionally set up a status LED, install the ISR, and create the decoder task. Use LED_BUILTIN or DCF_LED_NONE. ```cpp #include DCF77FreeRTOS dcf(26, DCF_NODEBUG); void setup() { Serial.begin(115200); // Start with built-in LED blinking on every DCF pulse dcf.begin(LED_BUILTIN); // LED_BUILTIN = 2 on most ESP32 boards // Or start without LED visualisation // dcf.begin(DCF_LED_NONE); } ``` -------------------------------- ### begin(int ledPin) - Start the receiver task Source: https://context7.com/szilvasyz/dcf77freertos/llms.txt Initializes the DCF77 receiver by allocating FreeRTOS resources, configuring the input pin, optionally setting up a status LED, and creating the decoder task. This method must be called once within the `setup()` function. ```APIDOC ## `begin(int ledPin)` — Start the receiver task Allocates a FreeRTOS queue (64 pulse slots) and an event group, configures the input pin, optionally sets up a status LED, installs the GPIO ISR, and creates the decoder task pinned to core 1 with priority 3. Must be called once inside `setup()`. ```cpp #include DCF77FreeRTOS dcf(26, DCF_NODEBUG); void setup() { Serial.begin(115200); // Start with built-in LED blinking on every DCF pulse dcf.begin(LED_BUILTIN); // LED_BUILTIN = 2 on most ESP32 boards // Or start without LED visualisation // dcf.begin(DCF_LED_NONE); } ``` ``` -------------------------------- ### Initialize and Read DCF77 Time Source: https://github.com/szilvasyz/dcf77freertos/blob/main/README.md Include the library, initialize the DCF77FreeRTOS object with the input pin, and optionally set an LED pin. The loop continuously checks for time updates and prints them to the serial monitor. ```cpp #include DCF77FreeRTOS dcf(4); // DCF input pin = 4 void setup() { Serial.begin(115200); dcf.begin(2); // optional LED pin = 2 } void loop() { DCFtime t; if (dcf.getTime(&t)) { Serial.printf("DCF time: %02d-%02d-%02d %02d:%02d (dow=%d) ", t.year, t.month, t.day, t.hour, t.minute, t.dow); } delay(1000); } ``` -------------------------------- ### Initialize DCF77FreeRTOS Receiver Source: https://context7.com/szilvasyz/dcf77freertos/llms.txt Construct a DCF77FreeRTOS object with the input pin and debug setting. No FreeRTOS resources are allocated until begin() is called. ```cpp #include // Pin 26, debug output disabled DCF77FreeRTOS dcf(26, DCF_NODEBUG); // Pin 4, debug output enabled (prints each pulse and raw frame to Serial) DCF77FreeRTOS dcf_debug(4, DCF_DEBUG); ``` -------------------------------- ### Configuration — `DCF77FreeRTOSConfig.h` Source: https://context7.com/szilvasyz/dcf77freertos/llms.txt Compile-time constants that allow tuning of the DCF77FreeRTOS library's behavior, including noise filtering, signal detection thresholds, and FreeRTOS task parameters. ```APIDOC ## Configuration — `DCF77FreeRTOSConfig.h` Compile-time tuning constants that control noise filtering, signal detection thresholds, task stack size, and task priority. Modify these in `DCF77FreeRTOSConfig.h` before building. ```cpp // DCF77FreeRTOSConfig.h — all values shown with their defaults // Minimum pulse width in ms to be considered valid (filters electrical noise) #define DCF_NOISE 35 // Number of consecutive valid bits required before status upgrades to "signal present" #define DCF_SGN_THRESHOLD 20 // Milliseconds of silence before status downgrades one level (2 minutes) #define DCF_SGN_TIMEOUT 120000 // FreeRTOS decoder task stack in bytes #define DCF_TASK_STACK 4096 // FreeRTOS decoder task priority (1–24; higher = more CPU time) #define DCF_TASK_PRIO 3 ``` ``` -------------------------------- ### Constructor - DCF77FreeRTOS(int pin, int dbg) Source: https://context7.com/szilvasyz/dcf77freertos/llms.txt Creates a DCF77FreeRTOS receiver instance associated with a specific GPIO input pin. The `dbg` parameter controls verbose serial output for debugging. ```APIDOC ## Constructor — `DCF77FreeRTOS(int pin, int dbg)` Creates the receiver instance and associates it with the specified GPIO input pin. The `dbg` parameter enables verbose Serial output of every classified pulse and decoded frame, which is useful during hardware bring-up. No FreeRTOS resources are allocated until `begin()` is called. ```cpp #include // Pin 26, debug output disabled DCF77FreeRTOS dcf(26, DCF_NODEBUG); // Pin 4, debug output enabled (prints each pulse and raw frame to Serial) DCF77FreeRTOS dcf_debug(4, DCF_DEBUG); ``` ``` -------------------------------- ### DCF77FreeRTOS Configuration Constants Source: https://context7.com/szilvasyz/dcf77freertos/llms.txt These compile-time constants in `DCF77FreeRTOSConfig.h` control noise filtering, signal detection thresholds, and FreeRTOS task parameters. Modify them before building to tune the library's behavior. ```cpp // DCF77FreeRTOSConfig.h — all values shown with their defaults // Minimum pulse width in ms to be considered valid (filters electrical noise) #define DCF_NOISE 35 // Number of consecutive valid bits required before status upgrades to "signal present" #define DCF_SGN_THRESHOLD 20 // Milliseconds of silence before status downgrades one level (2 minutes) #define DCF_SGN_TIMEOUT 120000 // FreeRTOS decoder task stack in bytes #define DCF_TASK_STACK 4096 // FreeRTOS decoder task priority (1–24; higher = more CPU time) #define DCF_TASK_PRIO 3 ``` -------------------------------- ### FreeRTOS Event Group for Callbacks Source: https://context7.com/szilvasyz/dcf77freertos/llms.txt Use this snippet to create a FreeRTOS task that efficiently reacts to DCF77 decoder events like sync or error without polling. It requires the DCF77FreeRTOS library and FreeRTOS API. ```cpp #include DCF77FreeRTOS dcf(26, DCF_NODEBUG); // A second FreeRTOS task that reacts immediately on sync or error void dcfWatcherTask(void* arg) { DCF77FreeRTOS* d = static_cast(arg); EventGroupHandle_t ev = d->events(); const EventBits_t WATCH = DCF_EVENT_SYNCED | DCF_EVENT_ERROR; while (true) { // Block indefinitely until SYNCED or ERROR fires EventBits_t bits = xEventGroupWaitBits(ev, WATCH, pdTRUE, // clear on exit pdFALSE, // any bit triggers portMAX_DELAY); if (bits & DCF_EVENT_SYNCED) { DCFtime t; d->getTime(&t); Serial.printf("[SYNC] %02d:%02d status=%d\n", t.hour, t.minute, d->getStatus()); } if (bits & DCF_EVENT_ERROR) { Serial.println("[ERROR] Frame rejected — parity or range check failed"); } } } void setup() { Serial.begin(115200); dcf.begin(LED_BUILTIN); xTaskCreatePinnedToCore(dcfWatcherTask, "dcfWatcher", 2048, &dcf, 2, nullptr, 0); } void loop() { vTaskDelay(pdMS_TO_TICKS(10000)); } ``` -------------------------------- ### Apply DCFtime to System Clock Source: https://context7.com/szilvasyz/dcf77freertos/llms.txt This function applies decoded time data from a `DCFtime` struct to the ESP32's system clock using the `time.h` library. Ensure `time.h` is included. ```cpp #include void applyDCFtoSystemClock(const DCFtime& t) { struct tm tminfo = {}; tminfo.tm_year = (2000 + t.year) - 1900; tminfo.tm_mon = t.month - 1; tminfo.tm_mday = t.day; tminfo.tm_hour = t.hour; tminfo.tm_min = t.minute; tminfo.tm_sec = 0; tminfo.tm_isdst = t.dst; time_t epoch = mktime(&tminfo); struct timeval tv = { .tv_sec = epoch, .tv_usec = 0 }; settimeofday(&tv, nullptr); } ``` -------------------------------- ### events() — FreeRTOS event group for zero-latency callbacks Source: https://context7.com/szilvasyz/dcf77freertos/llms.txt Returns the EventGroupHandle_t managed internally by the library. This allows FreeRTOS tasks to efficiently block until specific decoder events occur, such as a new minute, synchronization, or an error. ```APIDOC ## events() Returns the `EventGroupHandle_t` managed internally by the library. Three event bits are defined, allowing any FreeRTOS task to block efficiently until a specific decoder event occurs instead of polling. ### Event Bits | Bit constant | Trigger | |---|---| | `DCF_EVENT_NEW_MINUTE` | A new valid minute frame was decoded | | `DCF_EVENT_SYNCED` | Same as above (set together with `NEW_MINUTE`) | | `DCF_EVENT_ERROR` | Frame rejected (bad start bit, parity failure, or range error) | ### Example Usage ```cpp #include DCF77FreeRTOS dcf(26, DCF77_NODEBUG); // A second FreeRTOS task that reacts immediately on sync or error void dcfWatcherTask(void* arg) { DCF77FreeRTOS* d = static_cast(arg); EventGroupHandle_t ev = d->events(); const EventBits_t WATCH = DCF_EVENT_SYNCED | DCF_EVENT_ERROR; while (true) { // Block indefinitely until SYNCED or ERROR fires EventBits_t bits = xEventGroupWaitBits(ev, WATCH, pdTRUE, // clear on exit pdFALSE, // any bit triggers portMAX_DELAY); if (bits & DCF_EVENT_SYNCED) { DCFtime t; d->getTime(&t); Serial.printf("[SYNC] %02d:%02d status=%d\n", t.hour, t.minute, d->getStatus()); } if (bits & DCF_EVENT_ERROR) { Serial.println("[ERROR] Frame rejected — parity or range check failed"); } } } void setup() { Serial.begin(115200); dcf.begin(LED_BUILTIN); xTaskCreatePinnedToCore(dcfWatcherTask, "dcfWatcher", 2048, &dcf, 2, nullptr, 0); } void loop() { vTaskDelay(pdMS_TO_TICKS(10000)); } ``` ``` -------------------------------- ### Poll for Decoded Time Frame Source: https://context7.com/szilvasyz/dcf77freertos/llms.txt Use getTime() to copy the latest DCFtime into the provided pointer. It returns true if a new frame has arrived since the last call. Safe to call from any task. ```cpp #include DCF77FreeRTOS dcf(26, DCF_NODEBUG); void setup() { Serial.begin(115200); dcf.begin(LED_BUILTIN); } void loop() { DCFtime t; if (dcf.getTime(&t)) { // Prints once per minute when a valid frame is decoded // year is 2-digit (e.g. 25 for 2025); dst=1 means CEST, dst=0 means CET // dow: 1=Monday … 7=Sunday Serial.printf("Time: 20%02d-%02d-%02d %02d:%02d dow=%d DST=%d ts=%lu\n", t.year, t.month, t.day, t.hour, t.minute, t.dow, t.dst, t.tstamp); } delay(1000); } /* Expected Serial output (once per minute): Time: 2025-06-15 14:37 dow=7 DST=1 ts=3720541 */ ``` -------------------------------- ### getStatus() - Query receiver health Source: https://context7.com/szilvasyz/dcf77freertos/llms.txt Returns the current health status of the DCF77 receiver as an integer code. The status automatically downgrades over time if no valid signal events are detected, providing hysteresis-free health reporting. ```APIDOC ## `getStatus()` — Query receiver health Returns an integer status code reflecting the current signal quality. Each level automatically downgrades to the next lower level after `DCF_SGN_TIMEOUT` (120 seconds) without a qualifying event, providing hysteresis-free health reporting. | Return value | Constant meaning | Description | |---|---|---| | `0` | Disconnected | No edges detected on the input pin | | `1` | No signal | Edges detected but no valid pulse pattern | | `2` | Signal present | Valid pulses received (≥ `DCF_SGN_THRESHOLD` consecutive bits) | | `3` | Synced | At least one complete valid 59-bit frame decoded | ```cpp #include DCF77FreeRTOS dcf(26, DCF_NODEBUG); const char* statusLabel[] = { "Disconnected", "No signal", "Signal present", "Synced" }; void setup() { Serial.begin(115200); dcf.begin(LED_BUILTIN); } void loop() { int s = dcf.getStatus(); Serial.printf("DCF status: %d (%s)\n", s, statusLabel[s]); DCFtime t; if (s == 3 && dcf.getTime(&t)) { Serial.printf("Synced time: %02d:%02d\n", t.hour, t.minute); } delay(5000); } ``` ``` -------------------------------- ### Query DCF Receiver Health Status Source: https://context7.com/szilvasyz/dcf77freertos/llms.txt Call getStatus() to retrieve the current signal quality as an integer. Levels automatically downgrade after a timeout without events, providing hysteresis-free reporting. ```cpp #include DCF77FreeRTOS dcf(26, DCF_NODEBUG); const char* statusLabel[] = { "Disconnected", "No signal", "Signal present", "Synced" }; void setup() { Serial.begin(115200); dcf.begin(LED_BUILTIN); } void loop() { int s = dcf.getStatus(); Serial.printf("DCF status: %d (%s)\n", s, statusLabel[s]); DCFtime t; if (s == 3 && dcf.getTime(&t)) { Serial.printf("Synced time: %02d:%02d\n", t.hour, t.minute); } delay(5000); } ``` -------------------------------- ### `DCFtime` struct — Decoded time data Source: https://context7.com/szilvasyz/dcf77freertos/llms.txt Represents the decoded time data extracted from the DCF77 frame. It includes fields for hour, minute, year, month, day, day of the week, daylight saving time status, a timestamp of when the data was synced, and a flag for new, unread data. ```APIDOC ## `DCFtime` struct — Decoded time data All fields are decoded from the raw 59-bit DCF77 frame using BCD extraction and even-parity validation before being written to this struct. ```cpp struct DCFtime { int hour = 0; // 0–23 int minute = 0; // 0–59 int year = 0; // 2-digit (e.g., 25 → 2025) int month = 0; // 1–12 int day = 0; // 1–31 int dow = 0; // day-of-week: 1=Monday … 7=Sunday int dst = 0; // 1 = CEST (summer time), 0 = CET (winter time) unsigned long tstamp = 0; // millis() value at the moment of sync uint8_t newtime = 0; // 1 if unread new data available; cleared by getTime() }; // Usage: apply DCFtime to the ESP32 system clock via time.h #include void applyDCFtoSystemClock(const DCFtime& t) { struct tm tminfo = {}; tminfo.tm_year = (2000 + t.year) - 1900; tminfo.tm_mon = t.month - 1; tminfo.tm_mday = t.day; tminfo.tm_hour = t.hour; tminfo.tm_min = t.minute; tminfo.tm_sec = 0; tminfo.tm_isdst = t.dst; time_t epoch = mktime(&tminfo); struct timeval tv = { .tv_sec = epoch, .tv_usec = 0 }; settimeofday(&tv, nullptr); } ``` ``` -------------------------------- ### DCFtime Struct Definition Source: https://context7.com/szilvasyz/dcf77freertos/llms.txt This struct holds decoded time data from the DCF77 frame. All fields are validated before being populated. The `newtime` flag indicates unread data. ```cpp struct DCFtime { int hour = 0; // 0–23 int minute = 0; // 0–59 int year = 0; // 2-digit (e.g., 25 → 2025) int month = 0; // 1–12 int day = 0; // 1–31 int dow = 0; // day-of-week: 1=Monday … 7=Sunday int dst = 0; // 1 = CEST (summer time), 0 = CET (winter time) unsigned long tstamp = 0; // millis() value at the moment of sync uint8_t newtime = 0; // 1 if unread new data available; cleared by getTime() }; ``` -------------------------------- ### getTime(DCFtime* out) - Poll for a new decoded time frame Source: https://context7.com/szilvasyz/dcf77freertos/llms.txt Retrieves the most recently decoded DCFtime structure. It returns true if a new time frame has been successfully decoded since the last call. This method is thread-safe and can be called from any task. ```APIDOC ## `getTime(DCFtime* out)` — Poll for a new decoded time frame Copies the most recently decoded `DCFtime` into `*out` under a FreeRTOS critical section and returns `true` only if a new frame has arrived since the last successful call. The `newtime` flag inside `DCFtime` is cleared atomically on read. Safe to call from `loop()` or any user task. ```cpp #include DCF77FreeRTOS dcf(26, DCF_NODEBUG); void setup() { Serial.begin(115200); dcf.begin(LED_BUILTIN); } void loop() { DCFtime t; if (dcf.getTime(&t)) { // Prints once per minute when a valid frame is decoded // year is 2-digit (e.g. 25 for 2025); dst=1 means CEST, dst=0 means CET // dow: 1=Monday … 7=Sunday Serial.printf("Time: 20%02d-%02d-%02d %02d:%02d dow=%d DST=%d ts=%lu\n", t.year, t.month, t.day, t.hour, t.minute, t.dow, t.dst, t.tstamp); } delay(1000); } /* Expected Serial output (once per minute): Time: 2025-06-15 14:37 dow=7 DST=1 ts=3720541 */ ``` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.