Robot Timer, v1.0.0
Posted on

The library for implementing timers.
Major version. Implementing infinite timers. Support for handling overflowing the clock function.
Features
- possibilities:
- implementing infinite timers;
- handling overflowing the clock function:
- in case of overflow we use the average of the values obtained earlier;
- types:
- the
ClockFunctype represents the clock function; it should return the current timestamp in seconds; the result is of thedoubletype, so that the current timestamp can be fractional:- the
clockForStdLibrary()function implements theClockFunctype for the standard C++ library; - the
clockForArduino()function implements theClockFunctype for the Arduino environment;
- the
- the
InfiniteTimerstructure represents an infinite timer; the timer starts ticking from the moment it's created and continues to do so indefinitely; at the same time, the timer handles overflowing the clock function.
- the
Examples
Blink on the cicada principle:
#include <InfiniteTimer.h>
#include <ClockFunc.h>
#include <stdint.h>
using namespace irenica_ideas::robot_timer;
constexpr auto LED_COUNT = 3;
constexpr auto LED_LOG_LENGTH = 7;
constexpr auto TOTAL_LED_LOG_LENGTH = LED_LOG_LENGTH * LED_COUNT
+ (LED_COUNT - 1) /* for commas */;
constexpr auto LED_VOLTAGE_LEVEL_LOG_FACTOR = 5;
uint8_t ledPins[LED_COUNT] = {11, 12, 13};
uint8_t ledVoltageLevels[LED_COUNT] = {LOW, LOW, LOW};
// use prime numbers for timer periods according to the cicada principle (see below)
// https://www.sitepoint.com/the-cicada-principle-and-why-it-matters-to-web-designers/
InfiniteTimer ledTimers[LED_COUNT] = {
InfiniteTimer(0.29, clockForArduino),
InfiniteTimer(0.37, clockForArduino),
InfiniteTimer(0.53, clockForArduino)
};
void setup() {
Serial.begin(9600);
for (const auto& ledPin: ledPins) {
pinMode(ledPin, OUTPUT);
}
}
void loop() {
// update all the timers; only once per loop iteration
for (auto& ledTimer: ledTimers) {
ledTimer.update();
}
char ledLogBuffer[TOTAL_LED_LOG_LENGTH + 1 /* for null terminator */ ] = {0};
auto ledLogBufferOffset = 0;
for (auto ledIndex = 0; ledIndex < LED_COUNT; ledIndex++) {
// add a LED description for the Serial Plotter tool
// in comma-separated "LED_<index>:<voltage-level>" format
ledLogBufferOffset += snprintf(
ledLogBuffer + ledLogBufferOffset,
sizeof(ledLogBuffer) - ledLogBufferOffset,
"LED_%d:%d",
ledIndex,
ledVoltageLevels[ledIndex] * LED_VOLTAGE_LEVEL_LOG_FACTOR
);
if (ledIndex != LED_COUNT - 1) {
ledLogBuffer[ledLogBufferOffset++] = ',';
}
// check if the timer has ticked; any number of times per loop iteration
if (!ledTimers[ledIndex].didItTick()) {
continue;
}
ledVoltageLevels[ledIndex] = ledVoltageLevels[ledIndex] == LOW ? HIGH : LOW;
digitalWrite(ledPins[ledIndex], ledVoltageLevels[ledIndex]);
}
Serial.println(ledLogBuffer);
}
Screenshots
Output of the Serial Plotter tool for blinking on the cicada principle:
