Доброе утро! Задача: моргать светодиодом в разных режимах (горение, быстрое моргание, долгое моргание, несколько морганий и др.) Спойлер: Код Код (C++): #define BTN_LED 6 int req; // Light int bblink; // Режим мерцания кнопки int bled; // Запись состояния Button LED (HIGH / LOW) unsigned long timer; // Таймер Blink Button int tb; // Счетчик включений bool block; // Блокировка в цикле режима кнопки #5 (защита от флуда в Serial) void ledbtn_mode(int sd) { // 1 - свечение / 2 - выключение / 3 - blink mode / 4 - error blink mode switch (sd) { case 1: // Включение светодиода кнопки if(bblink != 1) { digitalWrite(BTN_LED, HIGH); // Включаем светодиод bblink = 1; // Записываем режим } break; case 2: // Выключение светодиода кнопки if(bblink != 2) { digitalWrite(BTN_LED, LOW); // Выключаем светодиод bblink = 2; // Записываем режим } break; case 3: // Blink Mode if(bblink != 3) { tb = 0; timer = millis(); // Записываем текущее время bblink = 3; // Запускаем режим мерцания } break; case 4: // Error Blink Mode if(bblink != 4) { tb = 0; timer = millis(); bblink = 4; } break; case 5: // Кнопка зажата, моргнем несколько раз if(bblink != 5) { block = false; // Сброс блокировки tb = 0; timer = millis(); bblink = 5; // Запуск режима } break; case 6: // Постоянное моргание if(bblink != 6) { tb = 0; timer = millis(); bblink = 6; } break; } } void setup() { Serial.begin(115200); pinMode(BTN_LED, OUTPUT); pinMode(13, OUTPUT); digitalWrite(BTN_LED, HIGH); delay(500); digitalWrite(BTN_LED, LOW); delay(500); digitalWrite(BTN_LED, HIGH); digitalWrite(13, LOW); } void loop() { if(Serial.available() > 0) { req = Serial.parseInt(); } if(req == 10) { //digitalWrite(BTN_LED, LOW); ledbtn_mode(1); } else if(req == 15) { //digitalWrite(BTN_LED, HIGH); ledbtn_mode(2); } else if(req == 20) { ledbtn_mode(3); } else if(req == 25) { ledbtn_mode(4); // Проблемный режим } else if(req == 30) { ledbtn_mode(5); // Проблемный режим } else if(req == 35) { ledbtn_mode(6); } if(bblink == 5) { digitalWrite(13, HIGH); } else { digitalWrite(13, LOW); } // Btn Blink Mode (#3) - Все ок if(bblink == 3) { if((millis() - timer) >= 500) { if(digitalRead(BTN_LED) == HIGH) { bled = LOW; } else { bled = HIGH; } digitalWrite(BTN_LED, bled); timer = millis(); } } // Error Blink Mode Btn (#4) - Проблема со сбросом режима if(bblink == 4) { // Моргнем три раза if(tb <= 6 && (millis() - timer) >= 150) { if(digitalRead(BTN_LED) == HIGH) { bled = LOW; } else { bled = HIGH; } digitalWrite(BTN_LED, bled); tb++; timer = millis(); } else if(tb >= 6) { digitalWrite(BTN_LED, HIGH); } } // Blink Mode (#5) - Проблема со сбросом режима if(bblink == 5) { // Моргнем три раза if(tb < 6 && (millis() - timer) >= 500) { if(digitalRead(BTN_LED) == HIGH) { bled = LOW; } else { bled = HIGH; } digitalWrite(BTN_LED, bled); tb++; timer = millis(); } else if(tb >= 6 && block == false) { Serial.println("<320>"); if(digitalRead(BTN_LED) == LOW) { digitalWrite(BTN_LED, HIGH); } block = true; } } // Постоянное моргание if(bblink == 6) { if((millis() - timer) >= 1500) { if(digitalRead(BTN_LED) == HIGH) { bled = LOW; } else { bled = HIGH; } digitalWrite(BTN_LED, bled); timer = millis(); } } } Я отправляю определенное число в Serial (10 / 15 / 20 / 25 / 30 / 35) и в соответствии с ним запускается нужный режим работы светодиода. Проблемы возникли в двух режимах (Режим №4 - Число 25 и Режим №5 - Число 30). В этих режимах светодиод должен моргнуть несколько раз (до переполнения счетчика) и после встать в обычный режим горения. Это работает, но ровно 1 раз. Если я повторно введу число вызова любого из этих режимов - ничего не произойдет. Это означает, что после переполнения счетчика переменная bblink не выходит из своего режима. Пример: - Ввожу в Serial число 30 - светодиод моргнет пару раз. Вроде все хорошо. - Пробую ввести снова число 30 - ничего не происходит. Но. Если после срабатывания режима я запущу другой, то этот режим снова можно будет запустить. Это означает, что переменная bblink сброшена. Я попробовал по окончанию цикла моргания сбросить переменную bblink, отвечающую за номер режима: Спойлер: Исправление Код (C++): // Blink Mode (#5) - Проблема со сбросом режима if(bblink == 5) { // Моргнем три раза if(tb < 6 && (millis() - timer) >= 500) { if(digitalRead(BTN_LED) == HIGH) { bled = LOW; } else { bled = HIGH; } digitalWrite(BTN_LED, bled); tb++; timer = millis(); } else if(tb >= 6 && block == false) { Serial.println("<320>"); if(digitalRead(BTN_LED) == LOW) { digitalWrite(BTN_LED, HIGH); } bblink = 0; block = true; } } Код (C++): bblink = 0; Теперь светодиод моргает постоянно. В чем ошибка?
Не понял. Куда вы вставили сброс bblink? Кажется, что не в окончание цикла, а просто после кода, который отвечает за цикл.
а что этот кусок кода делает, вне всех циклов? Мне кажется, что после case нет смысла проверять bblink if-ом. Вы тут задаёте начальные условия для цикла. Скажите, что делает block? Это избыточно, у вас и так есть проверка tb (счетчик горения). Так как у вас tb инкрементируется независимо от состояния светодиода, то миганий получается 3, да? прочитал коментарии) Какому режиму соответсвует bblink=0? Может, приравнять 1? Прошу, выложите, пожалуйста, код после правок (если они будут и не помогут) ещё раз целиком.
Я бы порекомендовал ещё не играть с bblink-ом вне процедуры ledbtn_mode, т.е. если нужно переключить режим мерцания, то вызывать процедуру ledbtn_mode с другим режимом. Она задает нач. положения переменных, о которых вы можете забыть