обходим delay();
- Войдите на сайт для отправки комментариев
Чт, 04/02/2016 - 11:54
Собственно возникла примерно такая проблема. Чтоб обойти делай заводим переменную unsigned long, пишем в нее значение millis() и потом сравниваем с неким значением.
А если таких отслеживаний надо делать 10шт приходится заводить 10 переменных, которые жрут память + не сильно удобно каждый раз думать где бы записать в переменную миллис чтоб оно потом не считывадлсь второй раз.
Подскажите плиз как правильно делать в таких случаях :)
я для таких случаев сделал функцию
boolean smartdelay (uint32_t interval, uint8_t i) { static uint32_t previousMillis[8]; static boolean sw[8]; switch (sw[i]) { case 0: previousMillis[i] = millis(); sw[i] = 1; break; case 1: if (millis() - previousMillis[i] >= interval) { previousMillis[i] = millis(); sw[i] = 0; } break; } return sw[i]; }класс титановый велосипед для delay без delay().
Обычно для не критических таемингов от 10мсек до 1минуты использую чтото типа такого. (прям из живого проекта).
enum{ TIMER_CURS=0, TIMER_BRIGHTESS, TIMER_JOYSTICK, TIMER_SCREAN, TIMER_GET_PARAMS, COUNT_TIMER //количество таймеров не более 15 } TIMERS_ID; /* Временные интервалы таймеров в порядке их следования в TIMERS_ID */ word TimerPeriod[COUNT_TIMER]={20,200,20,50,300}; /* Последние срабатывания таймеров */ word TimerArr[COUNT_TIMER]; word TimersMasck=_BV(TIMER_JOYSTICK)|_BV(TIMER_SCREAN)|_BV(TIMER_GET_PARAMS); word TimerRepeat=_BV(TIMER_JOYSTICK)|_BV(TIMER_SCREAN)|_BV(TIMER_GET_PARAMS); word Timer; boolean TimerProcess(void) { word Now=millis(); boolean f=false; word r=1; for(byte i=0;i<COUNT_TIMER;i++,r<<=1) { if(TimersMasck&r) //маска в 1 значить активен { if((Now-TimerArr[i])>TimerPeriod[i]) { if(TimerRepeat&r) TimerArr[i]=Now; //периодические таймер перезапускаем else TimersMasck&=~r; //непериодические таймер останавливаем Timer|=r; //таймер сработал return true; //f=true; } } } return f; } void TimerRun(byte timer) { bitSet(TimersMasck,timer); TimerArr[timer]=millis(); } boolean IsTimerRun(byte timer) { return TimersMasck & _BV(timer); } boolean IsTimerSet(byte timer) { word r=_BV(timer); if(Timer&r) { Timer&=~r; return true; } return false; }Экономно, гибко, 16 таймеров хватает всегда, т.е. не было у меня случая чтоб мало было. Заодно просто решает одну "скользкую" проблему - выравнивает нагрузку. В каждом цикле loop только одно срабатывание таймера, остальные отложатся на следующий (решается в строках 37,38). Без этого возможны очень противные проблемы, возникающие редко при неудачных совпадениях и потому трудно исправимые.