Прежде всего, давайте внимательно посмотрим на ваш код. Похоже, что проблема кроется в логике управления светодиодами. Также следует обратить внимание на использование функции `debounce()` и на то, как вы отслеживаете состояния светодиодов.
Вот несколько рекомендаций по исправлению вашей программы:
1. **Использование `millis()` для работы со светодиодами**: Убедитесь, что вы отслеживаете время для каждого светодиода отдельно, а не выполняете их включение по очереди в одном блоке. Необходимо добавлять логику, которая будет управлять состояниями светодиодов в зависимости от прошедшего времени.
2. **Обработка состояния кнопки**: В вашем коде нет логики, которая бы использовала значения, возвращаемые из `debounce()`. Также нет обработки состояния, при котором программа должна прекращать включать светодиоды при нажатии кнопки.
3. **Исправление функции `debounce()`**: Функция должна быть скорректирована так, чтобы возвращать текущее состояние кнопки, и её следует применять в основном цикле вашего кода.
Вот переписанный пример, который исправляет эти проблемы:
```cpp
// Зададим исходные данные для счета millis()
uint32_t tmr1, tmr2, tmr3;
const uint32_t per1 = 3000;
const uint32_t per2 = 500;
const uint32_t per3 = 1500;
// Инициализируем пины светодиода
const int RLED = 11;
const int YLED = 10;
const int GLED = 9;
// Пин кнопки
const int BUT = 2;
boolean lastBUT = LOW; // Переменная хранит предыдущее состояние кнопки
boolean currentBUT;
bool lightsOn = true; // Переменная для управления состоянием света
void setup()
{
pinMode(BUT, INPUT);
pinMode(RLED, OUTPUT);
pinMode(YLED, OUTPUT);
pinMode(GLED, OUTPUT);
}
boolean debounce() // Функция для обработки дребезга кнопки
{
boolean current = digitalRead(BUT); // Читаем кнопку
if (lastBUT != current) // Если состояние отличается
{
delay(10); // Ждем 10 мс
current = digitalRead(BUT); // Читаем кнопку еще раз
}
lastBUT = current; // Обновляем предыдущее состояние
return current; // Возвращаем актуальное состояние кнопки
}
void loop()
{
currentBUT = debounce();
if (currentBUT == HIGH) // Если кнопка нажата
{
lightsOn = !lightsOn; // Переключаем состояние света
if (!lightsOn) // Если свет выключен, все светодиоды выключаем
{
digitalWrite(RLED, LOW);
digitalWrite(YLED, LOW);
digitalWrite(GLED, LOW);
return; // Завершаем выполнение loop
}
}
if (lightsOn) {
uint32_t currentMillis = millis();
if (currentMillis - tmr1 >= per1) // Таймер для зеленого
{
digitalWrite(GLED, HIGH);
tmr1 = currentMillis;
// Выключаем другие LED
digitalWrite(RLED, LOW);
digitalWrite(YLED, LOW);
}
if (currentMillis - tmr2 >= per2) // Таймер для желтого
{
digitalWrite(YLED, HIGH);
tmr2 = currentMillis;
// Выключаем другие LED
digitalWrite(GLED, LOW);
digitalWrite(RLED, LOW);
}
if (currentMillis - tmr3 >= per3) // Таймер для красного
{
digitalWrite(RLED, HIGH);
tmr3 = currentMillis;
// Выключаем другие LED
digitalWrite(GLED, LOW);
digitalWrite(YLED, LOW);
}
}
}
```
**Изменения**:
1. Добавлена переменная `lightsOn`, чтобы отслеживать, включены ли светодиоды.
2. Исправлена логика функции `debounce()`, чтобы возвращать текущее состояние кнопки.
3. Таймеры для светодиодов обрабатываются отдельно, что позволяет использовать `millis()` для переключения между состояниями светодиодов.
Теперь светодиоды не будут включаться и выключаться одновременно, а кнопка будет должным образом управлять состоянием светофора.