ACTUALIZAR: El trabajo en nuestra estación meteorológica Arduino continuó después de la publicación de este artículo, que culminó con el lanzamiento de Estación meteorológica abierta (OWS) . Compruébelo para obtener actualizaciones adicionales, recursos, junto con código y nuevos tutoriales.
Surf de vela es uno de los deportes más adictivos del mundo. Todo lo que necesita es una tabla de kitesurf, un cuerpo de agua y algunos accesorios. Es una excelente manera de ponerse en contacto con la naturaleza, liberar su mente y hacer ejercicio. Además, puedes realmente volverse loco con eso.
Oh, olvidé un requisito esencial: viento. Y ahí es donde tenemos nuestro problema: nunca se sabe si habrá viento o no a menos que viva junto a su lugar favorito para practicar kitesurf.
vivo en Córdoba, Argentina , aproximadamente a 130 kilómetros (~ 80 millas) del lago donde practico kitesurf. Eso es aproximadamente un viaje de dos horas, con lo que puedo lidiar. Pero no puedo afrontar el hecho de que las previsiones meteorológicas son inexactas. Y donde vivo, las buenas condiciones del viento duran solo un par de horas. Lo último que quieres hacer es aclarar tu horario de los lunes para practicar kitesurf y encontrarte maldiciendo a los dioses en un lago sin viento después de dos horas de conducción.
Necesitaba conocer las condiciones del viento de mi lugar favorito para practicar kitesurf, en tiempo real. Entonces decidí construir mi propia estación meteorológica.
El objetivo era entregar datos meteorológicos en tiempo real al navegador de casa:
Antes de entrar en detalles, tomemos un momento para considerar las preguntas clave y las advertencias involucradas en un proyecto como este:
Puede pensar que el guante está ahí para hacer que la estación parezca más amigable; pero en realidad se usa para probar el sensor barométrico (la presión del guante aumenta dentro del guante inflado). A la derecha, puede ver la estación en su ubicación final, en lo alto de una torre cercana.
También diseñé y programé un sitio web sobre kitesurf , que incluye un gráfico en tiempo real de las medidas de la estación para ayudar a la comunidad de kitesurf. Finalmente, creé un grupo de kitesurf en Facebook .
Bueno, abordaré cada punto por turno:
Este fue un factor crítico y, en muchos sentidos, impulsó el resto del proceso de diseño. La mayoría de las estaciones prefabricadas por debajo de la línea de $ 2000 requieren un Conexión USB a una computadora . Si un ladrón reconocía que la estación tenía una computadora al lado, sería el final de las cosas, ya que el costo de reemplazar la computadora y la estación estaría por encima de mi presupuesto personal. Por eso, decidí probar varias plataformas de hardware para implementar la estación desde cero, a un costo menor.
Yo solo estaba soportando los costos de este proyecto paralelo y haciendo todo el trabajo en mi tiempo libre, así que, por supuesto, esto era una gran preocupación. Empecé con lo popular PIC32 y algunos módulos Ethernet de microchip preensamblados, pero los costos no fueron tan bajos como esperaba y hubo demasiados gastos generales involucrados en el ensamblaje y la extensión del hardware. Entonces, comencé a buscar en el Arduino : hardware y software de código abierto para la creación de prototipos electrónicos en lenguaje C. Esto era exactamente lo que quería y podía comprar módulos en DealeXtreme . Pude comenzar a jugar con solo $ 15 de gastos y dos días de mi tiempo.
Por supuesto, el Arduino también tiene sus limitaciones: solo 2 KBytes de RAM y 32 KB para mi software compilado, eso no deja mucho espacio para cadenas elegantes o variables inútiles1.
Actualmente, mi estación puede medir: velocidad del viento, ráfagas de viento, dirección del viento, temperatura, humedad, lluvia y presión atmosférica. La temperatura, la humedad y la presión son manejadas por un par de bibliotecas, lo que hizo la vida mucho más fácil.
Medir la velocidad del viento y la lluvia fue un poco complicado. Los sensores operados abriendo y cerrando un interruptor ( interruptor de láminas ). Por lo tanto, necesitaba implementar interrupciones de hardware para detectar el sensor tan pronto como active la entrada. Es decir, necesitaba llamar a algún método:
|_+_|Esta interrupción rompería la ejecución normal del código y llamaría a la función countAnemometerCycles o countRainCycles tan pronto como el interruptor experimenta un flanco descendente, producido al cerrar o abrir el circuito. Algunas variables se incrementan en cada disparador del interruptor. (Más tarde, pondera estas variables para tener en cuenta las conversiones de unidades).
|_+_|¡Pero no tan rápido! Este proceso genera cientos de disparos falsos como resultado del efecto de rebote del interruptor inherente a cualquier interruptor de hardware. Afortunadamente, existen soluciones tanto de hardware como de software para este problema.
El efecto de rebote se produce como consecuencia de que el interruptor abre o cierra físicamente sus 'contactos', que establecen contacto con el resto del circuito. Cuando los contactos comienzan a separarse (abriendo el interruptor) o unirse (cerrando el interruptor), se pueden generar algunos pequeños arcos eléctricos, así como una elasticidad mecánica en el circuito que activará el encendido y apagado del circuito durante un par de milisegundos. Cuando acciona un interruptor de luz, este efecto no es evidente; pero cuando adjunta una interrupción al borde descendente de una señal, este efecto de rebote desencadena un montón de interrupciones. Más Aquí .
Implementé un circuito antirrebote de hardware y una versión similar en software. Pero, ¿cómo se implementa exactamente un software antirrebote? ¡Fácil! Después de que ocurra el primer disparo esperado, “espere” el tiempo suficiente para que se estabilice el rebote antes de comenzar a escuchar nuevas interrupciones. Esto se puede lograr en un par de líneas de C:
|_+_|La función millis () devuelve el tiempo de ejecución actual en milisegundos desde que se encendió Arduino. También vale la pena señalar que estas variables deben definirse como volátiles para indicar al compilador que no optimice la ejecución y, por lo tanto, evite valores inexactos durante las interrupciones de hardware.
De alguna manera, necesitaba que la estación almacenara los datos acumulados y enviara periódicamente estas medidas a una base de datos MySQL. Así que agregué un módulo Ethernet con una ranura SD para registrar los valores y recuperarlos cada vez que un usuario (el servidor) se conecta a la estación. Durante la prueba en casa con conectividad ADSL, esto funcionó asombrosamente bien, pero casi pierdo el cabello cuando probé esto 'en el campo' con Internet 3G (usando un módem 3G), ya que la estación se reiniciaba al azar cuando intentaba recuperar el ¡mediciones! Después de pruebas importantes, finalmente descubrí que los ejemplos proporcionados en Internet que describen el 'servicio' de datos a un cliente conectado no consideraban que la conexión podría ser tan deficiente que la conexión con el cliente podría perderse a mitad de la transmisión del paquete, lo que provocó el el búfer de salida se desbordaría. Pero, ¿por qué una conexión interrumpida provocaría un desbordamiento del búfer? Bueno, digamos que comienza la sesión de transmisión y la estación comienza a llenar el búfer de salida con datos. Idealmente, el cliente consume este búfer más rápido de lo que se llena. Sin embargo, al conectarse con un módem 3G, este no fue el caso. La conexión con el cliente era demasiado deficiente, por lo que el búfer se llenó más rápido de lo que se consumió, lo que provocó un desbordamiento del búfer y un reinicio repentino de la estación.
Para abordar el problema, necesitaba agregar una función al Biblioteca Ethernet provisto con el Arduino que fue algo como esto:
|_+_|Luego, pude verificar si el cliente tenía algo de espacio en el búfer antes de intentar llenarlo con más datos:
|_+_|Por cierto, si está interesado en programar un Arduino, aquí está una gran guía.
Otra tarea interesante fue la implementación de un log LIFO. ¿Por qué fue esto necesario? Bueno, normalmente, cuando guardo las medidas en un archivo determinado, el enfoque es simple: abrir el archivo, agregar las nuevas muestras al final y cerrar el archivo. Pero digamos que quiero obtener las últimas 1000 mediciones, ordenadas cronológicamente. Esas medidas están al final del archivo; así que debería abrir el archivo, mover el cursor al final, generar las últimas mediciones, luego hacer que el cursor del archivo regrese a la medición anterior y generar eso buscando un delimitador de muestra para detectar dónde comenzar y detener. El Arduino no tiene suficiente RAM ni potencia de procesador para ejecutar este proceso rápidamente, así que necesitaba otro enfoque. En cambio, decidí enviar el archivo en orden inverso al servidor y luego revertir los literales de cadena en el lado del servidor:
|_+_|Con cualquier experiencia como desarrollador de PHP, es fácil obtener las últimas muestras con los caracteres en el orden correcto:
|_+_|En el lado del servidor, configuro un proceso cron para obtener las últimas medidas cada dos minutos e insertar los datos en un motor MySQL. Para mostrar los datos, creé www.kitesurfcordoba.com.ar y usó jQuery para actualizar automáticamente los gráficos (que a su vez se generan usando pChart v2.0 , una gran biblioteca de código abierto).
Había un montón de otros trucos necesarios para que todo funcionara, relacionados con la ingeniería de software y hardware, pero me he demorado lo suficiente, así que hablemos de minimizar el mantenimiento.
Esta fue una gran preocupación porque ciertamente no es fácil para mí llegar a la estación; si estuviera dispuesto a conducir dos horas solo para arreglar una falla menor, entonces no habría tenido que obligarla a entrar en primer lugar ( no mencioné esto antes, pero después de todo lo que hemos pasado, la estación es en realidad una 'ella', y su nombre es Dorothy).
Entonces, ¿de qué tipo de errores estamos hablando aquí? Bueno, por ejemplo: el software puede bloquearse, la red puede perder conectividad, el suministro de energía puede fallar (y lo hace), etc.
Esencialmente, la estación necesita realizar la mayor auto-recuperación posible. Es por eso que utilicé tanto blando como duro perros guardianes . Para aquellos que no están familiarizados, un perro guardián es una pieza de software o hardware que verifica si un sistema está funcionando correctamente y, de lo contrario, intenta devolverlo a la vida. El Arduino tiene un perro guardián integrado que puedes usar. Lo configuré para esperar 8 segundos: si una llamada tarda más que ese límite de tiempo, el controlador de software reiniciará la placa.
|_+_|Amo esta función. Sin embargo, hay ocasiones en las que la placa se reinicia y el módulo Ethernet no. ¿Por qué? Bueno, esta es una placa de creación de prototipos relativamente asequible, no un dispositivo a prueba de fallas muy caro (ciertamente no debería construir un marcapasos con él). Para superar este inconveniente, tuve que piratear el Arduino mediante el cableado cruzado de una entrada de reinicio de hardware a una salida digital en la propia placa. Para evitar un ciclo de reinicio, también se deben agregar un par de líneas de código:
|_+_|Después de eso, pude emitir un reinicio de hardware en el Arduino y todos los módulos encima (incluido el módulo Ethernet) simplemente llamando a attachInterrupt(RAINGAUGE_PIN, countRainCycles, FALLING);
, lo que devolvió a Dorothy a la vida después de un par de segundos.
Además, la placa se reinicia automáticamente después de una pérdida de energía. Y si falla la conectividad a Internet, aprovechamos las capacidades de almacenamiento de la tarjeta SD (los datos se pueden almacenar en la tarjeta durante más de una semana y el servidor puede extraer datos antiguos para recuperar las muestras faltantes). La combinación de todas estas características nos brinda una estación meteorológica altamente robusta que puede sobrevivir a las condiciones hostiles para las que fue construida para monitorear. En total, esto me costó alrededor de $ 300.
La estación ha estado funcionando desde diciembre de 2012. Hasta la fecha, no ha fallado (o si lo hizo, la estación se recuperó lo suficientemente rápido como para que la comunidad de kitesurf y yo no nos dimos cuenta). Hay aproximadamente 500 kitesurfistas que revisan la estación meteorológica con regularidad antes de viajar al lugar. Así que, además de la recompensa por resolver algunos desafíos técnicos difíciles, también tuve la oportunidad de brindar a un grupo de personas una experiencia de kitesurf más agradable.
1Inicialmente, estaba usando un Arduino Uno . Más tarde, cambié a un Arduino Mega debido a la necesidad de aumentar la RAM y la memoria flash.
Relacionado: Trabajar con muestreo de audio ESP32