// Definir pines para los LEDs de los semáforos en ambas vías
#define ROJO_VIA_1 13
#define AMARILLO_VIA_1 12
#define VERDE_VIA_1 14
#define ROJO_VIA_2 27
#define AMARILLO_VIA_2 26
#define VERDE_VIA_2 25
#define AZUL_VIA_1 16
#define AZUL_VIA_2 17
// Definir pines para los pulsadores de conteo
#define PULSADOR_VIA_1 2
#define PULSADOR_VIA_2 4
// Variables de conteo y estado
int CONTADOR_VIA_1 = 0;
int CONTADOR_VIA_2 = 0;
bool MODO_SATURADO_VIA_1 = false;
bool MODO_SATURADO_VIA_2 = false;
bool MENSAJE_VIA_1_MOSTRADO = false; // Bandera para evitar mensaje repetido de vía 1
bool MENSAJE_VIA_2_MOSTRADO = false; // Bandera para evitar mensaje repetido de vía 2
unsigned long TIEMPO_ANTERIOR = 0;
int ESTADO = 0;
void setup() {
Serial.begin(115200);
pinMode(ROJO_VIA_1, OUTPUT); pinMode(AMARILLO_VIA_1, OUTPUT); pinMode(VERDE_VIA_1, OUTPUT);
pinMode(ROJO_VIA_2, OUTPUT); pinMode(AMARILLO_VIA_2, OUTPUT); pinMode(VERDE_VIA_2, OUTPUT);
pinMode(AZUL_VIA_1, OUTPUT); pinMode(AZUL_VIA_2, OUTPUT);
pinMode(PULSADOR_VIA_1, INPUT_PULLUP); pinMode(PULSADOR_VIA_2, INPUT_PULLUP);
// Inicializar en modo normal: Vía 1 en verde, Vía 2 en rojo
digitalWrite(VERDE_VIA_1, HIGH);
digitalWrite(ROJO_VIA_2, HIGH);
TIEMPO_ANTERIOR = millis();
// Mostrar el modo inicial de cada vía una vez al inicio
mostrarModoInicial("1", MODO_SATURADO_VIA_1);
mostrarModoInicial("2", MODO_SATURADO_VIA_2);
}
void mostrarModoInicial(const char* VIA, bool MODO_SATURADO) {
Serial.print("Via ");
Serial.print(VIA);
Serial.println(MODO_SATURADO ? " en modo saturado (60 segundos)" : " en modo normal (15 segundos)");
}
void mostrarModoAlEncenderVerde(const char* VIA, bool MODO_SATURADO) {
// Mostrar mensaje solo si no se ha mostrado antes para esa vía
if ((VIA == "1" && !MENSAJE_VIA_1_MOSTRADO) || (VIA == "2" && !MENSAJE_VIA_2_MOSTRADO)) {
Serial.print("Via ");
Serial.print(VIA);
Serial.println(MODO_SATURADO ? " en modo saturado (60 segundos)" : " en modo normal (15 segundos)");
// Marcar que el mensaje ya ha sido mostrado para esa vía
if (VIA == "1") {
MENSAJE_VIA_1_MOSTRADO = true;
} else if (VIA == "2") {
MENSAJE_VIA_2_MOSTRADO = true;
}
}
}
void verificarModoSaturado(int &CONTADOR, bool &MODO_SATURADO, int LED_AZUL, const char* VIA) {
// Cambiar al modo saturado si el contador es igual o mayor a 20
bool nuevo_modo_saturado = (CONTADOR >= 20);
if (nuevo_modo_saturado != MODO_SATURADO) {
MODO_SATURADO = nuevo_modo_saturado;
digitalWrite(LED_AZUL, MODO_SATURADO ? HIGH : LOW);
Serial.print("Via "); Serial.print(VIA);
Serial.println(MODO_SATURADO ? " en modo saturado (60 segundos)" : " en modo normal (15 segundos)");
}
}
void loop() {
unsigned long TIEMPO_ACTUAL = millis();
// Leer pulsadores y actualizar contadores
if (digitalRead(PULSADOR_VIA_1) == LOW) {
CONTADOR_VIA_1++;
Serial.print("Contador Via 1: "); Serial.println(CONTADOR_VIA_1);
verificarModoSaturado(CONTADOR_VIA_1, MODO_SATURADO_VIA_1, AZUL_VIA_1, "1");
delay(200);
}
if (digitalRead(PULSADOR_VIA_2) == LOW) {
CONTADOR_VIA_2++;
Serial.print("Contador Via 2: "); Serial.println(CONTADOR_VIA_2);
verificarModoSaturado(CONTADOR_VIA_2, MODO_SATURADO_VIA_2, AZUL_VIA_2, "2");
delay(200);
}
// Definir tiempos en función del modo
int TIEMPO_VERDE_VIA_1 = MODO_SATURADO_VIA_1 ? 60000 : 15000;
int TIEMPO_VERDE_VIA_2 = MODO_SATURADO_VIA_2 ? 60000 : 15000;
int TIEMPO_AMARILLO = 3000; // Reducido a 3 segundos
// Máquina de estados para controlar los semáforos de forma exclusiva en cada vía
switch (ESTADO) {
case 0: // Vía 1 en Verde, Vía 2 en Rojo
digitalWrite(VERDE_VIA_1, HIGH); digitalWrite(ROJO_VIA_1, LOW);
digitalWrite(ROJO_VIA_2, HIGH); digitalWrite(VERDE_VIA_2, LOW); digitalWrite(AMARILLO_VIA_2, LOW);
if (TIEMPO_ACTUAL - TIEMPO_ANTERIOR >= TIEMPO_VERDE_VIA_1) {
ESTADO = 1;
TIEMPO_ANTERIOR = TIEMPO_ACTUAL;
CONTADOR_VIA_1 = 0; // Reiniciar contador de Vía 1 al finalizar el verde
digitalWrite(AZUL_VIA_1, LOW); // Apagar LED azul al cambiar a rojo
}
mostrarModoAlEncenderVerde("1", MODO_SATURADO_VIA_1); // Mostrar mensaje cuando Vía 1 enciende verde
break;
case 1: // Vía 1 en Amarillo, Vía 2 en Rojo
digitalWrite(VERDE_VIA_1, LOW); digitalWrite(AMARILLO_VIA_1, HIGH); digitalWrite(ROJO_VIA_1, LOW);
digitalWrite(ROJO_VIA_2, HIGH); digitalWrite(VERDE_VIA_2, LOW); digitalWrite(AMARILLO_VIA_2, LOW);
if (TIEMPO_ACTUAL - TIEMPO_ANTERIOR >= TIEMPO_AMARILLO) {
ESTADO = 2;
TIEMPO_ANTERIOR = TIEMPO_ACTUAL;
}
break;
case 2: // Vía 1 en Rojo, Vía 2 en Verde
digitalWrite(AMARILLO_VIA_1, LOW); digitalWrite(ROJO_VIA_1, HIGH); digitalWrite(VERDE_VIA_1, LOW);
digitalWrite(ROJO_VIA_2, LOW); digitalWrite(VERDE_VIA_2, HIGH); digitalWrite(AMARILLO_VIA_2, LOW);
if (TIEMPO_ACTUAL - TIEMPO_ANTERIOR >= TIEMPO_VERDE_VIA_2) {
ESTADO = 3;
TIEMPO_ANTERIOR = TIEMPO_ACTUAL;
CONTADOR_VIA_2 = 0; // Reiniciar contador de Vía 2 al finalizar el verde
digitalWrite(AZUL_VIA_2, LOW); // Apagar LED azul al cambiar a rojo
}
mostrarModoAlEncenderVerde("2", MODO_SATURADO_VIA_2); // Mostrar mensaje cuando Vía 2 enciende verde
break;
case 3: // Vía 1 en Rojo, Vía 2 en Amarillo
digitalWrite(ROJO_VIA_1, HIGH); digitalWrite(VERDE_VIA_1, LOW); digitalWrite(AMARILLO_VIA_1, LOW);
digitalWrite(VERDE_VIA_2, LOW); digitalWrite(AMARILLO_VIA_2, HIGH); digitalWrite(ROJO_VIA_2, LOW);
if (TIEMPO_ACTUAL - TIEMPO_ANTERIOR >= TIEMPO_AMARILLO) {
ESTADO = 0;
TIEMPO_ANTERIOR = TIEMPO_ACTUAL;
}
break;
}
}