Descripción
Este proyecto implementa un semáforo para dos calles (N-S y E-W) con control inteligente: tiempos dinámicos controlados por sensores de presencia (por ejemplo sensores IR/ultrasonido) y botón peatonal que solicita cruce. Diseño no bloqueante con millis().
Materiales
Ir a la Tienda- Arduino UNO (o compatible)
- LEDs: 4 x Rojo/Amarillo/Verde (12 LEDs) o 2 conjuntos para cada dirección
- Resistencias 220Ω para LEDs
- Sensores de presencia: 2 x HC-SR04 / sensores IR / sensores de presión
- Botón peatonal (push button) con resistencia pull-down
- Cables y protoboard
- Buzzer (opcional) para señal acústica peatonal
Resumen de pines (ejemplo)
| NS - Rojo | D2 |
| NS - Amarillo | D3 |
| NS - Verde | D4 |
| EW - Rojo | D5 |
| EW - Amarillo | D6 |
| EW - Verde | D7 |
| Sensor NS | A0 |
| Sensor EW | A1 |
| Botón peatonal | D8 |
| Buzzer | D9 |
Código Arduino (sube al IDE)
// SemaforoInteligente.ino
// Semáforo N-S / E-W con sensores y botón peatonal (no bloqueante)
// Pines LEDs
const int NS_ROJO = 2;
const int NS_AMAR = 3;
const int NS_VERDE = 4;
const int EW_ROJO = 5;
const int EW_AMAR = 6;
const int EW_VERDE = 7;
// Pines sensores / entrada
const int SENSOR_NS = A0; // analogico (puede ser digital si usas PIR/IR)
const int SENSOR_EW = A1;
const int BOTON_PEATON = 8; // input with pullup or pulldown
const int BUZZER = 9;
// Umbrales y tiempos (ms)
int umbralSensor = 300; // ajustar según sensor
unsigned long verdeMin = 8000; // 8s mínimo verde
unsigned long verdeMax = 20000; // 20s máximo verde
unsigned long amarTiempo = 3000; // 3s amarillo
// Estado del semaforo
enum Fase {NS_VERDE, NS_AMARILLO, EW_VERDE, EW_AMARILLO};
Fase fase = NS_VERDE;
unsigned long faseInicio = 0;
unsigned long faseDuracion = 0;
void setup(){
Serial.begin(9600);
// LEDs
pinMode(NS_ROJO, OUTPUT); pinMode(NS_AMAR, OUTPUT); pinMode(NS_VERDE, OUTPUT);
pinMode(EW_ROJO, OUTPUT); pinMode(EW_AMAR, OUTPUT); pinMode(EW_VERDE, OUTPUT);
// Entradas
pinMode(BOTON_PEATON, INPUT_PULLUP); // boton a GND cuando presionado
pinMode(BUZZER, OUTPUT);
// Iniciar estado
fase = NS_VERDE;
faseInicio = millis();
faseDuracion = verdeMin;
aplicarFase(fase);
}
void loop(){
unsigned long now = millis();
// Leer sensores (no bloqueante)
int lecturaNS = analogRead(SENSOR_NS);
int lecturaEW = analogRead(SENSOR_EW);
bool boton = (digitalRead(BOTON_PEATON) == LOW); // activo bajo
// Ajustar duración de verde según presencia: si hay tráfico en EW y poco en NS, darle más tiempo a EW
if(fase == NS_VERDE){
unsigned long dur = map(lecturaEW, 0, 1023, (int)verdeMin, (int)verdeMax);
// Si botón peatonal apretado, acortar si es necesario para permitir cruce pronto
if(boton) dur = min(dur, 10000UL); // cede antes (ejemplo)
faseDuracion = constrain(dur, verdeMin, verdeMax);
}
if(fase == EW_VERDE){
unsigned long dur = map(lecturaNS, 0, 1023, (int)verdeMin, (int)verdeMax);
if(boton) dur = min(dur, 10000UL);
faseDuracion = constrain(dur, verdeMin, verdeMax);
}
// Verificar cambio de fase
if(now - faseInicio >= faseDuracion){
// avanzar fase
if(fase == NS_VERDE) cambiarFase(NS_AMARILLO, amarTiempo);
else if(fase == NS_AMARILLO) cambiarFase(EW_VERDE, verdeMin);
else if(fase == EW_VERDE) cambiarFase(EW_AMARILLO, amarTiempo);
else if(fase == EW_AMARILLO) cambiarFase(NS_VERDE, verdeMin);
}
// Señal acústica cuando está activo el cruce peatonal (opcional)
if(boton && (fase == NS_AMARILLO || fase == EW_AMARILLO)){
// para indicar que boton fue registrado
tone(BUZZER, 1000, 200);
}
}
void cambiarFase(Fase nueva, unsigned long dur){
fase = nueva;
faseInicio = millis();
faseDuracion = dur;
aplicarFase(fase);
}
void aplicarFase(Fase f){
// Apagar todo primero
digitalWrite(NS_ROJO, LOW); digitalWrite(NS_AMAR, LOW); digitalWrite(NS_VERDE, LOW);
digitalWrite(EW_ROJO, LOW); digitalWrite(EW_AMAR, LOW); digitalWrite(EW_VERDE, LOW);
if(f == NS_VERDE){
digitalWrite(NS_VERDE, HIGH);
digitalWrite(EW_ROJO, HIGH);
} else if(f == NS_AMARILLO){
digitalWrite(NS_AMAR, HIGH);
digitalWrite(EW_ROJO, HIGH);
} else if(f == EW_VERDE){
digitalWrite(EW_VERDE, HIGH);
digitalWrite(NS_ROJO, HIGH);
} else if(f == EW_AMARILLO){
digitalWrite(EW_AMAR, HIGH);
digitalWrite(NS_ROJO, HIGH);
}
}
Este sketch es ejemplo. Ajusta umbralSensor, pines y lógica según los sensores que uses (ultrasonido necesita trig/echo).
Consejos y mejoras
- Agregar detección de peatones con botón y temporizador específico de cruce con señal sonora y contador.
- Usar comunicación entre semáforos para coordinar múltiples intersecciones (I2C, RS485 o RF).
- Agregar pantalla OLED para mostrar estados y cuenta regresiva de cruce peatonal.
- Implementar prioridad para vehículos de emergencia (botón remoto o sensor).
- Usar ESP32 + Wi‑Fi para enviar telemetría y ajustar tiempos desde web.
Pruebas y calibración
Prueba cada LED por separado, comprueba que los sensores devuelvan valores esperados (usa Serial.println). Ajusta verdeMin/Max y umbrales después de medir tráfico real.
Donaciones Aquí