Задержка без delay
- Войдите на сайт для отправки комментариев
Пнд, 11/05/2015 - 22:16
Всем привет. есть светодиод, который должен включиться при наступлении определенного события (в loop'e) с задержкой в ~0,5 сек. Если событие наступило- включается через 0,5сек, отступило - выключается через 0,5сек.
MILLIS? че то не получается. подскажите пожалуйста
int ledPin = 9;
int analogPin = 5;
int val = 0;
unsigned long currentTime;
unsigned long loopTime;
void setup()
{ currentTime = millis(); // считываем время, прошедшее с момента запуска программы
loopTime = currentTime;
pinMode(ledPin, OUTPUT);
pinMode(12, OUTPUT); // установка порта на выход
}
void loop()
{
val = analogRead(analogPin);
if (val > 254) //при наступлении этого события должен вкл. светодиод
{ val = 255;
currentTime = millis(); // считываем время, прошедшее с момента запуска программы
if(currentTime - loopTime >500){ // сравниваем текущий таймер с переменной loopTime + 1 секунда
digitalWrite(12, HIGH); /
loopTime = currentTime; // в loopTime записываем новое значение
}
}
if (val >80)
{ val = 250;
currentTime = millis(); // считываем время, прошедшее с момента запуска программы
if(currentTime - loopTime >500){ // сравниваем текущий таймер с переменной loopTime + 1 секунда
digitalWrite(12, LOW);
loopTime = currentTime; // в loopTime записываем новое значение
}}
if (val < 80)
{ val = 0;
currentTime = millis(); // считываем время, прошедшее с момента запуска программы
if(currentTime - loopTime >500){ // сравниваем текущий таймер с переменной loopTime + 1 секунда
digitalWrite(12, LOW);
loopTime = currentTime; // в loopTime записываем новое значение
}}
analogWrite(ledPin, val);
}
начните работать с одним событием ( если чё - дальше подскажем )
в сетапе строки 8..9 - не нужны
каждому событию нужна отдельная переменная засечки времени
:)
куррентайм - это же и есть миллис , лишняя переменная
луптайм - время жизни программы не нужно
для событий нужно millisOldEvent1 , millisOldEvent2 , millisOldEvent3 ..........
и отслеживать по
if ( millis() - millisOldEvent1 > 500 )
if ( millis() - millisOldEvent2 > 100 )
if ( millis() - millisOldEvent3 > 58 )
Как по условию я понял что нужно два таймера один с задержкой на включение второй с задержкой на отключение, по уставкам лудше поставить защелку типа RS-тригер
Мой вариант решения, по флагам events_now (0..5) программа всегда знает в какой фазе исполнения она находится:
#define ledPin 13 #define analogPin 5 int val; byte events_now=0; unsigned long prevmillis; void setup(){ pinMode(ledPin, OUTPUT); } void loop(){ val=analogRead(analogPin); if (val>254&&events_now==0) events_now=1 ; if (val<254&&events_now==3) events_now=4 ; if (events_now) led_mode(); } void led_mode (){ switch (events_now) { case 1: // если сработало 1 раз prevmillis=millis(); events_now=2; //флаг что идёт отсчёт до начала включения лед break; case 2: //если считаем время до включения if (millis()-prevmillis >500) { digitalWrite (ledPin,HIGH); events_now=3;}// лед горит, ожидаем val <254 break; case 4: // заявка на отключение лед prevmillis=millis(); events_now=5; break; case 5: // счёт до отключения идёт if (millis()-prevmillis >500){ digitalWrite (ledPin,LOW); events_now=0;} //все этапы пройдёны } }dimax
Пока первый таймер не отработает до конца с превышенной уставкой светик не дожен загоратся. Если уставка снизится раньше таймер дожен сбросится, у вас получается хоть на 1 мкс уставка превышенна светик включится на секунду.
Аналогичный алгоритм я делал так
#include <Timer_P.h> bool Night; Timer_P LightFilterOn, LightFilterOff; void setup() { } void loop() { //датчик света if (LightFilterOn.Timer(analogRead(A0) > 100, false, 2, 10000)) Night = true; if (LightFilterOff.Timer(analogRead(A0) < 100, false, 2, 10000)) Night = false; }Это фильтрация аналогового датчика освещенности. Временной гистерезис. 10000 в таймерах - период в течение которого должно выполняться условие первого операнда метода .Timer. Гистерезис по значению тоже есть <=99 отключение и >=101 включение, но вданном примере не играет основную роль.
Понадобится эта библиотека.
https://yadi.sk/d/hGQy8xu1fZNks
Мой вариант решения, по флагам events_now (0..5) программа всегда знает в какой фазе исполнения она находится:
#define ledPin 13 #define analogPin 5 int val; byte events_now=0; unsigned long prevmillis; void setup(){ pinMode(ledPin, OUTPUT); } void loop(){ val=analogRead(analogPin); if (val>254&&events_now==0) events_now=1 ; if (val<254&&events_now==3) events_now=4 ; if (events_now) led_mode(); } void led_mode (){ switch (events_now) { case 1: // если сработало 1 раз prevmillis=millis(); events_now=2; //флаг что идёт отсчёт до начала включения лед break; case 2: //если считаем время до включения if (millis()-prevmillis >500) { digitalWrite (ledPin,HIGH); events_now=3;}// лед горит, ожидаем val <254 break; case 4: // заявка на отключение лед prevmillis=millis(); events_now=5; break; case 5: // счёт до отключения идёт if (millis()-prevmillis >500){ digitalWrite (ledPin,LOW); events_now=0;} //все этапы пройдёны } }А нафиг здесь вообще в loop такие сложности, проще в луп вызывать led_mode, а уже в нем считывать analogRead и тогда будет всё под рукой и этот конечный автомат (а он здесь напрашивается по полной програме, тупо и просто) будет в одном месте, а не размазан по разным точкам.
Вместо 12 строки проверка в switch (events_now) { case 0: ...
А вместо 13 строки проверка в switch... case 3: if(val<254) events_now = 4; или типа того.
UPD: И да, классика, всё что в аналоге, имеет сволочную особенность, ловить помехи и лучше в таких местах закладывать гистерезис (разносить точки включения и выключения). Да что говорить, тут описано
Здравствуйте - Подскажите что врезать здесь- для выполнение команды с задержкой до 6 секунд.
1-кнопка - нажатие первое старт таймера 1, нажатие 2-раза старт таймера 2. эта кнопка работает нормально.
Проблема с 2 кнопкой.
2-кнопка нужно 1-вое нажатие стоп таймера 1 и через 6 секунд само сброс таймера 1,нажатие 2 -го раза этой кнопки стоп таймере 2 и через 6 секунд само брос иаймера 2.
ТО ЕСТЬ__________________________________________________________________________________
Timer2State= LOW;
Здравствуйте - Подскажите что врезать здесь- для выполнение команды с задержкой до 6 секунд.
1-кнопка - нажатие первое старт таймера 1, нажатие 2-раза старт таймера 2. эта кнопка работает нормально.
Проблема с 2 кнопкой.
2-кнопка нужно 1-вое нажатие стоп таймера 1 и через 6 секунд само сброс таймера 1,нажатие 2 -го раза этой кнопки стоп таймере 2 и через 6 секунд само брос иаймера 2.
ТО ЕСТЬ__________________________________________________________________________________
Timer2State= LOW;
проверь, должно скомпилиться
Вау- клева. А по вопросу как?