Прервать выполнение функции немедленно
- Войдите на сайт для отправки комментариев
Пнд, 09/01/2017 - 02:13
Друзья, привет!
Делаю светофор с четырьма режимами:
0. автопереключалка
1. красный
2. желтый
3. зеленый
Все хорошо пока не выполняю функцию autol() она выполняется непрерывно.
Подскажите пожалуйста, как можно:
1. Прервать выполнение функции немедленно.
2. При возвращении в функцию начать не с того же места а с начала. То-есть заново ее запустить и забыть о прерваной итерации.
Код ниже:
int red = 2;
int yellow = 3;
int green = 4;
int sb = 12;
int modec = 1;
int reading;
int lastButtonState=LOW;
int buttonState=LOW;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 0;
void setup() {
// put your setup code here, to run once:
pinMode(red, OUTPUT);
pinMode(yellow, OUTPUT);
pinMode(green, OUTPUT);
pinMode(sb, INPUT);
}
void loop (){
int reading = digitalRead(sb);
if (reading != lastButtonState) {
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
if (reading != buttonState) {
buttonState = reading;
if (buttonState == HIGH) {
modec++;
if (modec==4) {
modec=0;
}
}
}
}
if (modec==0) {
digitalWrite(red,LOW);
digitalWrite(yellow,LOW);
digitalWrite(green,LOW);
autol();
}
if (modec==1) {
digitalWrite(red,HIGH);
digitalWrite(yellow,LOW);
digitalWrite(green,LOW);
}
if (modec==2) {
digitalWrite(red,LOW);
digitalWrite(yellow,HIGH);
digitalWrite(green,LOW);
}
if (modec==3) {
digitalWrite(red,LOW);
digitalWrite(yellow,LOW);
digitalWrite(green,HIGH);
}
}
void autol() {
digitalWrite(red, HIGH);
delay(5000);
digitalWrite(red, LOW);
digitalWrite(yellow, HIGH);
delay(1000);
digitalWrite(yellow, LOW);
digitalWrite(green, HIGH);
delay(5000);
digitalWrite(green, LOW);
digitalWrite(yellow, HIGH);
delay(2000);
digitalWrite(yellow, LOW);
return;
}
А какое событие должно вызвать это прерывание?
(мне кажется , или я ответил на его вопрос)
void reset() { red = 2; yellow = 3; green = 4; sb = 12; modec = 1; lastButtonState=LOW; buttonState=LOW; lastDebounceTime = 0; debounceDelay = 0; }Все хорошо пока не выполняю функцию autol() она выполняется непрерывно.
Подскажите пожалуйста, как можно:
1. Прервать выполнение функции немедленно.
2. При возвращении в функцию начать не с того же места а с начала. То-есть заново ее запустить и забыть о прерваной итерации.
Поэтой причине удобная функция delay() так НЕУДОБНА. используйте millis().
Пока нет ответа на вопрос inspiritus, всё остальное - толчение воды в ступе. Ждем-с :)
Повторяю для тах кто в ТАНКЕ, delay() прервать нельзя.
Да, ладно Вам. Любое, самое замухрыжное прерывание, прервёт delay за милую душу.
Да, ладно Вам. Любое, самое замухрыжное прерывание, прервёт delay за милую душу.
И дальше что? Передаст управление другой строке. Ну не будет же программа висеть в вечном прерывании.
всегда можно нажать кнопку reset и случится то, чего желает ТС
... или сделать программный ресет...
... или сделать программный ресет...
ага - из делея прерыванием
И дальше что?
Что нужно программисту, то и дальше.
Ну так напишите свой delay() в котором будет выход по условию. Это ж программа. Не нравится стандартный delay - ни кто не запрещает написать свой, если клапауция всуе не упоминать.
#include <avr\wdt.h> const byte ldata[120]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3, 3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,4,0,4,0,4,2,2,2,2, 2,2,2,2,2,2}; #define RED (2) #define YELLOW (3) #define GREEN (4) #define BTN (12) unsigned long last_d=millis(), // last data change last_b=millis(); // last button time byte pos=0; // cycle position bool hold=false; // stay on single color void setup() { wdt_enable(WDTO_2S); pinMode(RED, OUTPUT); pinMode(YELLOW, OUTPUT); pinMode(GREEN, OUTPUT); pinMode(BTN, INPUT); } void loop() { wdt_reset(); if(hold){ if(millis()-last_b>=500 && digitalRead(BTN)){ // button poll switch(pos){ case 0: pos=110; break; // yellow case 104: pos=0; break; // red case 109: pos=0;hold=false;last_d=millis();break; // ret to normal mode case 110: pos=109; break; // green } last_b=millis(); } }else{ if(millis()-last_d>=500){ // animation cycle if(pos<119) pos+=1; else pos=0; last_d=millis(); } if(millis()-last_b>=500 && digitalRead(BTN)){ // button poll hold=true; pos=104; // no color last_b=millis(); } } digitalWrite(RED, ldata[pos]&1); //show digitalWrite(YELLOW,ldata[pos]&2); digitalWrite(GREEN, ldata[pos]&4); }Не хочу вникать в программу ТС, но если Вы хотите быстро прервать delay-длиное, то можно вместо длиного delay использовать свою функцию, которая будет тысячу раз, в цикле, использовать в тысячу раз болеее короткий delay. А между использованиями короткого delay, проверяйте нужное Вам условие для быстрого прекращения длинного delay. Если оно, условие, возникло, то прекращаете работу своей функции. Например, в операторе for
(inti=0; i <= 1000; i++){delay(1);..........} переменной i по нужному Вам условию присваиваете i=1000 и цикл скоропостижно завершается.класс титановый велосипед для delay без delay().
Ну я конечно не решил вопрос с перыванием delay(). Я просто написал иначе программу. Я проверил собирайте и закачивайте скетч.
/*millis_antonzol.ino #1 светодиоды красный ->2 (Red_pin) 1 горит / 0 нет желтый ->3 (Yellow_pin) 1 горит / 0 нет зеленый ->4 (Green_pin) 1 горит / 0 нет #2 кнопка ->5 (Btn1_pin) 0 нажата / 0 нет */ //#1 const int Red_pin = 2; bool Red; const int Yellow_pin = 3; bool Yellow; const int Green_pin = 4; bool Green; //#2 кнопка const int Btn1_pin = 5; bool Btn1, Btn1_old; bool Bounce_Btn1 = 0; // антидребезговый флаг byte modec = 1; // режим 1 красный мигает / 2 желтый мигает /3 зеленый / переключение R -> Y -> G -> Y -> R byte step = 1; // 1 мигает красный /1 мигает желтый /1 мигает зеленый void setup() { //#1 pinMode(Red_pin, OUTPUT); digitalWrite(Red_pin, Red = 0); pinMode(Yellow_pin, OUTPUT); digitalWrite(Yellow_pin, Yellow = 0); pinMode(Green_pin, OUTPUT); digitalWrite(Green_pin, Green = 0); //#2 pinMode(Btn1_pin, INPUT_PULLUP);// подключить кнопку 1 с подтяжкой Btn1 = digitalRead(Btn1_pin); } void loop () { //#1 static uint32_t past_1 = 0 ; static uint32_t past_3 = 0 ; if ((modec == 1 || modec == 4 && step == 1) && millis() - past_1 > 300) { // 0,3 сек мигание красным past_1 = millis(); digitalWrite(Red_pin, Red = ! Red); if (! Red && millis()- past_3 > 5000) { // если красный в режиме 4 мигает больше 5 сек past_3 = millis(); step = 2; } } if ((modec == 2 || modec == 4 && (step == 2 || step == 5)) && millis() - past_1 > 300) { // 0,3 сек мигание желтым past_1 = millis(); digitalWrite(Yellow_pin, Yellow = ! Yellow); if (! Yellow && millis()- past_3 > 2000) { // если желтым в режиме 4 мигает больше 2 сек past_3 = millis(); if (step == 2)step = 3; // R->Y->G if (step == 5)step = 1;// G->Y->R } } if ((modec == 3 || modec == 4 && step == 3) && millis() - past_1 > 300) { // 0,3 сек мигание зеленым past_1 = millis(); digitalWrite(Green_pin, Green = ! Green); if (! Green && millis()- past_3 > 5000) { // если желтым в режиме 4 мигает больше 5 сек past_3 = millis(); step = 5; } } //#2 static uint32_t past_2 = 0 ; if (! Bounce_Btn1 && Btn1 != digitalRead(Btn1_pin)) { // если прошел фронт изм на выводн Bounce_Btn1 = 1; // выставить флаг past_2 = millis(); // сделать временую засветку } else if ( Bounce_Btn1 && millis() - past_2 >= 5 ) { // если прошло антидребезговое время Bounce_Btn1 = 0; // то снять флаг Btn1_old = Btn1; Btn1 = digitalRead(Btn1_pin) ; // прочитать реальное значение на выводе if (Btn1_old && ! Btn1) { modec ++ ; if (modec > 4) modec = 1; digitalWrite(Red_pin, Red = 0); digitalWrite(Yellow_pin, Yellow = 0); digitalWrite(Green_pin, Green = 0); } } }А ТС еще спит?
А ТС еще спит?
разбудить?
Ахахахаха! Срочно за учебник!
Ахахахаха! Срочно за учебник!
Достал банку с попкорном... ))
Лучше учебник.
универсальный прерыватель функций
Ахахахаха! Срочно за учебник!
Достал банку с попкорном... ))
Присоединяюсь
универсальный прерыватель функций
у него время срабатывания 100 миллисекунд, при токе более 200 ампер )))
Если делей на 5 часов, то пойдеть )))))
Ахахахаха! Срочно за учебник!
ну давай, вещай, прерыватель делеев.
сегодня твой день, что не пост прям хоть записывай.
ну давай, вещай, прерыватель делеев.
...иш...петь хотели заставить...