Semáforos en Arduino… cuidado con la carretera

semaforo¿Qué pasa por ahí? Hoy la cosa por aquí esta rara rara rara. Voy a escribir un post que no es mío… qué complicado soy a veces…

La cosa es que hace poco recibí un correo de Ivanxu, un lector del blog. Ahí me pedía ayuda para hacer un proyecto con semáforos. La verdad te digo, ahí me acojoné. Me veía en Gran Vía montando semáforos o peor.. hackeándolos. Pero nada, era un ejercicio más terrenal y asequible para mí: leds.

Tras intercambiar algunos correos para ver la idea digamos que le resolví algunas dudas a Ivanxu. Nada del otro mundo la verdad, lo tenía casi todo montado. Pero a cambio me ha dejado publicar su proyecto por aquí. Igual alguien se anima a hacer algún semáforo. Bueno, en este caso son cuatro.

La idea de Ivanxu era hacer un par de semáforos con su semáforo de viandantes incluido. Es decir, un semáforo con uno más pequeño para avisar a las personas esperando en el paso de peatones que pueden o no pueden pasar. Además, quería añadirle un botón de esos que reducen el tiempo de espera y hacen que el semáforo de las personas de a pie pase a verde más rápido.

Supongo que entenderás que esto del semáforo es una forma de hablar. Al final, para replicar el proyecto de Ivanxu necesitarás 10 leds (4 verdes, 4 rojos y 2 amarillos) y dos pulsadores. Además de cables, una protoboard y tu Arduino. Si quieres darle forma de semáforo después ya es cosa tuya, yo voy a lo concreto 😉

La electrónica de los semáforos

Empezarás por la parte hardware, la electrónica. Esta parte es bastante sencilla. Al final es conectar 10 leds a la protoboard teniendo en cuenta que cada uno va en una fila (Si están en la misma línea están conectados al mismo punto y no funcionan). La fila en la que pinchemos la pata más corta del led irá conectada a GND y la otra a un pin digital que será el encargado de encender y apagar.

Ivanxu ha utilizado esta distribución, tú puedes copiarla o simplemente diseñar tu propio sistema:

Semáforo 1:
PIN 2: Led verde
PIN 3: Led amarillo
PIN 4: Led rojo
 
Semáforo 2:
PIN 5: Led verde
PIN 6: Led amarillo
PIN 7: Led rojo
 
Semáforo 3:
PIN 9: Led verde
PIN 10: Led rojo
 
Semáforo 4:
PIN 11: Led verde
PIN 12: Led rojo
Dónde semáforo 1 y semáforo 2 son los semáforos de los coches y el semáforo 3 y el 4 son los de la gente de la calle. El semáforo 3 iría unido al 1 y el 4 iría unido al 2. Por mí ya estaría conectado todo pero Ivanxu es un tío clásico, le gustan las cosas bien hechas, y ha añadido a cada led una resistencia de 220 Ohms. Esto es lo normal pero como los pines de Arduino tienen una resistencia de protección se pueden conectar los leds directamente y no pasa nada. Pero… ¡ojo! Esto solo sirve para los pines digitales, si conectas un led a el pin de 5 Voltios y a GND sin resistencia alguna… ¡y voló y yo volé con él! Empezará a oler a chamusquina y el led no se encenderá jamás.
Ahora vamos con los pulsadores. Para estos si que necesitas un par de resistencias de 10K. Para conectarlos lo que deberás hacer es meterlos en la protoboard (Fíjate que debes de ponerlos encima de la hendidura de tu protoboard para no conectar pines entre ellos y liarla parda). Después de eso, en el pin superior izquierdo o derecho conectas un cable que vaya a 5 Voltios. En la parte inferior lo que haces es conectar una resistencia de 10K que conectaras luego a GND. Luego, de la parte inferior del botón, a la altura de la resistencia, es dónde se conecta un cable que irá a un pin digital. En el caso de Ivanxu él los ha conectado al pin 8 el pulsador del semáforo 1 y 3 y al pin 13 el botón del otro semáforo.
 Digamos que el circuito de Ivanxu es éste:
circuito
fritzing
Que en la vida real ha quedado así:

circuitoreal

Cómo programar los semáforos en Arduino

Ahora vamos a la programación, que tiene miga. La idea de Ivanxu es encender los semáforos en verde, esperar un tiempo y luego pasarlos a ámbar y luego a rojo. Cuidado con esta afirmación porque es peligrosa. Para que las luces sean visibles y no cambien tan rápido que nuestros ojos no lo perciban lo que habrá que hacer es esperarse. Siempre tendremos que esperarnos tras una acción, así que eso de esperar tras el verde implica que esperaremos más, pero esperaremos todas las veces.
Bueno, ¿Y para qué el botón? El botón, si es pulsado cuando el semáforo principal está en verde se acelerará el cambio a ámbar y a rojo y con esto se encenderá antes el semáforo verde de los viandantes. Claro, porque solamente cuando el semáforo principal esté en rojo el de los viandantes se pondrá en verde y solo cuando éste se ponga en rojo se pondrá el principal en verde. Se presione o no el botón, esto sucederá. El botón simplemente acelera el proceso.
Lo que debes de hacer ahora es plantearte el programa. Lo primero que habrá que hacer será, en el setup, declarar todos los pines que tengan un led de salida y los del botón de entrada. Y luego viene el juego. Así es como lo ha programado Ivanxu:
const int boton1 = 8;
const int boton2 = 13;

char EstadoActual = 1;
int segundos=0;
int TiempoEspera[4] = {20, 5, 20, 5};

void CambiarEstado(char estado);

void setup() {
  for (int pin = 2; pin <= 7; pin++) 
    pinMode(pin, OUTPUT);
    
  for (int pin = 9; pin <= 12; pin++) 
    pinMode(pin, OUTPUT);
  
  pinMode(boton1, INPUT);
  pinMode(boton2, INPUT);
  CambiarEstado(1);
}

void loop(){

  if ((EstadoActual == 1) && (digitalRead(boton2) == true))
    TiempoEspera[0] = 10;

  if ((EstadoActual == 3) && (digitalRead(boton1) == true))
    TiempoEspera[2] = 10;
  
  delay(1000);
  segundos++;

  if (segundos > TiempoEspera[EstadoActual - 1]) {
    if (EstadoActual == 4)
      EstadoActual = 1;
    else
      EstadoActual++;
    CambiarEstado(EstadoActual);
    segundos = 0;
    TiempoEspera[0] = 20;
    TiempoEspera[2] = 20;
  }
}

void CambiarEstado(char estado) {
  switch (estado) {
    case 1:
      digitalWrite(9, LOW);
      digitalWrite(10, HIGH);

      digitalWrite(6, LOW);
      digitalWrite(7, HIGH);

      digitalWrite(12, LOW);
      digitalWrite(11, HIGH);

      digitalWrite(4, LOW);
      digitalWrite(2, HIGH);
      break;

   case 2:

      digitalWrite(2, LOW);
      digitalWrite(3, HIGH);
      break;

  case 3:
      digitalWrite(10, LOW);
      digitalWrite(9, HIGH);

      digitalWrite(7, LOW);
      digitalWrite(5, HIGH);

      digitalWrite(11, LOW);
      digitalWrite(12, HIGH);

      digitalWrite(3, LOW);
      digitalWrite(4, HIGH);
      break;

   case 4:

      digitalWrite(5, LOW);
      digitalWrite(6, HIGH);
  }
}
 Él lo que ha hecho es en el loop mirar si se ha pulsado el botón y con eso definir el tiempo que debe esperar el semáforo en verde. Y luego llamar a la función CambiarEstado que es la que se encarga de todo el tema de los semáforos encendidos y apagados. No voy a mirar el código porque me fío de Ivanxu y he visto cómo le funciona de maravilla el proyecto, pero yo lo habría hecho de otra forma. O al menos si estuviese empezando. Él ha utilizado formas de programar más avanzadas.
Que si la función que se activa según el caso, que si un bucle para poner los pines a INPUT… vamos, como un auténtico pro. Lo malo es que para ti, que eres un novatillo, te va a resultar un poco complicado de entender. Por eso yo te recomiendo que, si lo vas a hacer, te arremangues y lo hagas así.
Sabes que hay una secuencia a seguir, pues escríbete esa secuencia con tus palabras:
Encender verde y apagar rojo
Esperar
Encender ámbar y apagar verde
……
Una vez con esto, ya tienes oro en tus manos. Tan sólo debes de traducir esto. Para ello debes de saber que para encender un led deberás escribir digitalWrite(pin,HIGH) y para apagar deberás escribir digitalWrite(pin,LOW). Así de sencillo. Tan sólo debes de encender el verde y apagar el rojo y utilizar la función delay(1000) para esperar un segundo. El tiempo está en milisegundos así que cada mil milisegundos tienes un segundo.
Ten en cuenta que al empezar debes de apagar el semáforo rojo porque toda la secuencia (de los 3 semáforos) irá en un bucle y al volver deberá de estar apagado sino se te encenderá el led verde y el rojo. Por otra parte, para lo del botón, puedes utilizar este código:
 for(int i = 0; i<60 ; i++){
 
     if (digitalRead(pulsador) == true) {
      break;
    }
  }

Lo que harías sería poner esto después de encender el led verde del semáforo 1 y 3. De esta manera, si se pulsa el botón en ese tiempo de espera rápidamente se rompe el bucle (break) y sale de él para continuar con el paso a el color ámbar. Pero seguro que se te ocurre alguna otra manera. Esto es lo que le ha quedado a Ivanxu finalmente:

funcionamiento

Opt In Image

Me las piro…

Bueno, espero que si eres de esos que lleva tiempo pidiéndome algún proyecto para hacer y que me moje con este tema más o menos te des por satisfecho. El proyecto no es mío pero te lo traigo para que lo montes. Poco a poco. Si te gusta que ponga proyectos de este estilo solo tienes que dejarme un comentario ahí debajo expresando esa voluntad… 😉

[Total:6    Promedio:4.8/5]

Déjame un comentario que en el fondo soy buen chaval

  1. Dan

    Responder

    • Responder

      • Dan

        Responder

        • Responder

  2. Sera

    Responder

  3. Juan Andrés

    Responder

    • Responder

      • Juan Andrés

        Responder

        • Responder

  4. Ivanxu

    Responder

Deja un comentario