Помогите советом. Прерывание цикла.
- Войдите на сайт для отправки комментариев
Доброго времени суток. Помогите, пожалуйста, советом по организации прерывания.
Суть такая. Пытаюсь соорудить что-то типа LED контроллера.
Схема отладки:
1. UNO
2. Тактовая кнопка, притянута к земле, подключена на второй pin.
3. RGB светодиоды:
redled = 3;
greenled = 5;
blueled = 6;
Что хотелось бы увидеть. Диоды мигают по какому-то своему алгоритму, при нажатии кнопки происходит переключение программы "мигалки".
Например. Мигает красный, нажал кнопку - замигал зеленый, еще раз нажал - замигал синий, еще раз нажал - стали мигать RGB по очереди.
Программист я неопытный. Гуглил, читал, в итоге пришел к одному варианту, который больше всего напоминает то, что я хочу, но и с ним немного что-то не так.
По порядку
int switchPin = 2; int redled = 3; int greenled = 5; int blueled = 6; volatile int LEDstate = 0; char colors[3] = {redled, greenled, blueled}; //Засунул в массив для удобства обращения через циклы void setup() { pinMode(blueled, OUTPUT); pinMode(redled, OUTPUT); pinMode(greenled, OUTPUT); pinMode(switchPin, INPUT); attachInterrupt(0, LEDstateSwitch, LOW); } //Мигаем три раза цветом по выбору void anyblink(int x){ for(int i=0;i<3;i++){ digitalWrite(colors[x], HIGH); delay(1000); digitalWrite(colors[x], LOW); delay(1000); } } //Мигаем бесконечно цветом по выбору void anyblink(int x){ int tmp_LEDstate = LEDstate; while(tmp_LEDstate == LEDstate){ for(int i=0;i<3;i++){ digitalWrite(colors[x], HIGH); delay(1000); digitalWrite(colors[x], LOW); delay(1000); } } } //Три красных, три зеленых, три синих void anyblink_all(){ for(int i=0;i<3;i++){ anyblink(i); } } //В лупе - код, который запускает определенную функцию, в зависимости от значения LEDstate //LEDstate принимает значения от [0-3], а каждое нажатие кнопки увеличивает значение на 1 //Если значение LED state становится больше 3, то присваиваем значение "0" //Таким образом, переключаем программы мигалок по кругу void loop() { if (LEDstate > 3) //Проверяем, не превышено ли максимальное значение { LEDstate = 0; } else { if (LEDstate == 0) //Три красных свистка { anyblink(0); } else if (LEDstate == 1) //Три зеленых { anyblink(1); } else if (LEDstate == 2) //Три синих { anyblink(2); } else if (LEDstate == 3)//Три красных, три зеленых, три синих. { anyblink_all(); } } } //Обработка прерывания с дебонсом и увеличением значения LEDstate на 1 void LEDstateSwitch() { static unsigned long millis_prev; if(millis()-100 > millis_prev) LEDstate++; millis_prev = millis(); }
Получается на выходе следующее. Если берем функцию с тремя вспышками, то прерывается только та вспышка, с которой совпало нажатие кнопки, оставшиеся срабатывают, и только после этого происходит переключение программы. Если не совсем понятно, то на примере:
Мигает красный, который должен мигнуть три раза по условиям функции. Если нажимаем во время первой вспышки из трех, прерывается только первая вспышка, диод моргает еще два раза красным и после этого включается зеленая мигалка.
Если берем функцию anyblink_all(), которая, напоминаю, должна мигнуть три раза красным, три зеленым, и три синим, то попытавшись ее прервать на красном, увидим, как она домаргивает зеленым и синим и только потом начинается выполнение следующей функции.
В случае с infiniteblink(), бесконечным циклом, переключение вообще не происходило, если не добавлять условие
int tmp_LEDstate = LEDstate; while(tmp_LEDstate == LEDstate)
после обработки прерывания, программа продолжается с прерванного места, т.е после прерывания функция продолжится до конца.
надо взводить флаг и постоянно проверять его в цикле, если он взведен, делать break. А прерывание может происходить в _любом_ месте цикла
Не уверен, что правильно Вас понял, но спасибо :)
Добвил в начало каждой функции
Дабы зафиксировать текущее состояние режима. А в конце каждой итерации цикла включил проверку
Получилось вот так:
Только все еще не пойму, почему при выставлении триггера прерываний в LOW, все задержки половинятся. Похоже, что в функции delay() что-то скипается, раз кнопка поднята.
В общем, вроде работает основная часть. Если есть более изящный способ воплотить мою идею, буду рад увидеть :)
Код написан канешно не очень но я его поправил. Попробуйте
1 ошибка это delay();
2 ошибка это останавливать delay() прерыванием.
Ну делай - это само собой. А если без далай то тогда так
Я сделал так Полный скетч здесь https://yadi.sk/d/rbJvpZqd3Bvw4h
А это головной файл
Благодарю за внимание, но некорректно работает без этого
Да и, не понимаю пока почему, но при всех типах прерывания, кроме LOW, смена LEDstate происходит при как при нажатии, так и при отпускании кнопки. Т.е. за один цикл нажатия, происходит +2 к LEDstate.
Пропробывай
может, в millis() опять неявно прерывания разрешаются?
Ну делай - это само собой. А если без далай то тогда так
Я сделал так Полный скетч здесь https://yadi.sk/d/rbJvpZqd3Bvw4h
А это головной файл
Спасибо, это уже круто. Необходимо время для осмысления :) Совсем другой уровень.
Пропробывай
может, в millis() опять неявно прерывания разрешаются?
Вечером попробываю, спсибо!
Пропробывай
может, в millis() опять неявно прерывания разрешаются?
пробую: millis_prev = 5; if(6 - 50 > 5) O_O;
if
((millis()-millis_prev)>50) LEDstate++; else return;
Благодарю за внимание, но некорректно работает без этого
Да и, не понимаю пока почему, но при всех типах прерывания, кроме LOW, смена LEDstate происходит при как при нажатии, так и при отпускании кнопки. Т.е. за один цикл нажатия, происходит +2 к LEDstate.
Это у Вас идет дребезг контактов а с millis дребезг устраняется. Так что отавляйте это полезно
Ну, да. я это и имел ввиду. Там закомменчено в коде, что тут дебонс идет.
Вот. тут хотел уточнить. Какова роль переменных kol и volume?
kol-перебор цвета(красн. син.зелен) volume-количество морганий
kol-перебор цвета(красн. син.зелен) volume-количество морганий
А я так понял. что перебор цвета, это kolor, а у kol ОДЗ [0:5]
Да Вы правы vulume выполняла тоже что и kol можно обойтись без нее. Поэтому я применил ее в другое где она нужнее
kol-перебор цвета(красн. син.зелен) volume-количество морганий
Мда... "Найдите 10 отличий" (с)
color - цвет, value - значение/величина.