Programar fácil con Arduino

Programar fácil con Arduino, entiende cómo funciona el mundo.

  • Blog
  • ¿Quién soy?
  • Podcast
  • Curso Arduino [GRATIS]
  • Curso Domótica [GRATIS]
  • Acceder
Usted está aquí: Inicio / Podcast / #114 Sigfox, Arduino MKRFOX1200 y un medidor de radiación UV

#114 Sigfox, Arduino MKRFOX1200 y un medidor de radiación UV

Comentarios(12)
Luis del Valle Hernández

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
sigfox arduino mkrfox1200

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.

estaciones radiación UV comunidad valenciana
Estaciones radiación UV comunidad valenciana. Fuente GVA.

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.

espectro electromagnético

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.
penetracion radiacion uv

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:

  • S12SD
  • Waveshare-module
  • WEONE
  • ML8511

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 sensor uv

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.

salida voltaje ml8511
respuesta espectral ml8511

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.

MKRFOX1200 PLACA

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.

  • Arduino MKRFOX1200
  • Introducción a Arduino MKRFOX1200
  • Estación meteorológica con Arduino MKRFOX1200

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.

conector bateria mkrfox1200

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 sensor 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.

MKRFOX1200 BMP180 ML8511 SIGFOX

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.

configuracion thingspeak 1

Crea un nuevo canal

configuracion thingspeak 2

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.

configuracion thingspeak 3

En mi caso he utilizado solo 5 campos. Estos son los datos.

configuracion thingspeak 4

Una vez lo tengas creado ya lo puedes seleccionar en My Channels.

configuracion thingspeak 5

Si accedes podrás visualizar las gráficas, modificar el canal y acceder a las API Key para escribir y leer.

configuracion thingspeak 6

En API Keys está la información que utilizaremos para configurar la página web donde mostrar los datos.

configuracion thingspeak 7

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.

configuracion sigfox 1

Ahora haz click sobre el dispositivo. Aparecerá un menú y seleccionas Edit.

configuracion sigfox 2

Vete al menú de la derecha y haz click en CALLBACKS.

configuracion sigfox 3

Crea una nueva callback.

configuracion sigfox 4

De las opciones que se presentan, selecciona Custom Callback.

configuracion sigfox 5

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.

configuracion sigfox 6

Los datos que yo he utilizado son los siguientes.

configuracion sigfox 7

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.

configuracion sigfox 8

En las opciones del menú de la izquierda puedes ver los mensajes que has enviado.

configuracion sigfox 10

Si pinchas en la flecha hacia arriba, verás la llamada a la API Rest de Thingspeak con los datos obtenidos del Arduino MKRFOX1200.

configuracion sigfox 11

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:

  • Imagen 1
integraciones de Home Assistant

Integraciones de Home Assistant

En este tutorial voy a hablar de las integraciones de Home Assistant pero antes déjame contarte la historia de Jack, un norteamericano de bien, de los … [+ info...]

dispositivos inteligentes para el hogar

Tipos de dispositivos inteligentes para el hogar

En este artículo voy a hablar de los dispositivos domóticos o dispositivos inteligentes para el hogar que pueden ser integrados dentro de Home … [+ info...]

osciloscopios

Osciloscopio para proyectos con Arduino

Una imagen vale más que mil palabras. Seguro has escuchado esta frase alguna vez y es probable que en la mayoría de las ocasiones lo que dice sea … [+ info...]

Copyright © 2023 · Programar Fácil · Aviso legal

Utilizamos cookies propios y de terceros para mejorar nuestros servicios y experiencia de usuario. Si continua navegando, consideramos que acepta su uso.Aceptar Política de privacidad y cookies
Política de cookies

Privacy Overview

This website uses cookies to improve your experience while you navigate through the website. Out of these, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may affect your browsing experience.
Necessary
Siempre activado
Necessary cookies are absolutely essential for the website to function properly. This category only includes cookies that ensures basic functionalities and security features of the website. These cookies do not store any personal information.
Non-necessary
Any cookies that may not be particularly necessary for the website to function and is used specifically to collect user personal data via analytics, ads, other embedded contents are termed as non-necessary cookies. It is mandatory to procure user consent prior to running these cookies on your website.
GUARDAR Y ACEPTAR