Как стать автором
Обновить

Комментарии 6

в ардуино ид изначально есть примеры не тормозящего счетчика для мигания светодиодом.
реализуется легко в одной строке с условием и суммирование в переменную
делал так во всех проектах, никогда делай не использовал.
У меня даже была индикация на 7-и сегментник и конечный автомат в одном цикле и прекрасно работало
задержку дребезга делал примерно так
if ((PINC&(1<<PC5))==0x00){butt1++; if(butt1>200){butt1=201;}} else {butt1=0;}
if(butt1==200 ){тут чего-то делаем; butt1=201;}
и тут сразу отработка действия четко один раз
примерно таким же макаром удалось работать с энкодером без левых срабатываний


если кнопок много то библиотека конечно размер кода сократит.


На контроллере несколько таймеров — а это по сути еще несколько независимых параллельных процессов.
Правда с ардуино может не прокатить так как некоторые библиотеки уже используют таймер и попытка его использовать впрямую может привести к неожиданному результату.

Счётчик миллисекунд в ограничен разрядностью, и через какое то время сбросится в 0. Тут то эти таймеры и сглючат. Это реальная ситуация. Я уже четыре года занимаюсь проектом по действительному переводу ардуино на языки ПЛК. В первый год у меня были таймеры по такому же принципу. Было много реальных ошибок на устройствах собранных пользователями. Решается введением нескольких строчек.

bool _isTimer(unsigned long startTime, unsigned long period )
{
  unsigned long currentTime;
  currentTime = millis();
  if (currentTime >= startTime) {
    return (currentTime >= (startTime + period));
  }else {
    return (currentTime >= (4294967295 - startTime + period));
  }
}
От сброса счетчика миллисекунд существует простой, известный большинству ардуинщиков рецепт:

unsigned long tm = millis();
unsigned long elapsed = (tm >= previousMillis) ? tm - previousMillis : 0xFFFFFFFF - previousMillis + tm + 1;
if( elapsed > interval ) {
  .......
}

Простой контроль переполнения. И ничего не сглючит.
Это Ваш вариант (в стиле — убейте мозг), у меня свой (который делает то же самое), но более читаемый. Каждый программист — как художник — видит по своему))))
Не проще писать сразу так if (millis()-startTime>period)?
Ваш код защищает не от переполнения счетчика блока таймера как такового (он начинает тикать от startTime), а от смены знака при переходе счетчика millis() через 0, но ведь используемые беззнаковые типы данных unsigned long как раз позволяют производить вычитание на границе 0xFF… 0x0 без разрыва, мой код позволяет это делать:
ET = millis() — _StartTime; // вычисляем время
if (ET >= PT)
А от 50-дневного переполнения таймер конечно не защищен, но от него это и не требуется. Когда такие интервалы программируются лучше (надежнее и точнее) использовать RTC.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации