# CRON-like component for the ESP-IDF framework > 中文版请见 [README_zh.md](./README_zh.md) ## Component Features This component provides CRON-style task scheduling for the ESP-IDF framework, leveraging `esp_timer.h` for high-precision timing. It's optimized for embedded scenarios, supporting CRON syntax with second-level precision and seamless integration with ESP32/ESP8266 hardware. ## Usage Guide The API design prioritizes simplicity, including core functions for task creation, destruction, and scheduler control. The workflow is straightforward: define at least one task, start the scheduler, then manage tasks dynamically. A smart power-saving mechanism automatically puts the scheduler into low-power mode when no tasks are scheduled, minimizing CPU overhead. **Key Note**: Timing relies on `esp_timer` for hardware-accelerated precision, eliminating the need for system time management. Ensure proper timer initialization before creating tasks to maintain scheduling accuracy. ### Code Structure ```tree esp-cron/ ├── esp_cron.c # Core scheduling logic & API implementation ├── include/ │ ├── esp_cron.h # Public header exposing APIs │ └── cron_internal.h # Internal header for scheduler internals ├── library/ │ ├── ccronexpr/ # CRON expression parser (open-source component) │ └── jobs/ # Task linked list management └── examples/ # Usage examples ``` ## Quick Start Guide ### Include Header ```c #include "esp_cron.h" ``` ### 1. Create a Scheduled Task ```c cron_job *cron_job_create(const char *schedule, cron_job_callback callback, void *data) ``` - `schedule` supports CRON expressions with second-level precision: ```txt ┌────────────── second (0 - 59) | ┌───────────── minute (0 - 59) | │ ┌───────────── hour (0 - 23) | │ │ ┌───────────── day of month (1 - 31) | │ │ │ ┌───────────── month (1 - 12) | │ │ │ │ ┌───────────── day of week (0 - 6, Sunday=0; 7=Sunday in some systems) | │ │ │ │ │ * * * * * * ``` - `callback` is a task handler function pointer, defined as: ```c typedef void (*cron_job_callback)(cron_job *); ``` Callbacks are designed to be lightweight; the scheduler manages execution cycles automatically. - `data` is a user-defined pointer passed to the callback with the task handle. ### Destroy a Task Stop an existing task with: ```c int cron_job_destroy(cron_job *job); ``` ### Start the Scheduler Launch the scheduler after defining at least one task: ```c int cron_start(); ``` ### Stop the Scheduler Shut down the scheduler: ```c int cron_stop(); ``` ### Clear All Tasks Remove all scheduled tasks: ```c int cron_job_clear_all(); ``` ### Example Usage ```c /* Initialize ESP-Timer (project-dependent, not component-required) */ esp_timer_init(); /* Create two scheduled tasks */ cron_job *jobs[2]; jobs[0] = cron_job_create("* * * * * *", on_timer_trigger, (void *)0); jobs[1] = cron_job_create("*/5 * * * * *", on_timer_trigger, (void *)10000); /* Start scheduler */ cron_start(); /* Simulate main program execution (replace with business logic) */ vTaskDelay(pdMS_TO_TICKS(60000)); // Run for 60 seconds /* Cleanup resources */ cron_stop(); cron_job_clear_all(); ``` Callback function example: ```c void on_timer_trigger(cron_job *job) { uint32_t task_id = (uint32_t)job->data; printf("Task %u triggered at %lu ms\n", task_id, esp_timer_get_time() / 1000); } ``` ## Core API Reference ### Task Management | Function | Description | |---------------------------|--------------------------------------| | `cron_job* cron_job_create(const char* schedule, cron_job_callback callback, void* data);` | Create and register a task | | `int cron_job_destroy(cron_job* job);` | Destroy a specific task | | `int cron_job_clear_all();` | Clear all scheduled tasks | ### Scheduler Control | Function | Description | |-------------------|------------------------------------| | `int cron_start();` | Start the task scheduler | | `int cron_stop();` | Stop the task scheduler | ### Task Scheduling Operations | Function | Description | |-------------------------|--------------------------------------| | `int cron_job_schedule(cron_job* job);` | Manually schedule a task | | `int cron_job_unschedule(cron_job* job);` | Unscheduled a task | | `void cron_schedule_task(void* args);` | Special scheduling (e.g., run once) | ### Status Queries | Function | Description | |-----------------------------------|--------------------------------------| | `int cron_job_load_expression(cron_job* job, const char* schedule);` | Dynamically load a CRON expression | | `int cron_job_has_loaded(cron_job* job);` | Check if an expression is loaded | | `time_t cron_job_seconds_until_next_execution();` | Get seconds until next execution | ## Time Synchronization & Precision Optimization ### Local Timezone Configuration For projects requiring timezone-aware time display: 1. **Timezone environment configuration**: ```c setenv("TZ", "CST-8", 1); // Beijing Time (UTC+8) tzset(); // Apply timezone settings ``` This affects functions like `localtime` but **does not impact scheduling precision**—tasks run based on hardware timer absolute time, independent of system timezone. 2. **SNTP time synchronization (optional)**: For standard time in logs or displays: ```c void init_system_time(void) { sntp_setoperatingmode(SNTP_OPMODE_POLL); sntp_setservername(0, "pool.ntp.org"); // Use domestic servers like "cn.ntp.org" sntp_init(); int retry = 0; const int max_retry = 10; while (sntp_get_sync_status() != SNTP_SYNC_STATUS_COMPLETED && retry < max_retry) { vTaskDelay(pdMS_TO_TICKS(1000)); retry++; } time_t now = 0; time(&now); printf("System time synced: %s", ctime(&now)); } ``` **Note**: SNTP syncs only the system time for display; scheduling relies on `esp_timer` hardware timing, unaffected by network latency. ### Precision Optimization Guide 1. **Hardware timer configuration**: ```c /* Enable high-precision timer mode (ESP32-specific) */ esp_timer_create_args_t timer_args = { .callback = NULL, .arg = NULL, .flags = ESP_TIMER_FLAG_HIGH_PRECISION, // Key: enable APB clock source }; esp_timer_init(&timer_args); ``` 2. **Scheduler parameter tuning**: ```c /* Configure minimum scheduling interval (default: 1ms, adjust for power consumption) */ #define MIN_SCHEDULE_INTERVAL_US 100000 // 100ms interval for light sleep cron_start(); // Apply configuration on startup ``` 3. **Low-power scenario adaptation**: ```c /* Combine with timer wakeup for low-power scheduling */ esp_sleep_enable_timer_wakeup(5000000); // Wake up every 5 seconds esp_light_sleep_start(); ``` The scheduler checks task triggers during wakeup cycles, balancing precision and power consumption. ### Why No Timezone Dependence for Scheduling? This component uses **direct hardware timer timing** with these advantages: 1. **Precision isolation**: Triggers rely on ESP32 internal timers, unaffected by system time or timezone, with microsecond-level accuracy. 2. **No network dependency**: Stable scheduling without SNTP, ideal for offline embedded scenarios. 3. **Power optimization**: Timers work independently during CPU sleep, avoiding constant wakeups in traditional time systems. **Actual role of timezone configuration**: Only affects time display formats via functions like `localtime`, fully decoupled from scheduling logic. ## Acknowledgments - [esp_cron](https://github.com/DavidMora/esp_cron) by David Mora Rodriguez - [ccronexpr](https://github.com/staticlibs/ccronexpr) expression parser ## License This project is licensed under the [Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0). > English documentation: This page is in English. 中文文档请见 [README_zh.md](./README_zh.md)
idf.py add-dependency "bubao/esp_cron^0.0.5"