Semáforo Inteligente con Arduino

Tutorial paso a paso: semáforo para intersección con prioridad peatonal y tiempos adaptativos según sensores.

Donaciones Aquí

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 - RojoD2
NS - AmarilloD3
NS - VerdeD4
EW - RojoD5
EW - AmarilloD6
EW - VerdeD7
Sensor NSA0
Sensor EWA1
Botón peatonalD8
BuzzerD9

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.

Libros y Articulos recomendados

Recursos recomendados:

⬅ Ir a pagina de Biblioteca

Catalogo de proyectos

Recursos recomendados:

⬅ Ir a pagina de CATALOGO