Каждый экземпляр таймера занимает 2 или 4 байта. Не использует аппаратный таймер и не использует прерывания. Таймеры имеют разные режимы точности. Количество таймеров не ограничено.
Эти таймеры используются для неблокирующих задержек для Arduino.
csTimer myTimer;
void setup() {
myTimer.start(1000);
}
void loop() {
if (myTimer.run()) {
println(F("Tick"));
myTimer.start(1000);
}
}
Пример 2 - интервал таймера указывается при его создании:
csTimerDef<1000> myTimer;
void setup() {
myTimer.start();
}
void loop() {
if (myTimer.run()) {
println(F("Tick"));
myTimer.start();
}
}
Таймер может находиться в двух состояниях - запущен или остановлен. Таймер при создании находиться в состоянии остановлен.
Чтобы запустить таймер, необходимо вызвать функцию "start", а в параметрах указать требуемое время работы (в миллисекундах). На каждом цикле (loop) должна быть вызвана функция "run" (для каждого экземпляра таймера).
Если функция "run" возвращает True, то значит что таймер отработал свое время. Если его время еще не пришло - функция вернет False.
После сработки таймер переходит в остановленное состояние. Если необходимо снова запустить таймер, необходимо повторно вызвать функцию "start" (см. Примеры). Если таймер остановлен, вызов "run" всегда вернет False.
Если вы используете эти таймеры, нельзя использовать функцию "delay". Вы не можете вызвать "run" дважды в одном экземпляре таймера за одно сканирование - второй вызов не будет работать. Вы не должны "скрывать" вызов функции "run" в сложном условии (см. Примеры).
Чтобы достичь высокой точности, вы должны вызывать метод "run" для всех таймеров как можно чаще (рекомендуется минимум 1000 раз в секунду). Если ваша процедура "loop" не содержит медленных и блокирующих функций, тогда вам не нужно специально беспокоиться об этом - процедура "loop" вызывается достаточно часто и быстро.
Классы таймеров:
-
csTimer - большой таймер, максимальное время - 12 дней. Размер - 4 байта.
-
csTimerShort - короткий таймер, максимальное время - 16 секунд. Размер - 2 байта.
-
csTimerDef - аналог csTimer, но с поддержкой времени по умолчанию. Размер - 4 байта.
-
csTimerShortDef - аналог csTimerShort, но с поддержкой времени по умолчанию. Размер - 2 байта.
Функции в классах (для всех классов):
start - запуск таймера. Если таймер уже работает, таймер перезапускается.
startOnce - запуск таймера. Если таймер уже работает, перезапуск не происходит.
stop - остановка таймера.
enabled - если запущен, возвращает True.
run - Основная функция. Должен быть вызван в каждом цикле. Если таймер сработал, то True возвращается один раз.
getFlag - Читать бит флага пользователя. Если флаг не поддерживается, всегда возвращается False. Некоторые классы таймера могут содержать пользовательский флаг, который пользователь использует по своему усмотрению. (см: csTimer32bit_6day_Flag и другие разширенные классы).
setFlag - запись в бит флага пользователя.
Дополнительные 10 классов таймеров с разной точностью и минимальным размером в 1 байт.
Внимание: только для профессионалов! Требуется дополнительное тестирование.
Перечень разширенного набора классов
Примеры как надо писать и как не надо
Эти таймеры учитывают "переполнение счетчика времени" (aka millis overflow, millis rollover ) и корректно его обрабатывают.
Использование csTimerDef не увеличивает размер таймера. csTimer и csTimerDef действительно имеют одинаковый размер. Это осуществляется благодаря тому что время по умолчанию хранится в коде а не в оперативной памяти.
if ( ((TTimer)((TTimer)(TIMER_GET_TIME / PrecDiv) - timer) & BitMask) < MaxValue) { ...
Как это работает?
Очищеная запись: if ((TIMER_GET_TIME - timer) < MaxValue) { ...
Упростим запись (для 16 битного таймера): if (Текущее_Время - Время_Старта_Таймера < 16383) { ...
В нормальной ситуации число становится отрицательным (если таймер еще не достиг времени активации). Но здесь используется беззнаковое целое, поэтому происходит переполнение. Переполнение дает большое число. "Переполненными числами" считаются все которые превышают половину возможного диапазона (это аналогично "signed int" на бинарном уровне). Для определения переполненного числа используется константа "MaxValue".
Как только число стало меньше "переполненного" это значит что число больше не отрицательное, и это значит что таймер достиг времени активации.
Почему я не использую обычные числа? - потомучто в этом проекте активно используются бинарные операции и битовые маски, мне нужно полностью контролировать бинарную систему.