miércoles, 28 de marzo de 2018

Arduino controlando el tránsito

Hace un tiempo que venía pensando en hacer algo con Arduino que uniera el mundo físico con el de la programación. Comúnmente, al desarrollar, sólo interactuamos con las clásicas interfaces de usuario como el teclado o el mouse (y si tenemos suerte, con una pantalla táctil), pero Arduino me resultó interesante ya que permite obtener información de diferentes sensores y generar eventos a partir de ellos. Hay muchísimos sensores, como por ejemplo de temperatura, de luz, de presencia, de movimiento, de distancia, de inclinación, de gas, de fuego, de agua, pulsadores, entre tantos otros.

Buscando información sobre cómo comenzar, encontré que siempre se empieza con el mismo ejemplo: cuando se presione un botón pulsador, que se mantenga encendido un led por algún tiempo. Aunque esto parezca algo demasiado sencillo, se puede extrapolar a diferentes conceptos. O sea,  si reemplazamos el botón por un sensor como uno de luz y el led por una lamparita, podemos definir que si detecta que la iluminación del ambiente baja de un determinado umbral, se prenda la luz. Otro ejemplo sería reemplazando el botón por un sensor de nivel de agua y el led por un motor centrífugo. De esta forma podemos hacer que el motor suba agua a un tanque si el nivel del mismo alcanza un mínimo y apagarlo después de un tiempo.

Además de conocer más sobre estos ejemplos, hice un curso en https://www.coursera.org/ que brindaba la Universidad Autónoma de México, pero me pareció extremadamente básico (creo que el público objetivo eran chicos que apenas terminan la primaria). Luego encontré otro curso en la misma página, pero brindado por el Instituto de Física y Tecnología de Moscú, que realmente me pareció muy bueno. 

En esta nota intentaré describir como fue el proceso para realizar la tarea que requería el curso. Podrán ver el código, los componentes necesarios y un video del proyecto terminado en el repositorio de Github

El desafío 

Este curso tenía como tarea crear un robot (en su definición más formal) el cual controlara un modelo que representara un cruce de las vías del tren con un camino peatonal y una vía para autos. 


Por un lado tenemos que detectar cuando se acerca el tren. Para ello utilizamos un sensor de distancia por ultrasonido y para cuando un peatón quiere cruzar, se usa un botón de presión. Por otro lado, debemos informar a los vehículos cuando pueden pasar para lo cual ponemos una barrera en el camino. De la misma forma tenemos que avisar a los peatones si pueden cruzar y para ello usamos un semáforo, o sea, un led verde y uno rojo y además, generamos sonido por medio de un buzzer.
  
Entonces, el modelo debía cumplir con las siguientes reglas: 
  • Si aparece el tren, el semáforo se tiene que poner en rojo y bajar la barrera.
  • Una vez que pasó el tren, debe mantener el semáforo en rojo y abrir la barrera.
  • Si un peatón quiere cruzar debe presionar el botón, el cual baja la barrera y pone el semáforo en verde. 
  • Si el peatón presiona el botón mientras pasa el tren, una vez que este termina de pasar el semáforo debe ponerse en verde y mantener la barrera baja. 
  • La luz verde del semáforo se mantendrá encendida durante 5 segundos y después será intermitente por los próximos 4 segundos. El sonido de la alarma deberá cambiar también al llegar a los 4 segundos. 
  • El peatón deberá esperar 18 segundos desde la última vez que se le dio paso hasta que se le permita nuevamente. Los primeros 9 segundos tendrá la luz del semáforo en verde y los siguientes serán los vehículos quienes tengan habilitado el paso. 


Al parecer, estas reglas son sencillas, pero fue realmente desafiante lograrlas. 

Comiendo al elefante

En este caso los pequeños bocados fueron: 
1. Planeación: hacer un diagrama del mundo físico, la señal eléctrica y el código. 
2. Diseño: hacer un diagrama de estados 
3. Construcción: construir el código 
4. Implementación: construir el modelo físico

Planeación

Sabía que tenía ciertos requerimientos que se iban a convertir en componentes específicos y necesitaba saber si me alcanzaban los pines que tiene disponible la placa de Arduino, como por ejemplo, para el semáforo necesitaba dos led: uno rojo y otro verde, esto a nivel de la señal eléctrica requiere de un pin para cada uno. Para detectar el tren, precisaba algún tipo de sensor de presencia y decidí usar un medidor de distancia por ultrasonido (podría haber usado uno por IR, o un sensor de luz, etc.). En este caso el sensor requiere 2 pines más. También necesitaba el botón pulsador para los peatones, un servo para subir y bajar la barrera que habilita el tránsito de los autos y el buzzer para la señal sonora del aviso del tren.


Diseño

Definí una máquina para representar sus estados y sus transiciones ya que son muy marcados. Por ejemplo, no hay manera de que cuando esté habilitado el paso del tren se habilite a los peatones o los vehículos. Por otro lado, las transiciones también son muy representativas, o sea, si estaba pasando el tren y fue presionado el botón de los peatones la transición es TREN_A_PEATONES con los cual es más fácil decidir mantener baja la barrera y poner el semáforo en verde. 





Construcción

Comencé usando el IDE propio de Arduino, pero realmente no es más que un notepad con los botones de validar y subir, por lo que casi lo descarté al instante. Buscando un IDE mejor para trabajar, encontré un plugin para Visual Studio Code que integra con Arduino que me pareció bastante bueno. Este plugin permite tener en el IDE características como completador de código, descripción de las variables, ayuda sobre las funciones y la posibilidad de engancharlo con el GIT, entre otras. Todas funcionalidades que no tiene el IDE propio de Arduino, por supuesto. Además, permitir validar (Ctrl-Alt-R) y subir (Ctrl-Alt-U) el código al Arduino, ver la consola del puerto serie y hacer un debug del programa (algo que no llegué a probar). 

Una decisión de código fue separar en archivos diferentes (helpers.ino y UltraSoundSensor.ino) las funciones que no son específicas de este proyecto, por ejemplo la que hace la medición del sensor o la que sube o baja la barrera, dejando en el archivo principal (Proyecto_1.ino) las funciones que tienen lógica de negocio. 




Implementación

Comencé por poner los leds y el botón para generar el cambio de estado para habilitar a los peatones. Después puse la barrera y el estado de los vehículos y, por último, el sensor del tren con sus cambios de estados y transiciones. En ese momento me di cuenta que el sensor a veces daba un valor muy bajo y que, por lo que llegué a leer, puede deberse a la baja calidad de los componentes, la interferencia en los cables o los cambios de voltajes generados posiblemente por el servo de la barrera. Para solucionarlo, redefiní el método que mide la distancia para que devuelva el promedio entre 10 lecturas y que, de este manera, se filtren los valores extremos. 





Conclusión

Arduino permite unir el resultado de varios sensores y generar eventos en los componentes de salida de una forma sencilla y a muy bajo costo. Obviamente hay que tener ciertos conocimientos de electrónica y de programación básicos, pero la experiencia se puede ir adquiriendo a medida que uno construye. 

Con respecto al curso online, realmente fue muy bueno. Además de incrementar la complejidad módulo a módulo, me aportó técnicas para resolver situaciones comunes. 

Usar VSCode como IDE realmente me simplificó las tareas como commitear el código en el repositorio y poder volver atrás después de hacer algunas pruebas.

Al final de cuentas, encontrarme sin conocimientos, investigando y aprendiendo fue realmente muy entretenido.

Imágenes del modelo terminado
  


Link al video aqui

LINKS
  
Autor:
Marcelo Mosquera
.NET Technical Expert