Моделирование светофора: небольшое сомнение
Я пытаюсь смоделировать светофор с кнопкой для пешеходов, нажатие на которую останавливает движение на некоторое время. Вот условия, которые я пытаюсь выполнить,
Один зеленый светодиод (на контакте 10) загорелся на 3 секунды (первый загоревшийся светодиод). - Затем один оранжевый светодиод (на контакте 11) загорается на 1 секунду - Затем, наконец, один красный светодиод (на выводе 12) загорелся на 3 секунды.
Двухцветный свет (пешеходный) - Пешеходный светофор постоянно горит красным цветом (красный светодиод на выводе 9) и становится зеленым (светодиод на выводе 8) только после нажатия кнопки (на выводе 2).
При нажатии кнопки Если кнопка нажата, когда на светофоре автомобиля горит зеленый свет, оранжевый свет загорается на 1 секунду, затем автомобиль свет загорается красным на 5 секунд, в течение которых горит зеленый пешеходный свет зеленый.
После этих 5 секунд пешеходный светофор снова загорается красным, и возобновляется нормальное функционирование (автомобильный светофор снова загорается зеленым)
А вот мой код для того же самого,
int status=0; //mode:состояние контакта кнопки
int buttonpin=2;//контакт, связанный с кнопкой
void setup(){
pinMode(10,OUTPUT); //Зеленый светодиод на pin10
pinMode(11,OUTPUT); //Оранжевый светодиод на вывод 11
pinMode(12,OUTPUT); //Красный светодиод на вывод 12
pinMode(9,OUTPUT); // Пешеходный красный на контакте 9
pinMode(8,OUTPUT); //Пешеходный зеленый на выводе 8
}
void loop(){
digitalWrite(9,HIGH);//Включен красный свет для пешеходов
status=digitalRead(buttonpin);
if (status==HIGH){
digitalWrite(9,LOW); //красный для пешеходов выключен
digitalWrite(8,HIGH); //Включен зеленый для пешеходов
digitalWrite(11,HIGH);//загорается оранжевый
delay(1000);//задержка в 1 секунду
digitalWrite(11,LOW);//оранжевый выключен);
digitalWrite(12,HIGH);//красный начинает
delay(5000);//5 секунд задержки
digitalWrite(12,LOW);
digitalWrite(9,HIGH);
}
else{
digitalWrite(10,HIGH);//загорается зеленый
delay(3000);//3 секунды задержки
digitalWrite(10,LOW);//зеленый отключается
digitalWrite(11,HIGH);//загорается оранжевый
delay(1000);//задержка в 1 секунду
digitalWrite(11,LOW);//оранжевый выключен);
digitalWrite(12,HIGH);//красный начинает
delay(3000);
digitalWrite(12,LOW);//красный выключается
}
}
Проблема в том, что кнопка для пешеходов срабатывает только в том случае, если она уже нажата в момент включения зеленого сигнала светофора (из-за цикла if в коде), но как только зеленый сигнал светофора уже горит, скажем, 1,5 секунды, она не сработает, поскольку проверка условия цикла if уже была пройдена. Как мне исправить свой код, чтобы последовательность «При нажатии кнопки», описанная выше, работала в любое время, когда зеленый светодиод горит ВЫСОКИМ светом?
Прилагается схема, если необходимо.
Отредактированный код:
#include <TimerOne.h>
int status=0; //mode:state of button pin
int buttonpin=2;//контакт, связанный с кнопкой
void setup(){
pinMode(10,OUTPUT);
pinMode(11,OUTPUT);
pinMode(12,OUTPUT);
pinMode(9,OUTPUT);
pinMode(8,OUTPUT);
Timer1.initialize(100000);
Timer1.attachInterrupt( buttonCheck );
}
void loop(){
digitalWrite(9,HIGH);
status=digitalRead(buttonpin);
digitalWrite(10,HIGH);//загорается зеленый
delay(3000);//3 секунды задержки
digitalWrite(10,LOW);//зеленый отключается
digitalWrite(11,HIGH);//загорается оранжевый
delay(1000);//задержка в 1 секунду
digitalWrite(11,LOW);//оранжевый выключен);
digitalWrite(12,HIGH);//красный начинает
delay(3000);
digitalWrite(12,LOW);//красный выключается
}
void buttonCheck(){
if (status==HIGH){
digitalWrite(9,LOW);
digitalWrite(8,HIGH);
digitalWrite(11,HIGH);//загорается оранжевый
delay(1000);//задержка в 1 секунду
digitalWrite(11,LOW);//оранжевый выключен);
digitalWrite(12,HIGH);//красный начинает
delay(5000);//5 секунд задержки
digitalWrite(12,LOW);
digitalWrite(9,HIGH);
return;
}
}
Это сработает?
@Kv07, 👍-1
1 ответ
Лучший ответ:
Причина проблемы в том, как вы реализовали delay()
в своем эскизе. Это правда, что delay()
следует избегать в 99,9% случаев, но у него есть свои применения.
Если вы начнете с примера BlinkWithoutDelay, который поставляется с Arduino IDE, а затем добавите переменную-счетчик и оператор switch, вы легко сможете заставить работать «часть» ваших требований, связанную со светофорами.
Добавить функционал пешеходной кнопки с использованием неблокирующего кода сложнее (для меня это сложнее), но это проблема, легко решаемая с помощью delay()
.
Но что, если вы когда-нибудь захотите, чтобы ваш эскиз делал больше? Что произойдет, если вы добавите в него еще одну кнопку? delay()
— это «блокирующий» код, поэтому его использование, вероятно, снова «укусит» вас, если вы попытаетесь добавить функциональность в этот эскиз.
const byte buttonPin = 2;
byte secondsCounter = 0;
byte trafficLightState = 0;
unsigned long oneSecond = 1000;
unsigned long previousMillis = 0;
void setup(){
pinMode(10, OUTPUT); // Зеленый светодиод на вывод 10
pinMode(11, OUTPUT); // Оранжевый светодиод на вывод 11
pinMode(12, OUTPUT); // Красный светодиод на вывод 12
pinMode(9, OUTPUT); // Пешеходный красный на контакте 9
pinMode(8, OUTPUT); // Зеленый для пешеходов на выводе 8
// Я использовал провод от GND к "buttonPin" в качестве переключателя.
pinMode(buttonPin, INPUT_PULLUP);
Serial.begin(9600);
}
void loop(){
// Получить текущее время.
unsigned long currentMillis = millis();
// Если кнопка нажата, когда на светофоре горит зеленый свет,
// оранжевый свет горит 1 секунду, затем фары автомобиля выключаются
// красный в течение 5 секунд, в течение которых горит зеленый свет для пешеходов.
if(trafficLightState == 0 && digitalRead(buttonPin) == LOW){
digitalWrite(10, LOW);
digitalWrite(11, HIGH);
digitalWrite(12, LOW);
digitalWrite(9, HIGH);
digitalWrite(8, LOW);
Serial.println("Button Pressed. Orange light ON for 1 second, Pedestrian red ON.");
delay(1000);
digitalWrite(11, LOW);
digitalWrite(12, HIGH);
digitalWrite(9, LOW);
digitalWrite(8, HIGH);
Serial.println("Red light ON for 5 seconds, Pedestrian green ON.");
delay(5000);
digitalWrite(11, HIGH);
digitalWrite(12, LOW);
digitalWrite(9, HIGH);
digitalWrite(8, LOW);
Serial.println("Pedestrian red ON.");
trafficLightState = 0;
secondsCounter = 0;
currentMillis = millis();
}
// Обновлять состояние светофора каждую секунду.
if(oneSecondTimer(oneSecond, currentMillis) == 1){
secondsCounter += 1;
if(secondsCounter > 7){secondsCounter = 1;}
// Зеленый свет светофора.
if(secondsCounter == 1){
trafficLightState = 0;
Serial.println("Green traffic light ON for 3 seconds");
}
// Оранжевый светофор.
else if(secondsCounter == 4){
trafficLightState = 1;
Serial.println("Orange traffic light ON for 1 second");
}
// Красный свет светофора.
else if(secondsCounter == 5){
trafficLightState = 2;
Serial.println("Red traffic light ON for 3 seconds");
}
}
// Включайте/выключайте светофоры по мере необходимости.
switch(trafficLightState){
// Включить зеленый свет светофора и красный свет для пешеходов.
case 0:
digitalWrite(10, HIGH);
digitalWrite(11, LOW);
digitalWrite(12, LOW);
digitalWrite(9, HIGH);
digitalWrite(8, LOW);
break;
// Включить оранжевый сигнал светофора и красный сигнал для пешеходов.
case 1:
digitalWrite(10, LOW);
digitalWrite(11, HIGH);
digitalWrite(12, LOW);
digitalWrite(9, HIGH);
digitalWrite(8, LOW);
break;
// Включи красный свет светофора, пешеходный красный свет.
case 2:
digitalWrite(10, LOW);
digitalWrite(11, LOW);
digitalWrite(12, HIGH);
// Зеленый свет для пешеходов ВКЛЮЧЕН ТОЛЬКО если кнопка была
// нажал, когда на светофоре горел зеленый свет.
// digitalWrite(9, НИЗКИЙ);
// digitalWrite(8, HIGH);
break;
}
}
byte oneSecondTimer(unsigned long delayTime, unsigned long currentMillis){
if(currentMillis - previousMillis >= delayTime){previousMillis = currentMillis;return 1;}
else{return 0;}
}
- Питание светодиодной ленты - Сколько ампер?
- Несколько условий оператора if
- Светодиоды: разница между общим анодом и общим катодом
- Светодиод L продолжает гореть
- Улучшенное циклическое переключение цветов RGB.
- Плавное мигание светодиодов
- Остановить мигание светодиодов
- FastLED - Как управлять определенными светодиодами