Работа по таймеру в Arduino. GyverTimer [12.11.19]

ОБНОВЛЕНИЯ


  • v3.2
    • Добавлен isEnabled
    • Возможность не запускать таймер при создании
Предыдущие

  • v2.0 – улучшенный алгоритм работы таймера
    • Кратные интервалы
    • Защита от пропусков
    • Защита от переполнения millis()
    • Убраны дефайны
  • v2.1 – возвращены дефайны
  • v2.2 – улучшена стабильность
  • v3.0
    • Логика работы разделена на интервал и таймаут
    • Добавлен общий класс GTimer (для миллисекундного и микросекундного таймера)
    • Добавлена возможность остановить и продолжить счёт таймера

ТЕОРИЯ


Я думаю все знают классический алгоритм создания таймера на millis() – счётчике аптайма:

Таймер

// Данный код выполняет действия периодически за указанный период
// Нам нужно задать период таймера В МИЛЛИСЕКУНДАХ
// дней*(24 часов в сутках)*(60 минут в часе)*(60 секунд в минуте)*(1000 миллисекунд в секунде)
// (long) обязательно для больших чисел, иначе не посчитает
// можно посчитать на калькуляторе, но какбэ ардуино и есть калькулятор, пусть считает...
unsigned long period_time = (long)5*24*60*60*1000;
// переменная таймера, максимально большой целочисленный тип (он же uint32_t)
unsigned long my_timer;
void setup() {
  my_timer = millis();   // "сбросить" таймер
}
void loop() {
  if (millis() - my_timer >= period_time) {
    my_timer = millis();   // "сбросить" таймер
    // дейтвия, которые хотим выполнить один раз за период
  }
}

БИБЛИОТЕКА


  • Миллисекундный и микросекундный таймер
  • Два режима работы:
    • Режим интервала: таймер “срабатывает” каждый заданный интервал времени
    • Режим таймаута: таймер “срабатывает” один раз по истечении времени (до следующего перезапуска)
  • Служебные функции:
    • Старт
    • Стоп
    • Сброс
    • Продолжить

Поддерживаемые платформы: все Arduino (используются стандартные Wiring-функции)

УСТАНОВКА


  • Библиотеку можно найти и установить через менеджер библиотек по названию GyverTimer в:
    • Arduino IDE (Инструменты/Управлять библиотеками)
    • Arduino IDE v2 (вкладка “Library Manager”)
    • PlatformIO (PIO Home, вкладка “Libraries”)
  • Про ручную установку читай здесь

ДОКУМЕНТАЦИЯ


Конструктор


Класс GTimer позволяет работать как с миллисекундным, так и с микросекундным таймером. В общем виде пример выглядит так:

GTimer myTimer(type, period);

Где type это MS (мс, миллисекундный таймер) или US (мкс, микросекундный), period - период в мс или мкс соответственно.

Настройки по умолчанию


  • При создании таймера можно ничего не указывать: GTimer myTimer; , тогда таймер будет сконфигурирован как миллисекундный и не запустится
  • Если указать только тип таймера (MS/US) GTimer myTimer(MS); , таймер настроится на выбранный режим (мс/мкс) и не запустится
  • Если указать тип таймера и интервал GTimer myTimer(US, 5000); , таймер настроится на выбранный режим (мс/мкс) и запустится в режиме интервала

Режимы работы


Таймер может работать в режиме интервалов и в режиме таймаута:

  • Интервалы. Запуск - метод setInterval(время) с указанием времени. В режиме интервалов таймер срабатывает (метод isReady() возвращает true) каждый раз при достижении указанного периода и автоматически перезапускается. Удобно для периодических действий
  • Таймаут. Запуск - метод setTimeout(время) с указанием времени. В режиме таймаута таймер срабатывает (метод isReady() возвращает true) только один раз при достижении указанного периода и автоматически отключается. Для повторного запуска нужно вызвать .setTimeout() с указанием периода, или просто .start() - запустит таймер на новый круг с прежним периодом

Важный момент: сравнение времени происходит в методе isReady(), без его вызова таймер ничего не считает! Нужно вызывать isReady() всегда, когда требуется счёт времени.

Управление таймером


Для управления состоянием таймера есть следующие методы:

  • start() - запускает (перезапускает) таймер с последним установленным временем
  • stop() - останавливает таймер
  • resume() - продолжает отсчёт таймера с момента остановки
  • reset() - сбрасывает таймер (отсчёт периода/таймаута начинается заново)
  • isEnabled() - возвращает true, если таймер работает (если он не stop() или не вышел таймаут)
void setInterval(uint32_t interval);	// установка интервала работы таймера (также запустит и сбросит таймер) - режим интервала
void setTimeout(uint32_t timeout);		// установка таймаута работы таймера (также запустит и сбросит таймер) - режим таймаута
boolean isReady();						// возвращает true, когда пришло время
boolean isEnabled();					// вернуть состояние таймера (остановлен/запущен)
void reset();							// сброс таймера на установленный период работы
void start();							// запустить/перезапустить (со сбросом счёта)
void stop();							// остановить таймер (без сброса счёта)	
void resume();							// продолжить (без сброса счёта)	

// служебное
void setMode(boolean mode);				// установка режима работы вручную: AUTO или MANUAL (TIMER_INTERVAL / TIMER_TIMEOUT)

ПРИМЕРЫ


Остальные примеры смотри в папке examples библиотеки, также примеры можно открыть из Arduino IDE/Файл/Примеры

// пример работы в режиме интервалов
#include "GyverTimer.h"   // подключаем библиотеку
GTimer myTimer(MS);  // создать миллисекундный таймер (ms) (по умолч. в режиме интервала)
//GTimer myTimer(MS, 1000);  // можно сразу указать период (по умолч. в режиме интервала)
//GTimer myTimer(US, 5000);  // или микросекундный (us), на 5000 мкс (по умолч. в режиме интервала)
// без указания периода таймер автоматически не запустится!
void setup() {
  Serial.begin(9600);
  myTimer.setInterval(500);   // запуск в режиме интервала 500 мс
  
  // myTimer.stop();   // "остановить" таймер
  // myTimer.start();   // запустить (перезапустить) таймер
  // myTimer.reset();   // сбросить период
  // myTimer.resume();   // продолжить работу после stop
}
void loop() {
  if (myTimer.isReady()) Serial.println("Timer!");  // 2 раза в секунду
}
// Пример работы в режиме таймаута
#include "GyverTimer.h"   // подключаем библиотеку
GTimer myTimer(MS);    // создать миллисекундный таймер
//GTimer myTimer(US);    // US - микросекундный
void setup() {
  Serial.begin(9600);
  myTimer.setTimeout(3000);   // настроить таймаут 3 сек
  Serial.println("Start");
}
void loop() {
  // выведет Timeout 3 sec! через 3 секунды после вызова setTimeout(3000)
  if (myTimer.isReady()) Serial.println("Timeout 3 sec!");
  
  // после срабатывания остановит счёт
  // можно перезапустить при помощи setTimeout(время) или start()
}
// пример параллельной работы нескольких таймеров
#include "GyverTimer.h"   // подключаем библиотеку
// создаём таймеры в миллисекундах
GTimer myTimer1(MS, 500);
GTimer myTimer2(MS, 600);
GTimer myTimer3(MS, 1000);
void setup() {
  Serial.begin(9600);
}
void loop() {
  if (myTimer1.isReady())
    Serial.println("Timer 1!");
  if (myTimer2.isReady())
    Serial.println("Timer 2!");
  if (myTimer3.isReady())
    Serial.println("Timer 3!");
}

ПОДДЕРЖАТЬ


Вы можете поддержать меня за создание доступных проектов с открытым исходным кодом, полный список реквизитов есть вот здесь.

3.9/5 - (8 голосов)
Подписаться
Уведомить о
guest

12 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии