Cómo controlar el semáforo usando un botón y la función millis() (Previsualizar)

sketch Arduino ejemplo millis
Primero debes completar Parpadeo del semáforo de peatones con un bucle for() antes de ver esta lección

Cuando pulsamos el botón, automáticamente el semáforo de coches cambia de verde a rojo y el de peatones de rojo a verde. Pero, ¿qué ocurre si el semáforo de coches se acaba de poner en verde? Si nos ponemos en el lugar del peatón, sería un semáforo ideal, pues solo tenemos que llegar, pulsar y cruzar. Pero si somos conductores, el semáforo mola menos, ¿verdad?

¿Cómo funcionan los semáforos que cruzamos cada día andando o en coche?

En la vía hay varios actores, entre ellos, conductores y peatones. Suponemos que somos un peatón y llegamos a un semáforo que está en rojo. ¿Qué hacemos? Pulsamos el botón. ¿Qué ocurre? Pueden ocurrir dos cosas: (1) Que el semáforo cambie casi de forma inmediata a verde. (2) Que tengamos que esperar un poco antes de que el semáforo pase de rojo a verde.

¿De qué depende que se dé la situación 1 o 2? El factor que determina que nos encontremos ante una u otra situación podríamos decir que es la suerte. Pero no, depende del tiempo que hace que el semáforo de peatones estuvo en verde, o lo que es lo mismo, cuánto tiempo lleva el semáforo de los coches en verde.

¿Cómo medidos el tiempo?

Usar la función millis() es genial cuando necesiamos contar el tiempo.

millis() nos devuelve el número de milisegundos que han pasado desde que le damos a subir en Arduino IDE el último programa. Este número vuelve a ser cero cuando pasan 50 días aproximadamente.

¿Cómo implementamos este sistema en Arduino para nuestro semáforo?

Ya tenemos el circuito del semáforo montado, ¿verdad? Recordamos que el esquema de conexiones era este:

Esquema de conexion LEDs y boton con Arduino

Para conocer cúanto tiempo lleva el semáforo de coches en verde, necesitamos dos variables: (1) El tiempo actual, que sería cómo preguntar a Arduino qué hora es. (2) El tiempo anterior, que sería cómo preguntar a Arduino qué hora era cuando se pulsó el botón la última vez.

Como el número que nos devuelve la función millis() es un unsigned long, lo ideal es almacenar su valor en una variable del mismo tipo, evitando de esta forma pérdidas de datos. Para realizar operaciones matemáticas con el valor de millis() debemos de hacerlo con variables de mismo tipo, pues realizar una operación aritmética usando una variable unsigned long y un valor pequeño guardado en una variable de tipo int puede generar errores en los resultados.

Vamos a ir haciéndolo:

En primer lugar, debemos de crear las variables constantes que contienen el número de pin al que hemos conectado cada uno de los componentes:

  const int LED_ROJO_COCHE = 13;
  const int LED_AMBAR_COCHE = 11;
  const int LED_VERDE_COCHE = 9;
  const int LED_ROJO_PEATON = 7;
  const int LED_VERDE_PEATON = 5;
  const int BOTON = 2;

Además, necesitamos conocer si el botón está pulsado o relajado. Por ello, creamos una variable te tipo int donde almacenamos el estado del botón:

  int estadoBoton = 0;

Aquí viene lo importante, necesitamos saber el tiempo cuando pulsamos el botón (tiempoActual) y el tiempo cuando se pulsó el botón la última vez (tiempoAnterior). Como hemos dicho, estas variables serán de tipo unsigned long y las inicializamos en 0, esto último no es necesario:

  unsigned long tiempoActual = 0;
  unsigned long tiempoAnterior = 0;

Pasamos a la función void setup(). Aquí inicializamos tanto los LEDs como el botón:

  pinMode(LED_ROJO_COCHE, OUTPUT);
  pinMode(LED_AMBAR_COCHE, OUTPUT);
  pinMode(LED_VERDE_COCHE, OUTPUT);
  pinMode(LED_ROJO_PEATON, OUTPUT);
  pinMode(LED_VERDE_PEATON, OUTPUT);
  pinMode(BOTON, INPUT);

En la función void loop() programamos cómo queremos que funcione nuestro semáforo. Veámoslo por partes:

Primero, pondremos el estado del semáforo que querramos que esté por defecto. El que yo he elegido es el semáforo de coches en verde y, por tanto, para evitar accidentes, el de peatones en rojo:

  digitalWrite(LED_VERDE_COCHE, HIGH);
  digitalWrite(LED_ROJO_PEATON, HIGH);

Lo siguiente que debemos hacer es comprobar si el botón ha sido pulsado. Es decir, leemos el botón y lo guardamos en la variable estadoBoton

  estadoBoton = digitalRead (BOTON);

Si pulsamos el botón, tenemos que consultar el tiempo y guardarlo en la variable tiempoActual. Esto es:

  if (estadoBoton == HIGH){
    tiempoActual = millis();  
  }

Si el tiempo transcurrido entre la última vez que se pulsó el botón y el tiempo actual es superior, por ejemplo a 15000 milisegundos, el semáforo de coches pasa de verde a ámbar y de ámbar a rojo y, el de peatones, de rojo a verde:

  if (tiempoActual - tiempoAnterior > 15000) {
    digitalWrite(LED_VERDE_COCHE, LOW);
    digitalWrite(LED_AMBAR_COCHE, HIGH);
    delay(500);
    digitalWrite(LED_AMBAR_COCHE, LOW);
    digitalWrite(LED_ROJO_COCHE, HIGH);
    digitalWrite(LED_ROJO_PEATON, LOW);
    digitalWrite(LED_VERDE_PEATON, HIGH);
    delay(5000);

Dentro de este mismo if, el semáforo verde de los peatones parpadeará 4 veces.

    for(int i=0; i<3; i++) {
      digitalWrite(LED_VERDE_PEATON, LOW);
      delay(200);
      digitalWrite(LED_VERDE_PEATON, HIGH);
      delay(200);
    }

De manera simultánea tanto el semáforo rojo de los coches como el verde de los peatones se apagan para dar paso a la línea uno de la función void loop()

    digitalWrite(LED_VERDE_PEATON, LOW); 
    digitalWrite(LED_ROJO_COCHE, LOW);

¡Importantísimo! Antes de cerrar el if tenemos que actualizar la variable tiempoAnterior, guardando en esta el tiempo de la última vez que se pulsó el botón, es decir, tiempoActual. Por supuesto, solo si hemos entrado en el if:

    tiempoAnterior = tiempoActual;

En definitiva, el código completo nos ha quedado así:

Volver a: Semáforo con Arduino

©2017 Fábrica Digital desde Jerez de la Frontera, España.

956 05 77 07 (llamadas) / 717 717 452 (Whatsapp) / hola@fabricadigital.org

Horario de verano: de Lunes a Viernes de 09:00 a 13:00.

Calle Manuel Yélamo Crespillo, Edif. Los Ramos, 11401 Jerez de la Frontera, Cádiz. - Cómo llegar

Información Legal - Aceptamos

 

Inicia Sesión con tu Usuario y Contraseña

o    

¿Olvidó sus datos?

Create Account