#pragma once #include // Generic class to handle intervals template class OnEveryN { public: OnEveryN() : lastTime(0) {} // Check if the interval has elapsed bool ready() { unsigned long currentTime = millis(); if (currentTime - lastTime >= interval) { lastTime = currentTime; return true; } return false; } private: unsigned long lastTime; // Stores the last execution time }; // Helper macros to generate unique names #define CONCATENATE_DETAIL(x, y) x##y #define CONCATENATE(x, y) CONCATENATE_DETAIL(x, y) #define UNIQUE_NAME(base) CONCATENATE(base, __LINE__) // Macro for ON_EVERY_N_MILLISECONDS (constant N via template) #define ON_EVERY_N_MILLISECONDS(N) \ static OnEveryN UNIQUE_NAME(__on_everyN_); \ if (UNIQUE_NAME(__on_everyN_).ready()) // Runtime-configurable variant (interval can be a variable/expression) class OnEveryMsVariable { public: OnEveryMsVariable() : lastTime(0) {} bool ready(unsigned long interval) { if (interval == 0) return false; // ignore 0 to avoid busy looping unsigned long now = millis(); if (now - lastTime >= interval) { lastTime = now; return true; } return false; } private: unsigned long lastTime; }; // Macro for variable interval in milliseconds #define ON_EVERY_MILLISECONDS(VAR_INTERVAL) \ static OnEveryVariable UNIQUE_NAME(__on_everyVar_); \ if (UNIQUE_NAME(__on_everyVar_).ready(VAR_INTERVAL)) // Macro for ON_EVERY_N_SECONDS #define ON_EVERY_N_SECONDS(N) ON_EVERY_N_MILLISECONDS((N) * 1000)