#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// Dirección I2C común: 0x27 o 0x3F. Ajusta según tu módulo.
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Definición de pines para los LEDs
const int pinRojo = 8;
const int pinAmarillo = 9;
const int pinVerde = 10;
// Tiempos de duración para cada fase (en segundos)
const int tiempoVerde = 10;
const int tiempoAmarillo = 3;
const int tiempoRojo = 12;
// Variables de control de estado
enum EstadoSemaforo { VERDE, AMARILLO, ROJO };
EstadoSemaforo estadoActual = VERDE;
unsigned long tiempoPrevio = 0;
const unsigned long intervaloUnSegundo = 1000; // 1000 milisegundos = 1 segundo
int tiempoRestante = tiempoVerde;
void setup() {
// Configurar pines de los LEDs como salidas
pinMode(pinRojo, OUTPUT);
pinMode(pinAmarillo, OUTPUT);
pinMode(pinVerde, OUTPUT);
// Inicializar la pantalla LCD
lcd.init();
lcd.backlight();
// Encender el primer estado
actualizarLuces();
actualizarPantalla();
}
void loop() {
unsigned long tiempoActual = millis();
// Ejecutar el bloque de código de forma exacta cada 1 segundo
if (tiempoActual - tiempoPrevio >= intervaloUnSegundo) {
tiempoPrevio = tiempoActual;
tiempoRestante--;
// Si el temporizador llega a cero, cambia de estado
if (tiempoRestante < 0) {
cambiarDeEstado();
}
actualizarPantalla();
}
}
void cambiarDeEstado() {
switch (estadoActual) {
case VERDE:
estadoActual = AMARILLO;
tiempoRestante = tiempoAmarillo;
break;
case AMARILLO:
estadoActual = ROJO;
tiempoRestante = tiempoRojo;
break;
case ROJO:
estadoActual = VERDE;
tiempoRestante = tiempoVerde;
break;
}
actualizarLuces();
}
void actualizarLuces() {
// Apagar todas las luces primero
digitalWrite(pinRojo, LOW);
digitalWrite(pinAmarillo, LOW);
digitalWrite(pinVerde, LOW);
// Encender solo el LED del estado activo
switch (estadoActual) {
case VERDE:
digitalWrite(pinVerde, HIGH);
break;
case AMARILLO:
digitalWrite(pinAmarillo, HIGH);
break;
case ROJO:
digitalWrite(pinRojo, HIGH);
break;
}
}
void actualizarPantalla() {
lcd.setCursor(0, 0);
// Mostrar el nombre del estado actual centrado
switch (estadoActual) {
case VERDE:
lcd.print("SEMAFORO: VERDE ");
break;
case AMARILLO:
lcd.print("SEMAFORO: AMARIL");
break;
case ROJO:
lcd.print("SEMAFORO: ROJO ");
break;
}
// Mostrar el tiempo restante en la segunda fila
lcd.setCursor(0, 1);
lcd.print("Cambio en: ");
lcd.print(tiempoRestante);
lcd.print("s "); // Espacios vacíos al final para borrar caracteres viejos
}