//Se asignan los números de pines correspondientes a las luces led
int pinRojoAuto = 11;
int pinAmarilloAuto = 12;
int pinVerdeAuto = 13;
int pinRojoPeaton = 2;
int pinAmarilloPeaton = 3;
int pinVerdePeaton = 4;
//Se asgina el pin del botón
int pinBoton = 7;
//Se configuran los tiempos de duración para el semáforo de los automóviles
int tiempoAuto = 30;
//Se configuran los tiempos de duración para el semáforo de los peatones
int tiempoPeaton = 15;
//Se configura cuánto tiempo durará el color amarillo en los semáforos
int tiempoAmarillo = 3;
//Se crea una variable para determinar si es turno de los automóviles o no
bool turnoAuto;
//Se crea una varible para llevar el conteo del tiempo restante para cambiar de turno
int timer;
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
//Se asigna el modo de salida para las luces led
pinMode(pinRojoAuto, OUTPUT);
pinMode(pinAmarilloAuto, OUTPUT);
pinMode(pinVerdeAuto, OUTPUT);
pinMode(pinRojoPeaton, OUTPUT);
pinMode(pinAmarilloPeaton, OUTPUT);
pinMode(pinVerdePeaton, OUTPUT);
//Se asigna el modo de entrada para el botón
pinMode(pinBoton, INPUT_PULLUP);
//Se inicializa con el turno del auto primero
turnoAuto = true;
resetTimer();
}
void loop() {
// put your main code here, to run repeatedly:
Serial.println(timer);
//Se lee el valor del botón
readButton();
//Se actualiza el turno del carro si es necesario
calculateAutoTurn();
//Actualiza las luces led del semáforo de automóviles
processAutoLeds();
//Actualiza las luces led del semáforo de peatones
processPeatonLeds();
//Se actualiza el tiempo restante
timer--;
//Se agrega un tiempo de espera de un segundo para el siguiente ciclo
//Debido a esto, el botón se tiene que mantener presionado hasta que pase el siguiente ciclo
delay(1000);
}
//Función para reiniciar el contador de tiempo
void resetTimer() {
//Se toma el timpo según el turno actual
if(turnoAuto) {
timer = tiempoAuto;
}
else {
timer = tiempoPeaton;
}
}
//Función para la lectura del botón
void readButton() {
//Se valida si el botón está presionado
if(digitalRead(pinBoton) == LOW) {
Serial.println("Boton presionado");
//Se estima el nuevo tiempo a asignar al timer del tiempo restante a un segundo antes de cambiar a amarillo
int tiempoNuevo = tiempoAmarillo + 1;
//Se valida si es el turno del auto y si el tiempo restante es mayor al tiempo calculado
//La segunda validación evita que el tiempo sea actualizado aún cuando ya se actualizó anteriormente
if(turnoAuto && timer > tiempoNuevo) {
//Si la condición es verdadera, entonces se actualiza el tiempo restante
timer = tiempoNuevo;
}
}
}
//Se calcula si es turno del automóvil o no
void calculateAutoTurn() {
//Si el tiempo del semáforo se acabó, se procede a validar cuál es el siguiente turno
if(timer <= 0) {
//Se actualiza el turno y se reinicia el conteo del timer
turnoAuto = !turnoAuto;
resetTimer();
}
}
//Función para actualizar las luces led del semáforo de automóviles
void processAutoLeds() {
//La luz roja estará encendida una vez no sea turno del automóvil
bool redOn = !turnoAuto;
//La luz amarilla estará encendida cuando el turno sea del automóvil y
//se encuentre dentro del rango de tiempo que la luz amarilla debe estar encendida
bool yellowOn = turnoAuto && timer <= tiempoAmarillo;
//La luz verde estará encendida cuando el turno sea del automóvil y
//se encuentre fuera del rango de tiempo que la luz amarilla debe estar encendida
bool greenOn = turnoAuto && timer > tiempoAmarillo;
//Se actualiza el valor de las luces
if(redOn) {
digitalWrite(pinRojoAuto, HIGH);
}
else {
digitalWrite(pinRojoAuto, LOW);
}
if(yellowOn) {
digitalWrite(pinAmarilloAuto, HIGH);
}
else {
digitalWrite(pinAmarilloAuto, LOW);
}
if(greenOn) {
digitalWrite(pinVerdeAuto, HIGH);
}
else {
digitalWrite(pinVerdeAuto, LOW);
}
}
//Función para actualizar las luces led del semáforo de peatones
void processPeatonLeds() {
//La luz roja estará encendida una vez sea turno del automóvil
bool redOn = turnoAuto;
//La luz amarilla estará encendida cuando el turno no sea del automóvil y
//se encuentre dentro del rango de tiempo que la luz amarilla debe estar encendida
bool yellowOn = !turnoAuto && timer <= tiempoAmarillo;
//La luz verde estará encendida cuando el turno no sea del automóvil y
//se encuentre fuera del rango de tiempo que la luz amarilla debe estar encendida
bool greenOn = !turnoAuto && timer > tiempoAmarillo;
//Se actualiza el valor de las luces
if(redOn) {
digitalWrite(pinRojoPeaton, HIGH);
}
else {
digitalWrite(pinRojoPeaton, LOW);
}
if(yellowOn) {
digitalWrite(pinAmarilloPeaton, HIGH);
}
else {
digitalWrite(pinAmarilloPeaton, LOW);
}
if(greenOn) {
digitalWrite(pinVerdePeaton, HIGH);
}
else {
digitalWrite(pinVerdePeaton, LOW);
}
}