Как обнулить счетчик при повторном обращении к функции в switch..case
- Войдите на сайт для отправки комментариев
Пт, 30/09/2022 - 18:35
Всем привет! Такой вопрос: Как обнулить счетчик при повторном обращении к функции в switch..case. Функция Lights1 () не должна выполняться бесконечно, а всего лишь 1 раз, что собственно я и сделал, но должна выполнится еще раз когда я снова переключу режим о попаду в эту функцию. Режим переключается кнопкой по кругу.
bool FOG_BEAM_RIGHT = 0; bool FOG_BEAM_LEFT = 0; int TURNL_RIGHT = 0; int TURNL_LEFT = 0; int LOWBEAM_RIGHT = 0; int LOWBEAM_LEFT = 0; int HIGHTBEAM_RIGHT = 0; int HIGHTBEAM_LEFT = 0; boolean bStopFlag = false; int g = 0; int f = 0; int s = 0; int d = 75; int ButPin = 8; // Подключаем кнопку к выходу 4 int flag = 0; // флаг состояния int regim = 0; // Переключалка bool LEDflag = false; //Флаг состояния // 0 1 2 3 4 5 6 7 int Pins[] = { 2, 3, 5, 6, 9, 10, 11, 12 }; //Пины куда подключен све bool flagB = false; uint32_t btnTimer = 0; uint32_t myTimerA; //Таймеры задержки uint32_t myTimerB; //Таймеры задержки uint32_t myTimer; int ledState = LOW; // переменная, показывающая состояние светодиода unsigned long previousMillis = 0; //в этой переменной будем хранить время, когда светодиод последний раз мигнул const long period = 35; void setup() { Serial.begin(9600); for (int i = 0; i <= 7; i++) { pinMode(Pins[i], OUTPUT); } pinMode(ButPin, INPUT_PULLUP); } void loop() { int regim = buttonClick(); switch (regim) { case 0: Lights1(); break; case 1: Lights2(); break; case 2: Lights3(); break; case 3: Lights4(); break; default: break; } } int buttonClick() { bool btnState = digitalRead(ButPin); if (btnState && !flagB && millis() - btnTimer > 50) { flagB = true; btnTimer = millis(); f++; Serial.println(f); } if (!btnState && flagB && millis() - btnTimer > 50) { flagB = false; btnTimer = millis(); } if (f > 3) { f = 0; } return f; } void Lights1() { int i = 0; while (i < 1 && !bStopFlag) { for (int i = 7; i >= 0; i--) { digitalWrite(Pins[i], HIGH); delay(d); digitalWrite(Pins[i], LOW); } for (int i = 0; i <= 7; i++) { digitalWrite(Pins[i], HIGH); delay(d); digitalWrite(Pins[i], LOW); } for (int i = 7, j = 0; j <= 3, i >= 4; i--, j++) { digitalWrite(Pins[i], HIGH); digitalWrite(Pins[j], HIGH); delay(250); } for (int i = 7, j = 0; j <= 3, i >= 4; i--, j++) { digitalWrite(Pins[i], LOW); digitalWrite(Pins[j], LOW); delay(500); } i++; } bStopFlag = true; } void Lights2() { int i = 0; while (i < 10) { unsigned long currentMillis = millis(); // сохраняем текущее время if (currentMillis - previousMillis >= period) // проверяем прошли ли 1000ms { previousMillis = currentMillis; // сохраняем последнее время когда мигнул светодиод if (ledState == LOW) { //если светодиод выключен, то включаем его, и наоборот ledState = HIGH; } else { ledState = LOW; } digitalWrite(Pins[0], ledState);//устанавливаем светодиод в состояние, определяемое переменной ledState i++; } } while (i < 20) { unsigned long currentMillis = millis(); // сохраняем текущее время if (currentMillis - previousMillis >= period) // проверяем прошли ли 1000ms { previousMillis = currentMillis; // сохраняем последнее время когда мигнул светодиод if (ledState == LOW) { //если светодиод выключен, то включаем его, и наоборот ledState = HIGH; } else { ledState = LOW; } digitalWrite(Pins[7], ledState);//устанавливаем светодиод в состояние, определяемое переменной ledState i++; } } } void Lights3() { int i = 0; while (i < 10) { unsigned long currentMillis = millis(); // сохраняем текущее время if (currentMillis - previousMillis >= period) // проверяем прошли ли 1000ms { previousMillis = currentMillis; // сохраняем последнее время когда мигнул светодиод if (ledState == LOW) { //если светодиод выключен, то включаем его, и наоборот ledState = HIGH; } else { ledState = LOW; } digitalWrite(Pins[0], ledState);//устанавливаем светодиод в состояние, определяемое переменной ledState digitalWrite(Pins[5], ledState); i++; } } while (i < 20) { unsigned long currentMillis = millis(); // сохраняем текущее время if (currentMillis - previousMillis >= period) // проверяем прошли ли 1000ms { previousMillis = currentMillis; // сохраняем последнее время когда мигнул светодиод if (ledState == LOW) { //если светодиод выключен, то включаем его, и наоборот ledState = HIGH; } else { ledState = LOW; } digitalWrite(Pins[7], ledState);//устанавливаем светодиод в состояние, определяемое переменной ledState digitalWrite(Pins[2], ledState); i++; } } } void Lights4() { int g = 1; do { for (int i = 7; i >= 0; i--) { digitalWrite(Pins[i], HIGH); delay(200); for (int i = 7; i >= 0; i--) digitalWrite(Pins[i], LOW); } g++; } while (g == 1); }
Вариантов много. Например, с минимальными переделками, можно по окончании процедуры которую нужно выполнить 1 раз присваивать regim любое значение за пределами case. Следующее присвоение номера одноразовой процедуры опять выполнит процедуру один раз.
Присваивать можно прямо в функции?
У Вас он глобальный. Поэтому можно везде. И в функции тоже.
Вариантов много. Например, с минимальными переделками, можно по окончании процедуры которую нужно выполнить 1 раз присваивать regim любое значение за пределами case. Следующее присвоение номера одноразовой процедуры опять выполнит процедуру один раз.
Функция зацикливается тогда почему то.
Я даже делал вот так. Поидее функция должна выполнится 1 раз. Но она зацикливается (
А вот так она сколько раз выполняется?
А вот так она сколько раз выполняется?
Бесконечно, пока есть питание.
Функция зацикливается потому что функция опроса кнопок всегда возвращает старое значение в не зависимости от нажатия. Нажатия не было, а regim опять получает старое значение, как его не меняй - 46 строка. Надо сначала проверять нажата ли кнопка и если нажата, ждать отпускания и только потом менять режим. Если не нажата, режим менять не надо.
Функция зацикливается потому что функция опроса кнопок всегда возвращает старое значение в не зависимости от нажатия. Нажатия не было, а regim опять получает старое значение, как его не меняй - 46 строка. Надо сначала проверять нажата ли кнопка и если нажата, ждать отпускания и только потом менять режим. Если не нажата, режим менять не надо.
Подскажите пожалуйста как это сделать? Получается делать f++ при отпускании кнопки?
На форуме есть титановый велосипед для кнопки - библиотека для кнопок, которая может отслеживать много событий, в том числе и отпускание. Если её использовать, то просто можно организовать алгоритм - отпустили кнопку - изменили режим, крутанули цикл. Если кнопка не нажималась, то цикл не крутим или крутим тот же самый. Главное, изменение переменной regim или после отпускания кнопки или внутри однократной функции.
Оставь все как есть, просто в конце функции каждого из остальных режимов добавь
bStopFlag=0;
Хотя у тебя тупо инкремент по нажатию со сбросом по достижению значения 3+,
Можно просто один раз записать в следующем case.
Функция зацикливается потому что функция опроса кнопок всегда возвращает старое значение в не зависимости от нажатия. Нажатия не было, а regim опять получает старое значение, как его не меняй - 46 строка. Надо сначала проверять нажата ли кнопка и если нажата, ждать отпускания и только потом менять режим. Если не нажата, режим менять не надо.
Сделал вот так, перестал слушаться кнопку на 2 режиме ))
А вообще чтоб не было затыков по коду нужно функции правильно писать.
Т.е. твоя функция buttonClick() что делает ? Инкрементирует значение переменной.
Вот и возвращать она должна не ее состояние, а указание на то, нужно инкрементировать или нет.
Иначе смысл её объявлять не как void и требовать от нее возвращать что-то ?
Если она внутри себя глобальную переменную меняет.
Блин, логично. только я сделал s = 0; т.к. стоп флаг и так уже false. Но теперь новый прикол, функция Lights4() тоже бесконечна хотя должна выполнится 1 раз. Мне вот интересно почему? я ведь переменную g инкрементирую и по сути условие больше не выполняется... Нипанятна )
Ааа... т.е. ее нужно объявить как int? )
Сделал вот так, перестал слушаться кнопку на 2 режиме ))
Он не может перестать слушаться. Он может выполнить один раз и ты это не замечаешь.
Если 4 режим тоже однократный, то и у него в конце надо regim присвоить например 10.
Тут немного не понял, пот if в loop?
Да. Ты ж проверяешь в 4 строке кнопку? а вот что делает 3 строка я не понял.
я так и не понял как это организовать в loop )
Попробуй вот так
Ссылка на библиотеку в первой строке
Не, так вообще не работает (
Не может быть. При каждом клике переменная regim меняет значение в интервале 0..3. Все, как ты и задумал. Если не работает, значит разбирайся с функциями Lights
ЗЫ: обрати внимание на комментарий в строках 23 и 24
строка 51 лишняя.
А как подключена кнопка? Разомкнутый контакт чему соответствует LOW или HIGH?
По хорошему лишняя строка 21. Я не разбирался в скетче до упора, у ТС в лупе тоже regim объявлена
А так?
Зачем?
Не нужно плодить сущности, их у ТС и так напложено (наплудено )))) овердохрена ))
В общем сделал вот так: Нашел скетч в сети и переделал немного под свой лад
Работает пока как мне нужно.
Спасибо парни за советы =)
Я смотрю, титановый лисапед для мазохистов писан )))
Я даже делал вот так. Поидее функция должна выполнится 1 раз. Но она зацикливается (
Вас не смущает, что в строках №№ 5 и 9 используется переменная i в обеих? Не то, чтобы так нельзя, но Вы точно понимаете, что делаете?
Я даже делал вот так. Поидее функция должна выполнится 1 раз. Но она зацикливается (
Вас не смущает, что в строках №№ 5 и 9 используется переменная i в обеих? Не то, чтобы так нельзя, но Вы точно понимаете, что делаете?
Так светодиоды бегут с лева направо загораясь по одному. Мне так и нужно по идее. Но не нужен вечный цикл
Имелось в виду две РАЗНЫЕ переменные с одинаковым именем
ЗЫ: строка 9 не нужна, и без нее зажженный светодиод будет отключаться
Так светодиоды бегут с лева направо загораясь по одному. Мне так и нужно по идее. Но не нужен вечный цикл
Повторяю вопрос, попробуйте внимательно прочитать: Вас не смущает, что в строках №№ 5 и 9 используется одна и та же (по имени) переменная i? Если не смущает, то я ничего - хозяин-барин.
Так светодиоды бегут с лева направо загораясь по одному. Мне так и нужно по идее.
бредятина какая... если ты зажигаешь светодиоды по одному, нафига ты каждый раз гасишь их все?
Нет, вы не поняли, они как бы пробегают по одному, с нулевого светодиода к 7 светодиоду, т.е. светодиод загорелся, погас, за ним следующий и так до конца и все... мне нужно было что бы они вот так пробежали от 0 до 7 и больше цикл не выполнялся)) Это как бы эффект отключения такой. Надеюсь я норм объяснил. Ну может я это неправильно реализовал ))
в смысле без 9 строки зажженный светодиод будет отключаться? А как контроллер поймет? Или я что то не догоняю ))). Ну хотя скорее всего я не догоняю)))))))))))))))))))
в смысле без 9 строки зажженный светодиод будет отключаться? А как контроллер поймет? Или я что то не догоняю ))). Ну хотя скорее всего я не догоняю)))))))))))))))))))
Он никак не поймет. Он сделает то, что ему указано сделать. Смотри внимательно
Какой светодиод включается? С индексом i. А какой через 200 мс выключается? Тоже с индексом i. Т.е. тот же самый. Прикинь )))
в смысле без 9 строки зажженный светодиод будет отключаться? А как контроллер поймет? Или я что то не догоняю ))). Ну хотя скорее всего я не догоняю)))))))))))))))))))
Он никак не поймет. Он сделает то, что ему указано сделать. Смотри внимательно
Какой светодиод включается? С индексом i. А какой через 200 мс выключается? Тоже с индексом i. Т.е. тот же самый. Прикинь )))
Л - Логика ))). Спасибо за подсказку. Действительно )