Задержка в ARDUINO без delay(), с проверкой millis() на переполнение.

В этом посте вы можете скачать маленькую библиотеку для ARDUINO в которой реализован таймер для создания задержки в ARDUINO без delay() с проверкой millis() на переполнение.


В необходимости реализации задержки без delay сомнений нет, т.к. останавливать работу всего устройства для ожидания чего-либо это не корректно. Можно конечно копипастить в каждый скетч одну и ту же функцию, но реализация задержки с помощью объекта гораздо проще.



Ардуино. Задержка без delay() с помощью millis(). Библиотека Timer.

Описание библиотеки можно посмотреть здесь: Задержка в ARDUINO без delay()

Текущая версия: 0.0.2 / 2019.01.28

Изменения:
1. Тип возвращаемых данных методом getState() стал enum;
2. При вызове метода setTime() метод reset() выполняется сразу внутри него.

Предыдущие версии:
0.0.1 / 2018.10.31 / http://allforproject.ru/sdm_downloads/arduino-lib-timer/

Size: 3 KB
Version: 0.0.2


Файлы библиотеки:


Timer.h


  1. #ifndef Timer_h
  2. #define Timer_h
  3.  
  4. #include "Arduino.h"
  5. class Timer {
  6. public:
  7.     Timer();                            //конструктор по-умолчанию
  8.     Timer(uint32_t delayTime);          //конструктор №1, принимает время задержски в мс
  9.     enum timerState {
  10.         READY,
  11.         COUNTDOWN,
  12.         DELAY_OVER,
  13.         PAUSED
  14.     };
  15.     void delay();                       //выполняет задержку, результат сохраняет в state
  16.     void start();                       //запускает таймер
  17.     void stop ();                       //останавливает таймер, с сохнанением оставшегося времени задержки
  18.     void reset ();                      //подготавливает таймер к запуску, восстанавливая время задержки
  19.     void setTime(uint32_t delayTime);   //изменяет время задержки
  20.     uint32_t getTime ();                //возвращает установленное время задержки
  21.     timerState getState ();
  22.  
  23. protected:
  24.     uint32_t _delayTime;                //хранит время задержки
  25. private:
  26.     timerState state ;
  27.     uint32_t _timeStore;                //хранит millis()
  28.     uint32_t _delayTimeBuffer;          //буфер для работы с временем задержки
  29. };
  30. #endif

Timer.cpp


  1. #include "Arduino.h"
  2. #include "Timer.h"
  3.  
  4. Timer::Timer(){
  5. _delayTime = 0;
  6. state = timerState::DELAY_OVER;
  7. };
  8. Timer::Timer(uint32_t delayTime){
  9. _delayTime = delayTime;
  10. reset();
  11. };
  12. void Timer::delay(){
  13.     if(state == timerState::COUNTDOWN){
  14.         if (millis() < _timeStore){
  15.             if(millis() + 4294967295 - _timeStore >  _delayTimeBuffer) {state = timerState::DELAY_OVER;}
  16.         }
  17.         else{
  18.             if(millis () > _timeStore + _delayTimeBuffer) {state = timerState::DELAY_OVER;}
  19.         }
  20.     }
  21. };
  22. void Timer::start(){
  23.     if ((state == timerState::READY) || (state == timerState::PAUSED)){
  24.         state = timerState::COUNTDOWN;
  25.         _timeStore = millis();
  26.     }
  27. };
  28. void Timer::stop(){
  29.     state = timerState::PAUSED;
  30.     if (millis() < _timeStore){ _delayTimeBuffer = _delayTimeBuffer - (millis() + 4294967295 - _timeStore);}
  31.     else{_delayTimeBuffer = _delayTimeBuffer - (millis() - _timeStore);}
  32. };
  33. void Timer::reset(){
  34.     state = timerState::READY;
  35.     _delayTimeBuffer = _delayTime;
  36. }
  37. void Timer::setTime(uint32_t delayTime){
  38.     _delayTime = delayTime;
  39.     reset();
  40.     };
  41. uint32_t Timer::getTime (){return _delayTime;};
  42.  
  43. Timer::timerState Timer::getState (){
  44.     return state;
  45. };

Комментарий по работе:
После создания объекта с помощью конструктора по-умолчанию необходимо указать время задержки с помощью метода setTime(). Далее необходимо выполнить метод start(), который по сути является триггером для метода delay(), он устанавливает state в состояние COUNTDOWN. Теперь крутим delay() и контролируем состояние свойства state с помощью метода getStatus(). Как только он станет примет значение DELAY_OVER delay() выполняться перестает, что свидетельствует об окончании задержки.
Предусмотрена возножность остановки таймера с помощью метода stop(), с сохранением оставшегося времени задержки и возможности дальнейшего запуска методом start(). После окончания задержки таймер необходимо «взвести» методом reset(), после этого его можно использовать снова.


Скетч для проверки:


  1. #include <Timer.h>
  2. Timer timer(5000); // создаем объект таймер с задержкой 5 сек
  3. //Timer timer ; 
  4. void setup() {
  5.   Serial.begin(9600);
  6.   //timer.setTime(2000);
  7. }
  8.  
  9. void loop() {
  10.   timer.delay();  //крутим в цикле функцию задержки
  11.   if (timer.getState() == Timer::timerState::COUNTDOWN) Serial.print (F("."));
  12.   if (timer.getState() == Timer::timerState::DELAY_OVER) {
  13.     Serial.println();
  14.     Serial.println (F("Delay over!"));
  15.     timer.reset();
  16.     } ; 
  17.   test();
  18.   //delay (500);
  19. }
  20. void test() {
  21.   if (Serial.available()) {
  22.     byte symbol = Serial.read();
  23.     switch (symbol){
  24.     case '0' : 
  25.       Serial.println();
  26.       Serial.println(F("0 pressed"));
  27.       timer.start(); // старт таймера
  28.     break;
  29.     case '1' :
  30.       Serial.println();
  31.       Serial.println(F("1 pressed"));
  32.       timer.stop(); // остановка таймера
  33.     break;
  34.     case '2' :
  35.       Serial.println();
  36.       Serial.println(F("2 pressed"));
  37.       timer.setTime(10000); // установка времени задержки
  38.     break;
  39.     }
  40.   }
  41. }

Оцените пожалуйста статью:

ПечальноТак себеНе плохоХорошоОтличная статья! 2 оценок.
Загрузка...

9 Replies to “Задержка в ARDUINO без delay(), с проверкой millis() на переполнение.

  1. Добрый день. Много искал библиотеки с таймерами. Ваша понравилась комментариями. Но программа не компилируется для Ардуино Нано. В чём может быть причина?

    Плата:»Arduino Nano, ATmega328P»
    Ошибка компиляции для платы Arduino Nano.

    1. Радик здравствуйте! Укажите в комментарии лог компилятора. К сожалению ардуино нано нет под рукой и проверить не могу. На меге и уно все компилируется.

  2. Добрый вечер. Ардуино нано уже использовал в другом проекте. Надеюсь на днях придёт ещё посылка с ардуинками, Тогда обязательно ещё раз всё проверю и отпишусь. Спасибо.

  3. Arduino: 1.8.9 (Windows 10), Плата:»MH-ET LIVE Tiny88(16.0MHz)»

    C:\Program Files (x86)\Arduino\libraries\Timer\Timer.cpp: In constructor ‘Timer::Timer()’:

    C:\Program Files (x86)\Arduino\libraries\Timer\Timer.cpp:13:9: error: ‘timerState’ is not a class or namespace

    state = timerState::DELAY_OVER;

    ^

    C:\Program Files (x86)\Arduino\libraries\Timer\Timer.cpp: In member function ‘void Timer::delay()’:

    C:\Program Files (x86)\Arduino\libraries\Timer\Timer.cpp:20:17: error: ‘timerState’ is not a class or namespace

    if(state == timerState::COUNTDOWN){

    ^

    C:\Program Files (x86)\Arduino\libraries\Timer\Timer.cpp:22:81: error: ‘timerState’ is not a class or namespace

    if(millis() + 4294967295 — _timeStore > _delayTimeBuffer) {state = timerState::DELAY_OVER;}

    ^

    C:\Program Files (x86)\Arduino\libraries\Timer\Timer.cpp:25:68: error: ‘timerState’ is not a class or namespace

    if(millis () > _timeStore + _delayTimeBuffer) {state = timerState::DELAY_OVER;}

    ^

    C:\Program Files (x86)\Arduino\libraries\Timer\Timer.cpp: In member function ‘void Timer::start()’:

    C:\Program Files (x86)\Arduino\libraries\Timer\Timer.cpp:30:19: error: ‘timerState’ is not a class or namespace

    if ((state == timerState::READY) || (state == timerState::PAUSED)){

    ^

    C:\Program Files (x86)\Arduino\libraries\Timer\Timer.cpp:30:51: error: ‘timerState’ is not a class or namespace

    if ((state == timerState::READY) || (state == timerState::PAUSED)){

    ^

    C:\Program Files (x86)\Arduino\libraries\Timer\Timer.cpp:31:17: error: ‘timerState’ is not a class or namespace

    state = timerState::COUNTDOWN;

    ^

    C:\Program Files (x86)\Arduino\libraries\Timer\Timer.cpp: In member function ‘void Timer::stop()’:

    C:\Program Files (x86)\Arduino\libraries\Timer\Timer.cpp:36:13: error: ‘timerState’ is not a class or namespace

    state = timerState::PAUSED;

    ^

    C:\Program Files (x86)\Arduino\libraries\Timer\Timer.cpp: In member function ‘void Timer::reset()’:

    C:\Program Files (x86)\Arduino\libraries\Timer\Timer.cpp:41:13: error: ‘timerState’ is not a class or namespace

    state = timerState::READY;

    ^

    exit status 1
    Ошибка компиляции для платы MH-ET LIVE Tiny88(16.0MHz).

    Этот отчёт будет иметь больше информации с
    включенной опцией Файл -> Настройки ->
    «Показать подробный вывод во время компиляции»

      1. Это компиляция примера который был в комплекте с библиотекой.

        Arduino: 1.8.9 (Windows 10), Плата:»MH-ET LIVE Tiny88(16.0MHz)»

        Изменены опции сборки, пересобираем все
        C:\Program Files (x86)\Arduino\libraries\Timer\example\example.ino: In function ‘void loop()’:

        example:11:34: error: ‘Timer::timerState’ is not a class or namespace

        if (timer.getState() == Timer::timerState::COUNTDOWN) Serial.print (F(«.»));

        ^

        example:12:34: error: ‘Timer::timerState’ is not a class or namespace

        if (timer.getState() == Timer::timerState::DELAY_OVER) {

        ^

        exit status 1
        ‘Timer::timerState’ is not a class or namespace

        Этот отчёт будет иметь больше информации с
        включенной опцией Файл -> Настройки ->
        «Показать подробный вывод во время компиляции»

        1. Евгений, похоже по какой-то причине компилятор вместо типа данных ENUM распознает в переменной timerState класс или пространство имен, через оператор доступа «::».

          1. Интересно что для другого типа платы все ОК

          2. Евгений, скачайте старую версию. Ссылка есть в описании. Там нет ENUMa.

Добавить комментарий