Si hablamos de Arduino estamos hablando de la democratización del uso de los microcontroladores. Desde que hace más de un año presentó el Arduino MKR1000, las cosas han ido cambiando. La entrada de redes LPWAN ha impulsado la última placa presentada, el Arduino MKRFOX1200 con conexión a Sigfox.
Como no, siempre que sale un Arduino destinado al IoT con una nueva tecnología, me sale el Síndrome de Ansia Viva (#SAV acuñado por el gran Obijuan) y tengo que probarlo. Yo soy fan de Arduino al igual que hay fanboys de Apple o de Google.
Pero si hay algo que realmente me gusta hacer con esta placa, es hacer proyectos. Me encanta plantear retos e investigar sobre la materia. Se trata de ir descubriendo no solo la programación y la electrónica, también de aprender sobre el mundo.
Qué es el torque, como funcionan unos engranajes, a montar y desmontar sistemas mecánicos, tornillería, carpintería e incluso aspectos meteorológicos como la radiación UV (ultravioleta). Precisamente de esto último te voy a hablar hoy.
Sigfox nos abre la puerta de la conectividad a zonas inaccesibles para otras tecnologías y Arduino MKRFOX1200 nos ayuda a implementar dispositivos y prototipos de una forma fácil y rápida. De bajo consumo y con muy buena cobertura.
Esto me ha llevado a plantear el proyecto que os voy a presentar hoy, un medidor de radiación UV con Sigfox y Arduino MKRFOX1200.
Indice de contenidos
- 1 Por qué medir la radiación UV en Alicante
- 2 Qué es la radiación UV
- 3 Cómo medir la radiacion UV
- 4 Sensores radiación UV con Arduino y Sigfox
- 5 Sensor radiación UV ML8511 con Arduino
- 6 Arduino MKRFOX1200 con conexión a Sigfox
- 7 SigFox la red del IoT
- 8 Sensor de temperatura y presión BMP180
- 9 Conectando los componentes a Arduino MKRFOX1200
- 10 Programando Arduino MKRFOX1200 con Sigfox
- 11 Configuración Thingspeak para Sigfox
- 12 Configuración callback de Sigfox a Thingspeak
- 13 Pagina web con jQuery y Bootstrap para visualizar los datos de Sigfox
- 14 Conclusiones Sigfox y Arduino MKRFOX1200 con sensor radiación UV
Por qué medir la radiación UV en Alicante
Yo vivo en una zona donde el número de días despejados (sin nubes) es muy superior a los días nublados. Esto conlleva a que estamos expuestos a más cantidad de radiación que en zonas donde hay más nubosidad.
No es algo que preocupe a corto plazo, pero como veremos más adelante, la exposición a largo plazo puede tener efectos irreversibles.
En la actualidad, la página web de la Consellería de Vivienda, Obras Públicas y Vertebración del Territorio de la Generalitat Valenciana, tenemos acceso a las estaciones de medida de radiación UV-B y el índice UV.
En concreto hay 5 estaciones en algunos casos distanciadas más de 100 Km. La idea es poder probar si podemos tomar medidas en diferentes playas de la ciudad de Alicante y cotejarlo con los datos reales que nos ofrecen estas estaciones y los datos de predicción del índice UV.
Pero aún voy más allá. Este proyecto se enmarca dentro de los proyectos realizados dentro de la Asociación MakerALC (de la cual soy miembro) donde nuestra idea es crear dispositivos del IoT para ciudades inteligentes totalmente libres.
Que cualquier ciudad, pueblo o comunidad, pueda comprar el hardware y replicarlo gracias a la liberación del código.
De todo esto te mantendré informado en el podcast y en el blog ;)
Qué es la radiación UV
Dentro del proceso del prototipado, una de las partes más importantes es la fase de investigación. Esto conlleva a conocer todos aquellos aspectos importantes para desarrollar un proyecto.
En este proyecto, no nos queda otra que saber qué es la radiación UV. No voy a entrar en detalles muy técnicos, creo que hay suficiente información en Internet para profundizar en esta radiación.
Si nos fijamos en el espectro de luz solar, podemos diferenciar tres grandes franjas.
Fuente Shuterstock.
Por un lado el espectro de luz visible que va desde los 400 nm a 700 nm de longitud de onda. A un lado tenemos el infrarrojo a partir de los 700 nm y en el otro extremo la luz ultravioleta, de 10 nm a 400 nm.
Pero no solo el sol puede generar radiación UV, también puede ser generada de forma artificial con lámparas de vapor de mercurio o con equipos de soldadura.
A diferencia de lo que te pueda parecer, la radiación UV se utiliza en varias áreas como por ejemplo revelar circuitos impresos con insoladoras, se pueden esterilizar herramientas o utensilios debido a su capacidad de eliminar bacterias y virus o para el control de plagas atrayendo a insectos.
Pero no toda la radiación ultravioleta penetra en la tierra. Dependiendo de la longitud de onda, se divide en tres grupos. Cada una de ellas llega con diferente intensidad a nosotros.
- Radiación UV-C: comprendida entre los 100 a 280 nm. La capa de ozono y la atmósfera la absorbe en su totalidad.
- Radiación UV-B: comprendida entre los 280 y 315 nm. Parte de ella penetra en la tierra.
- Radiación UV-A: comprendida entre los 315 y 400 nm. El 90% de la radiación que llega a nosotros es de este tipo.
Fuente Shuterstock.
La radiación UV-B es la realmente peligrosa ya que afecta a los seres humanos de forma contraproducente. A corto plazo puede provocarnos inflamaciones y quemaduras (las típicas cuando vas a la playa). A largo plazo, puede llegar a generar arrugas en la piel e incluso cáncer.
Por este motivo es conveniente controlar la radiación en sitios turísticos como las playas. Puedes consultar la información detallada que nos ofrece el ICNIRP (Comisión Internacional de Protección contra la Radiación No Ionizante).
Cómo medir la radiacion UV
Para medir la radiación UV nos basamos en el estándar establecido por Organización Mundial de la Salud, Organización Meteorológica Mundial, Programa de Naciones Unidas para el Medio Ambiente y la Comisión Internacional de Protección contra la Radiación No Ionizante.
Establecen una tabla por la cual cuantificar la peligrosidad de la radiación UV con un índice, el índice UV. Incluso nos muestra un código de colores que va desde el verde al morado indicando el riesgo.
Indice UV. Fuente AEMET.
La radiación UV no depende solo de la capa de ozono, otros factores como la altura del sol, la latitud, la nubosidad o la reflexión son determinantes para aumentar o reducir este índice.
A la hora de notificar a la población, no nos vale con tomar la medida. La OMS recomienda en su guía práctica que se debe predecir un valor medio diario durante 30 minutos para notificar. En el caso de una observación continua, solo valdrán los valores medios entre 5 o 10 minutos.
Si el sensor o la estación proporciona valores decimales, se deberá redondear al entero más próximo.
Toda esta investigación nos sirve para plasmar en código nuestro proyecto. Debemos se conscientes que esta parte es una de las más importantes del prototipado con Arduino.
Sensores radiación UV con Arduino y Sigfox
Como siempre se nos abre un gran abanico de posibilidades. Recomiendo la lectura de este artículo donde trata el tema de una forma exquisita y aportando mucha información.
Si nos vamos a las estaciones profesionales, encontramos los espectrorradiómetros y los radiómetros. Estos últimos son los que utilizan las estaciones de la Comunidad Valenciana. El gran problema es el precio, no está al alcance de muchos de nosotros.
Sin embargo, el avance de nuevos sensores para utilizar con Arduino nos da la posibilidad de medir el índice UV con los fotodiodos. Estos componentes son sensibles a la luz UV y varían su resistencia (por consecuencia su voltaje) dependiendo de su incidencia.
En primera instancia son calibrados con espectrorradiómetros o radiómetros. Una vez calibrados son capaces de conseguir una buena precisión al medir del índice UV.
Solo tenemos que hacer un a búsqueda en Google y nos aparecerán unos cuantos. Algunos de ellos son:
Alguno de ellos es digital y se comunica por I2C y otros son analógicos. Debemos de llevar cuidado con estos últimos ya que son más sensibles al ruido.
Debemos de fijarnos en dos características importantes, la respuesta espectral y la salida de voltajes, que sea lineal.
En mi caso el elegido ha sido el ML8511 de Sparkfun.
Sensor radiación UV ML8511 con Arduino
Se trata de un sensor analógico que nos da un voltaje dependiendo de la radiación que incida en el fotodiodo. Como ya te he dicho, la respuesta espectral y una salida de voltaje son las características más importantes a tener en cuenta.
ML8511. Fuente Sparkfun.
Si nos vamos a la hoja de características técnicas, comprobamos que la salida de voltaje es lineal y la respuesta espectral abarca la longitud de onda de la radiación UV-B y UV-A.
El voltaje de operación es de entre 3,3 V y 3, 6V es decir, el voltaje con el que tenemos que alimentar el sensor. Lo que más me gusta es su consumo que ronda entre los 300 μA y los 500 μA en modo normal, en funcionamiento. Si está en modo de reposo (standby) consume 0,1 μA.
Para activar el modo reposo tenemos que poner uno de los pines marcado con EN en estado bajo (LOW).
Está todo ensamblado sobre una PCB de pequeñas dimensiones, ideal para prototipar. Solo tiene 4 conectores
Arduino MKRFOX1200 con conexión a Sigfox
El pasado mes de abril, en el Arduino Day se presentó, como ya nos tienen acostumbrados, una nueva placa, el Arduino MKRFOX1200. De momento, como suele suceder, los que ya tenemos alguna en nuestras manos estamos experimentando.
El microchip o SoC (System on a Chip) que utiliza es el mismo que el Arduino MKR1000. Esto hace que muchos de los conocimientos adquiridos los podemos utilizar, no empezamos de cero. Sin embargo con respecto al software, la cosa cambia.
Arduino MKRFOX1200. Fuente Arduino.
Ya no estamos conectando a una red WiFi, ahora nos conectamos a Sigfox y eso requiere de una nueva librería y de una nueva plataforma. Gracias al módulo de Sigfox ATA8520 y a una antena GSM podremos conectar a esta red.
Además, el Arduino MKRFOX1200 incorpora una suscripción gratuita durante dos años a Sigfox. Un acuerdo que nos beneficia a todos :)
No voy a entrar en detalle de las características más importantes, ni de cómo lo puedes configurar. A continuación te dejo unos tutoriales que puedes seguir para dar los primeros pasos.
Respecto a la alimentación es algo que actualmente estoy investigando. Por ahora he hecho pruebas con el Arduino MKRFOX1200 conectado al ordenador mediante el puerto USB. En este caso se alimenta con 5V y no tiene problemas para suministrar el voltaje a los sensores.
Pero también existen otras formas de alimentar esta placa. Por un lado el pin Vin que nos permite suministrar 5V. Pero sin duda alguna, si queremos un dispositivo del IoT funcional, tendremos que utilizar los conectores para baterías o pilas.
El rango de valores que admite estos conectores es de 1,6 V a 3,7 V. Es igual que el Arduino MKR1000. Gracias a sus diferentes estados de reposo, podemos llegar a utilizar esta placa durante 6 meses con dos pilas AA o AAA de 1,5V.
Todo esto lo trataré en un artículo dedicado a los consumos.
Por último, cabe destacar de Arduino MKRFOX1200 que tiene incorporado un sensor de temperatura. Es fácilmente accesible y podemos utilizarlo para saber los grados que hay en la placa.
SigFox la red del IoT
Sigfox es una red propia que se está expandiendo muy rápidamente por todo el mundo. Utilizan una banda de frecuencia libre que en Europa es la de 868 MHz y en EEUU es la de 915 MHz.
No se trata de una red de banda ancha, más bien es una red que sirve única y exclusivamente para transmitir poca cantidad de información. Ese es su fuerte ya que debido a esto, se consiguen unos consumos muy bajos.
Los límites de transmisión son 140 mensajes al día de no más de 12 bytes. Si dividimos los 140 mensajes entre las 24 horas del día, tenemos que podemos enviar un mensaje cada 10,2 minutos. No está nada mal.
También debemos tener mucho ojo con los datos que transmitimos, no podemos pasarnos de 12 bytes. Lo idóneo es utilizar esta plataforma como pasarela de nuestros dispositivos.
Para conseguir esto debemos hacer uso de una característica que nos ofrece Sigfox, las callback. Esta función permite retransmitir a otras plataformas cada dato que enviamos a Sigfox.
Todo esto lo iremos viendo a lo largo de diferentes artículos donde vaya explicando las diferentes funcionalidades de Sigfox. Para este proyecto he decidido utilizar la plataforma Thingspeak. Si quieres profundizar más sobre ella te aconsejo que eches un vistazo al curso que tengo en el Campus.
Sensor de temperatura y presión BMP180
Además del sensor de radiación UV, he incorporado otro sensor que me de información sobre la temperatura y la presión atmosférica, el BMP180. Como ya te he comentado, el propio Arduino MKRFOX1200 tiene incorporado un sensor de temperatura.
BMP180. Fuente Sparkfun.
La decisión de incorporar este sensor es solo experimentar sobre las capacidades de la placa. Al igual que con los otros componentes, dedicaré un artículo exclusivamente a este sensor.
Cabe destacar las siguientes características técnicas obtenidas del datasheet:
- Rango de presión atmosférica: de 300 hPa a 1100 hPa
- Voltaje de operación: de 1,6 V a 3,6 V
- Rango de temperaturas: de -40ºC a 80ºC
- Consumos: de 3 μA a 1.000 μA (dependiendo del modo)
- Comunicación: I2C por lo tanto es un sensor digital
Y con esto ya tendríamos todos los componentes necesarios para nuestro dispositivo de radiación UV con Arduino MKRFOX1200 y Sigfox. Ahora vamos a ensamblarlos.
Conectando los componentes a Arduino MKRFOX1200
El esquema eléctrico que he utilizado es el siguiente.
El sensor BMP180 va conectado al Arduino MKRFOX1200 a través del I2C. El pin 12 es el SLC y el pin 11 es el SDA. El pin de alimentación del BMP180 va al pin Vcc del Arduino. Este suministra 3,3 V suficiente para alimentar el sensor. También conectamos la masa al pin GND del Arduino.
El sensor ML8511 tiene 4 pines. Dos son de alimentación, el de 3,3 V lo conectamos al Vcc y el GND con la masa del Arduino. El pin de OUT es que nos proporciona el voltaje para saber el índice UV y lo conectamos al pin analógico A1.
Como hemos visto antes, el sensor puede funcionar en modo normal o reposo. Esto se consigue modificando el estado del pin EN del sensor. Si está a 0 V (LOW) se pone en modo reposo. Si está a 3,3 V (HIGH) se pone en modo normal.
Por defecto siempre lo pondremos en estado alto así que conectamos este pin al Vcc del Arduino MKRFOX1200.
Por último hay que sacar un cable directamente del pin Vcc al pin A2. Esto nos va a servir de referencia para hacer los cálculos según la recomendación de Sparkfun. Gracias a esta conexión, podremos tener en cuenta las fluctuaciones que puedan existir a la hora de alimentar la placa de una forma u otra.
Todo esto lo veremos en la programación.
Programando Arduino MKRFOX1200 con Sigfox
Dentro del código que estoy desarrollando vamos a encontrar diferentes partes. Por un lado la gestión del sensor de radiación UV ML8511. Por otro lado la gestión del sensor BMP180. Por último la gestión de los mensajes con Sigfox.
En el caso de los dos sensores, he optado por hacer una media de los 100 valores durante 5 minutos. Utilizo la misma técnica que el sensor de nivel de agua con ultrasonidos. Una vez que han pasado los 5 minutos, ya se puede transmitir los datos a Sigfox.
Para la transmisión utilizo una estructura con la información de temperatura, presión y radiación UV. También he reservado dos variables con el estado y la hora de envío del mensaje para su uso futuro.
Una vez transmitido, ponemos en modo reposo la placa durante 10 minutos. Cuando se despierta empieza a hacer de nuevo todo el ciclo. Gracias a la librería ArduinoLowPower podemos hacer esta gestión de una forma muy sencilla.
Para la transmisión de los datos se utiliza la librería Sigfox de Arduino. Viene con bastantes ejemplos y es muy sencilla de utilizar. A continuación te dejo todo el código necesario. Puedes modificar o utilizar dicho código como quieras, sin problema :)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 |
// Descomentar para hacer debug #define DEBUG_SIGFOX // Librerías #include <SFE_BMP180.h> #include <Wire.h> #include <ArduinoLowPower.h> #include <SigFox.h> // Sensor de temperatura y presión const int numBmp180 = 50; // Número de muestras SFE_BMP180 bmp180; float temps[numBmp180]; // Array para almacenar lecturas int tempActual = 0; // Lectura por la que vamos float tempTotal = 0; // Total de las que llevamos float tempMedia = 0; // Media de las medidas bool tempPrimera = false; // Para saber que ya hemos calculado por lo menos una float presis[numBmp180]; // Array para almacenar lecturas float presisTotal = 0; // Total de las que llevamos float presisMedia = 0; // Media de las medidas // Sensor de UV int UVOUT = A1; // Entrada del sensor int REF_3V3 = A2; // Entrada de referencia 3,3V const int numUv = 50; // Número de muestras float uvs[numUv]; // Array para almacenar lecturas int uvActual = 0; // Lectura por la que vamos float uvTotal = 0; // Total de las que llevamos float uvMedia = 0; // Media de las medidas bool uvPrimera = false; // Para saber que ya hemos calculado por lo menos una // Estructura para almacenar datos typedef struct __attribute__ ((packed)) sigfox_message { uint8_t status; int16_t bmpTemperature; uint16_t bmpPressure; float sparkUv; uint8_t lastMessageStatus; } SigfoxMessage; SigfoxMessage msg; // Centinela para saber cuando transmitir 10 minutos mínimo tomando muestras bool empiezaTransmitir = false; unsigned long tiempoInicial = 0; unsigned long tiempoEstimado = 5 * 60 * 1000; //5 minutos void setup() { #ifdef DEBUG_SIGFOX Serial.begin(9600); #endif /********* Sigfox ************/ if (!SigFox.begin()) { // Something is really wrong, try rebooting // Reboot is useful if we are powering the board using an unreliable power source // (eg. solar panels or other energy harvesting methods) reboot(); } // Ponemos el módulo en estado reposo hasta que mandemos el mensaje SigFox.end(); /************ SETUP BMP180 **************/ // Iniciamos el sensor de temperatura y presión if (bmp180.begin()) { #ifdef DEBUG_SIGFOX Serial.println("BMP180 iniciado"); #endif } else { #ifdef DEBUG_SIGFOX // Algo ha ido mal Serial.println("BMP180 ha fallado\n\n"); #endif while (1); // Bucle infinito. } // Inicializamos el array media temperatura y presión for (int i = 0; i < numBmp180; i++) { temps[i] = 0; presis[i] = 0; } // Inicializamos el array media radiación UV for (int i = 0; i < numUv; i++) { uvs[i] = 0; } /********* SETUP UV ************/ pinMode(UVOUT, INPUT); pinMode(REF_3V3, INPUT); // Debugamos Sigfox SigFox.debug(); // Obtenemos el tiempo inicial tiempoInicial = millis(); } void loop() { // Medir temperatura medirTemp(); // Medir radiación UV medirUV(); // Si ha pasado el tiempo establecido marcamos para empezar a transmitir if (millis() - tiempoInicial >= tiempoEstimado) { empiezaTransmitir = true; } // Comprobamos que tengamos todas las medidas y que haya pasado el tiempo estimado if (uvPrimera && tempPrimera && empiezaTransmitir) { #ifdef DEBUG_SIGFOX Serial.print("Temperatura: "); Serial.print(tempMedia, 2); Serial.print(" *C , "); Serial.print("Presion: "); Serial.print(presisMedia, 2); Serial.println(" mb"); Serial.print("Radiación UV (mW/cm^2): "); Serial.println(uvMedia); Serial.print("Milisegundos: "); Serial.println(millis()); #endif // Almacenamos la información para enviar msg.bmpTemperature = tempMedia; msg.bmpPressure = presisMedia; msg.sparkUv = uvMedia; // Reseteamos los contadores tempPrimera = false; uvPrimera = false; empiezaTransmitir = false; tempActual = 0; uvActual = 0; // Start the module SigFox.begin(); // Wait at least 30ms after first configuration (100ms before) delay(100); // Clears all pending interrupts SigFox.status(); delay(1); SigFox.beginPacket(); SigFox.write((uint8_t*)&msg, 12); msg.lastMessageStatus = SigFox.endPacket(true); #ifdef DEBUG_SIGFOX Serial.println("Status: " + String(msg.lastMessageStatus)); #endif SigFox.end(); //A dormir 10 minuto LowPower.sleep(10 * 60 * 1000); // Empezamos a contar el tiempo tiempoInicial = millis(); } else { delay(200); } } /*************Sigfox**************/ void reboot() { NVIC_SystemReset(); while (1); } void medirUV() { // Eliminamos la última medida uvTotal = uvTotal - uvs[uvActual]; int uvLevel = averageAnalogRead(UVOUT); int refLevel = averageAnalogRead(REF_3V3); // Calculo de la radiacion con la referencia de 3,3V float outputVoltage = 3.3 / refLevel * uvLevel; float uvIntensity = mapfloat(outputVoltage, 0.99, 2.8, 0.0, 15.0); // Conversión entre voltaje y radiación UV // Almacenamos la distancia en el array uvs[uvActual] = uvIntensity; // Añadimos la lectura al total uvTotal = uvTotal + uvs[uvActual]; // Avanzamos a la siguiente posición del array uvActual = uvActual + 1; // Comprobamos si hemos llegado al final del array if (uvActual >= numUv) { uvPrimera = true; uvActual = 0; } // Calculamos la media uvMedia = uvTotal / numUv; } // Calcula la media de cada pin int averageAnalogRead(int pinToRead) { byte numberOfReadings = 10; unsigned int runningValue = 0; for (int x = 0 ; x < numberOfReadings ; x++) runningValue += analogRead(pinToRead); runningValue /= numberOfReadings; return (runningValue); } // Función map con floats //From: http://forum.arduino.cc/index.php?topic=3922.0 float mapfloat(float x, float in_min, float in_max, float out_min, float out_max) { return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; } void medirTemp() { char status; double T, P; // Eliminamos la última medida tempTotal = tempTotal - temps[tempActual]; presisTotal = presisTotal - presis[tempActual]; status = bmp180.startTemperature(); //Inicio de lectura de temperatura if (status != 0) { delay(status); //Pausa para que finalice la lectura status = bmp180.getTemperature(T); //Obtener la temperatura if (status != 0) { status = bmp180.startPressure(3); //Inicio lectura de presión if (status != 0) { delay(status); //Pausa para que finalice la lectura status = bmp180.getPressure(P, T); //Obtenemos la presión if (status != 0) { // Almacenamos la temperatura en el array temps[tempActual] = (float)T; // Almacenamos la presión en el array presis[tempActual] = (float)P; // Añadimos la lectura al total tempTotal = tempTotal + temps[tempActual]; // Añadimos la lectura al total presisTotal = presisTotal + presis[tempActual]; // Avanzamos a la siguiente posición del array tempActual = tempActual + 1; // Comprobamos si hemos llegado al final del array if (tempActual >= numBmp180) { tempPrimera = true; tempActual = 0; } // Calculamos la media tempMedia = tempTotal / numBmp180; presisMedia = presisTotal / numBmp180; } } } } } |
Configuración Thingspeak para Sigfox
Lo primero que tienes que tener es una cuenta gratuita de Thinspeak. Esto te permite almacenar hasta 8 campos siempre y cuando no se supere el límite de 3.000 bytes con un máximo de 3 millones de mensajes al año.
Lo primero es crear un canal donde estarán los campos. Accede a mis canales.
Crea un nuevo canal
Rellena todos los campos necesarios, el nombre, la descripción y los campos numerados del 1 al 8. Si quieres que tu canal lo pueda ver todo el mundo tienes que marcar Make Public.
En mi caso he utilizado solo 5 campos. Estos son los datos.
Una vez lo tengas creado ya lo puedes seleccionar en My Channels.
Si accedes podrás visualizar las gráficas, modificar el canal y acceder a las API Key para escribir y leer.
En API Keys está la información que utilizaremos para configurar la página web donde mostrar los datos.
Copia la URL Get a Channel Feed. Elimina la palabra GET y esto te servirá de base para más adelante. Esta es la URL de lectura de mi canal.
1 2 |
https://api.thingspeak.com/channels/277292/feeds.json?results=20 |
Si lo que quieres es actualizar datos a través de la callback de Sigfox, tienes que utilizar la siguiente URL.
1 |
https://api.thingspeak.com/update?api_key=TU_API_KEY&field1=valor1&field2=valor2&field3=valor3&field4=valor4&field5=valor5 |
Y con esto ya tenemos preparada la plataforma en la nube para el IoT. Ahora vamos a pasar a configurar la callback de Sigfox.
Configuración callback de Sigfox a Thingspeak
Ya hemos visto que Sigfox va a funcionar como pasarela entre el Arduino MKRFOX1200 y Thingspeak. Para conseguir esto hay que configurar la función de callback. Básicamente lo que hace es mandar toda la información que llega a la plataforma a través de una API Rest.
No solo se puede utilizar Thingspeak, también tenemos la opción de utilizar otras plataformas como Firebase o ThingerIO. Esto queda al gusto del consumidor. Lo único que tendrás que cambiar es la URL de la API Rest que estés utilizando.
Lo primero es acceder al backend de Sigfox. Debes tener dado de alta tu dispositivo con los tutoriales que te he comentado anteriormente.
Una vez dentro entra den Device Type.
Ahora haz click sobre el dispositivo. Aparecerá un menú y seleccionas Edit.
Vete al menú de la derecha y haz click en CALLBACKS.
Crea una nueva callback.
De las opciones que se presentan, selecciona Custom Callback.
Aquí necesitarás rellenar dos campos, el Custom payload config y Url pattern. El primer campo indica el tipo de datos con los que vas a trabajar y el segundo la URL donde enviarlos. En nuestro caso es la URL de actualización que hemos visto antes.
Si tienes dudas sobre como rellenar estos campos sigue los consejos y ayuda que nos proporciona Sigfox.
Los datos que yo he utilizado son los siguientes.
Donde el Custom payload config es
1 |
status::uint:8 temp::int:16:little-endian press::uint:16:little-endian uv::float:32:little-endian lastMsg::uint:8 |
Tiene que guardar relación con los datos que hay que enviar desde el propio Arduino MKRFOX1200.
La Url pattern es
1 |
https://api.thingspeak.com/update?api_key=TU_API_KEY&field1={customData#temp}&field2={customData#press}&field3={customData#uv}&field4={customData#status}&field5={customData#lastMsg} |
Sustituye TU_API_KEY por la API Key de lectura de Thingspeak. Un vez que lo tengas le das a guardar y listo.
Para ver el estado del dispositivo entra en Device y pincha en el Id del dispositivo que quieres ver.
En las opciones del menú de la izquierda puedes ver los mensajes que has enviado.
Si pinchas en la flecha hacia arriba, verás la llamada a la API Rest de Thingspeak con los datos obtenidos del Arduino MKRFOX1200.
Si todo ha ido bien, ya puedes ir a Thingspeak y comprobar que está recibiendo datos.
Pagina web con jQuery y Bootstrap para visualizar los datos de Sigfox
La última cosa que deberíamos hacer es visualizar los datos en una página web. De momento sería lo ideal ya que lo podemos ver en cualquier dispositivo ya sea móvil, tablet o pc.
Yo he utilizado jQuery, Bootstrap, JavaScript y Google Charts. Te dejo a continuación el código de la web y el archivo JS.
Archivo HTML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Sensor UV Alicante</title> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <!-- Latest compiled and minified CSS --> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous"> <!-- Optional theme --> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css" integrity="sha384-fLW2N01lMqjakBkx3l/M9EahuwpSfeNvV63J5ezn3uZzapT0u7EYsXMjQV+0En5r" crossorigin="anonymous"> <style type="text/css"> header{ background: #2980b9; color: white; } aside{ background: #0f5786; color: white; } footer{ background: #2980b9; color: white; } h4{ font-size: 45px; } .centerdiv { width: 50%; margin: 0 auto; } </style> </head> <body onload="cargarInfo()"> <div class="container"> <header class="container"> <h1>Sensores Alicante</h1> </header> <div class="container"> <section class="row"> <div class="col-xs-12 col-sm-4 col-md-4 col-lg-4"> <h4 id="divuv" class="text-center">1,3</h4> <div id="chartuv_div" class="centerdiv"></div> </div> <div class="col-xs-12 col-sm-4 col-md-4 col-lg-4"> <h4 id="divtemp" class="text-center">27º</h4> <div id="charttemp_div" class="centerdiv"></div> </div> <div class="col-xs-12 col-sm-4 col-md-4 col-lg-4"> <h4 id="divpress" class="text-center">1001</h4> <div id="chartpres_div" class="centerdiv"></div> </div> </section> </div> <footer class="container"> <h3></h3> </footer> </div> <!--Librería jQuery--> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script> <!-- Latest compiled and minified JavaScript --> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script> <!--Javascript propios--> <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script> <script type="text/javascript" src="radiacion.js"></script> </body> </html> <!--<a href="#" id="get-data">Get JSON data</a> <div id="show-data"></div>--> |
Archivo JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
var uvradiation; var temperature; var pressure; var tiempoRefresh = 300000; var numberResults=20; window.setInterval(loadJson, tiempoRefresh); function cargarInfo() { loadJson(); drawChartUV(); drawChartTemp(); drawChartPress(); } function loadJson() { $.getJSON('https://api.thingspeak.com/channels/277292/feeds.json?results='+numberResults, function (data) { // Radiación UV uvradiation = Math.round(data.feeds[numberResults-1].field3); $('#divuv').text(uvradiation); // Temperatura temperature = Math.round(data.feeds[numberResults-1].field1); $('#divtemp').text(temperature); // Presión pressure = Math.round(data.feeds[numberResults-1].field2); $('#divpress').text(pressure); }); } google.charts.load('current', {'packages':['gauge', 'line', 'corechart']}); google.charts.setOnLoadCallback(drawChartUV); function drawChartUV() { var data = google.visualization.arrayToDataTable([ ['Label', 'Value'], ['UV', 0] ]); var options = { animation:{ duration: 500, easing: 'out', }, min:0, max:15, width: 400, height: 120, greenFrom:0, greenTo:4, redFrom: 7, redTo: 15, yellowFrom:4, yellowTo: 7, minorTicks: 4 }; var chart = new google.visualization.Gauge(document.getElementById('chartuv_div')); chart.draw(data, options); setInterval(function() { data.setValue(0, 1, uvradiation); chart.draw(data, options); }, 13000); } google.charts.setOnLoadCallback(drawChartTemp); function drawChartTemp() { var data = google.visualization.arrayToDataTable([ ['Label', 'Value'], ['Temp', 0] ]); var options = { animation:{ duration: 500, easing: 'out', }, min:-5, max:45, width: 400, height: 120, greenFrom:15, greenTo:30, redFrom: 35, redTo: 45, yellowFrom:30, yellowTo: 35, minorTicks: 10 }; var chart = new google.visualization.Gauge(document.getElementById('charttemp_div')); chart.draw(data, options); setInterval(function() { data.setValue(0, 1, temperature); chart.draw(data, options); }, 13000); } google.charts.setOnLoadCallback(drawChartPress); function drawChartPress() { var data = google.visualization.arrayToDataTable([ ['Label', 'Value'], ['Pres', 0] ]); var options = { animation:{ duration: 500, easing: 'out', }, min:800, max:1200, width: 400, height: 120, greenFrom:990, greenTo:1200, redFrom: 800, redTo: 990, minorTicks: 5 }; var chart = new google.visualization.Gauge(document.getElementById('chartpres_div')); chart.draw(data, options); setInterval(function() { data.setValue(0, 1, pressure); chart.draw(data, options); }, 13000); } |
Conclusiones Sigfox y Arduino MKRFOX1200 con sensor radiación UV
Que más voy a contar de las bondades que nos ofrece una placa como Arduino MKRFOX1200. Has visto a lo largo de este tutorial cómo se puede configurar un dispositivo que se conecte a Sigfox.
No lo he detallado mucho debido a que está en fase de prototipado todavía. La idea es seguir evolucionando el dispositivo para que cualquier persona u organismo lo pueda replicar en su ciudad.
¿Tienes alguna experiencia con Sigfox?
¿Crees que es útil este dispositivo del IoT con Arduino MKRFOX1200?
Cualquier duda o comentario aquí abajo, gracias :)
Puedes escuchar este programa en, iVoox, iTunes y en Spreaker. Si lo haces, por favor valora y comenta, así podremos llegar a más gente.
Gracias a Shutterstock por ceder los derechos de las siguientes imágenes: