Monitor de Co2 con sensor mh z19


¿Alguna vez se ha preguntado por qué a menudo se siente somnoliento o incluso cansado por la mañana después de dormir toda la noche? Hay muchas cosas que pueden provocar un sueño de mala calidad,   pero   dada la grave pandemia  al que nos estamos exponiendo  desgraciadamente, también  hay otra razón  contundente: una mayor  exposición a  agentes virulentos al no  estar suficientemente ventilado la estancia .

En efecto , ambas casuísticas citadas  se deben a una concentración inadecuada de dióxido de carbono (CO2) puesto que las personas emiten dióxido de carbono durante la respiración , lo  que implica que   la concentración de CO2 es uno de los principales factores que afectan la calidad del aire y con ello   la exposición a agentes infecciosos.

Por estas razones según los científicos  apuntan que puede ser interesante contar con  un medidor de CO2 para comprender si la concentración de CO2 en nuestro entorno  como afecta la calidad del aire.

Una concentración menor de 800 ppm se considera adecuada, aunque lo ideal es que ronde las 500 ppm. A partir de 800 ppm salta la alerta ya que la ventilación es deficiente, lo que facilita en gran medida la permanencia del virus en el aire, de tal forma que su capacidad de transmisión puede prolongarse durante varias horas.

Estos medidores se pueden comprar ya montados, pero  no dispondremos ningún nivel de mejora ni personalización ni interacción  y los de bajo coste además ofrecen muy poca precisión ,  por lo que vamos a  ver como construir  un medidor real para que entendamos como funciona y de paso podemos pensar en futuras mejoras .

 

La elección del sensor

En un prototipo puede que se vea tentado en usar  sensores del tipo  MQ135 , un sensor de calidad de aire barato) , que detecta NH3, NOx, alcohol, benceno, humo, CO2  y que hemos visto en numerosos proyectos en este blog.

Este  tipo sensores  son  módulos listo para usar para Arduino y Raspberry Pi  gracias a su doble salida analogica   y digital  (para el uso con laRPi se requiere un convertidor AD adicional a no ser que solo necesite la señal de haber superado el umbral  ajustable de disparo de la señal digital ,pero para Arduino la conexión es directa ). 


Los sensores de la serie MQ utilizan un pequeño elemento calefactor con un sensor electrónico-químico por lo que son sensibles a una amplia gama de gases y son adecuados para su uso en interiores. Es cierto que  tienen una alta sensibilidad y un tiempo de respuesta rápido, pero tardan unos minutos en dar lecturas precisas porque el sensor tiene que calentarse.

Estos sensores son  muy fáciles de de usar para medir la concentración de GLP, i-butano, propano, metano, alcohol, hidrógeno y humo en el aire, midiendo concentraciones de gas de 100 a 10000 ppm   siendo ideal para la detección de fugas de gas, alarmas de gas u otros proyectos de robótica y microcontroladores. 

Según el fabricante  en general este tipo de sensores tienen relativa poca precisión incluso después de aplicar la corrección de temperatura y humedad. Además  suelen  tener  un alto consumo de energía (800 mw) y un tiempo de precalentamiento  excesivo lo cual son bastantes inconvenientes para abandonarlo y probar con otro  tipo de sensor.

Hay bastantes sensores de CO2 en el mercado de precios muy variados: MG811 (~ 40 $), MH-Z14 WINSEN (~ 40 $), MH-Z19 WINSEN (~ 30 $), K-30 (~ 85 $), VERNIER CO2-BTA ( ~ 330 $).

Los  sensores de CO2 NDIR (infrarrojo no dispersivo) son el   tipo de sensor más común utilizado para medir el CO2, pues  tienen buena precisión y bajo consumo de energía aunque los precios son muy variados.

Un ejemplo de sensor NDIR es el sensor MH-Z19 tiene buenas características y muy buen precio, así que puede ser una buena opción.  Aquí algunos parámetros técnicos del sensor MH-Z19 :

Tensión de trabajo   4,5 V ~ 5,5 V CC
Corriente media   <85 mA
Nivel de interfaz   3,3 V
Rango de medición   0 ~ 5% VOL opcional
Señal de salida   PWM, UART
Tiempo de precalentamiento   3min
Tiempo de respuesta   T90 <90 s
Temperatura de trabajo   0-50C
Humedad de trabajo   0 ~ 95% de humedad relativa
Peso   15 g
Esperanza de vida   > 5 años
Dimensión   57,5 × 34,7 × 16 mm (largo × ancho × alto)

Este sensor e pequeña escala de uso general  utiliza el principio infrarrojo no dispersivo (NDIR) para detectar la presencia de CO2 en el aire, con buena selectividad y dependencia anaerobia, larga vida y cuenta con compensación de temperatura incorporada y al mismo tiempo  salida en serie, salida analógica y salida PWM. Además, tiene un precio contenido (en amazon unos 14€)

Hay varias  variantes de este sensor con diferentes rangos de medición:

  • 0 ~ 10000 ppm
  • 0 ~ 2000 ppm
  • 0 ~ 5000 ppm

Una opción interesante es la primera porque el modelo B es el más extendido y fácil de conseguir,  si bien  un nivel de CO2 superior a 2000 ppm no sería apropiado para un ambiente doméstico. 

Puede ser interesante montar un dispositivo móvil para poder medir el nivel de CO2 donde quiera dentro del hogar , puesto que como el voltaje de trabajo del MH-Z19 es de 4.5 ~ 5.5V DC, puede usarse la salida USB standard  o simplemente  3 baterías AA ) como fuente de alimentación.

 

Respecto a la visualización de los datos una pantalla OLED LCD 0.96 “I2C IIC SPI Serial 128X64 (en amazon unos 9€)  es una buena opción pues  es muy fácil usarla con nuestro Arduino  gracias a la conexión I2C , y claro las librerías gratuitas para Arduino

Para  poderla usar en nuestro proyecto , es importante tener en cuenta que necesitaremos  la biblioteca de controladores oled Adafruit SSD1306

Respecto al conexionado , no puede ser más sencillo, pues conectaremos la alimentación   del sensor ,la pantalla  y nuestro  arduino  a través de un interruptor al polo positivo de   un portapilas de 3 pilas de 1.5V. Obviamente  complementaremos las conexiones de VCC  con las  masa (0v) conectando el  polo negativo del portapilas a las conexiones de 0v del sensor ,la pantalla  y nuestro  arduino.  

El montaje se complementará con las conexiones de datos  del  sensor MH-Z19    y de la pantalla , conectando la salida PWM del  sensor digital  al pin 7 (pin digital 7) de Arduino ,  y las conexiones de datos I2C  de la pantalla a los pines  SDA( pin 19)   y   pin SCL(pin 18) de nuestra placa Arduino. 

 

Medidor de CO2 MH-Z19

Este  es el resumen de elementos básicos de  hw para hacer este pequeño proyecto:

  • Sensor de co2 infrarrojo MH-Z19 (en amazon unos 14€)
  • Arduino Pro Micro  ( o cualquier otra placa Arduino que disponga)
  • Pantalla OLED LCD 0.96 “I2C IIC SPI Serial 128X64 (en amazon unos 9€)
  • Soporte de batería 3 AAA 1.5V 
  • Interruptor

Implementación

Necesitaremos lo siguientes elementos software para implementar este proyecto

Respecto al   proyecto, cuyo código Arduino al completo podemos ver más abajo , de forma  simplificada  este es   su funcionamiento: 

Primero importamos las librerías  para el control de la  pantalla I2C

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

A continuación definiremos las variables, empezando definiendo el pin 7 para el pwm para el sensor de Co2,  constantes, etc   destacando el valor del precalentamiento para el sensor de co2  cuyo valor es de 120 segundos

#define pwmPin 7        
int preheatSec = 120;
int prevVal = LOW;
long th, tl, h, l, ppm = 0;

Ahora veremos la  parte esencial , cuya principal ocupación es proporcionar el valor de la medida de C02 en la variable ppm 

void PWM_ISR() {
long tt = millis();
int val = digitalRead(pwmPin);

if (val == HIGH) {
if (val != prevVal) {
h = tt;
tl = h - l;
prevVal = val;
}
} else {
if (val != prevVal) {
l = tt;
th = l - h;
prevVal = val;
ppm = 2000 * (th - 2) / (th + tl - 4);
}
}
}

Otra  función  importante es la inicialización de la pantalla OLED , que  conseguiremos al introducirla en la función setup

void setup() { 
Serial.begin(115200);
pinMode(pwmPin, INPUT);
attachInterrupt(digitalPinToInterrupt(pwmPin), PWM_ISR, CHANGE);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3C (for the 128x64)
display.setTextColor(WHITE);
}

Dado el intervalo de precalentamiento , es interesante una función que presente la cuenta atrás para que el usuario sea consciente de que es necesario esperar ese intervalo:

void displayPreheating(int secLeft) {
display.setTextSize(2);
display.println("PREHEATING");
display.setTextSize(1);
display.println();
display.setTextSize(5);
display.print(" ");
display.print(secLeft);
display.display();
}

Obviamente tampoco nos puede faltar la visualización del nivel de ppm , que solo se mostrará si es superior  a 1000 ppm ( obviamente podemos ajustar este umbral al valor que deseemos).

void displayPPM(long ppm) {
display.setTextSize(2);
display.println("CO2 PPM");
display.setTextSize(1);
display.println();
display.setTextSize(5);
if (ppm < 1000) {
display.print(" ");
}
display.print(ppm);
display.display();
Serial.println(ppm);
}

Finalmente en el bucle principal  básicamente  borraremos la pantalla y mostraremos la  cuenta atrás  del precalentamiento para finalmente mostrar el nivel de ppm  cada 1000ms.

void loop() { 
display.clearDisplay();
display.setCursor(0,0);
if (preheatSec > 0) {
displayPreheating(preheatSec);
preheatSec--;
}
else {
displayPPM(ppm);
}
delay(1000);
}

 

Para terminar, IhorMelynk nos ofrece el código fuente para Arduino que el mismo cargó en su Arduino:

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif

#define pwmPin 7

int preheatSec = 120;
int prevVal = LOW;
long th, tl, h, l, ppm = 0;

void PWM_ISR() {
long tt = millis();
int val = digitalRead(pwmPin);

if (val == HIGH) {
if (val != prevVal) {
h = tt;
tl = h - l;
prevVal = val;
}
} else {
if (val != prevVal) {
l = tt;
th = l - h;
prevVal = val;
ppm = 2000 * (th - 2) / (th + tl - 4);
}
}
}

void setup() {
Serial.begin(115200);
pinMode(pwmPin, INPUT);
attachInterrupt(digitalPinToInterrupt(pwmPin), PWM_ISR, CHANGE);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3C (for the 128x64)
display.setTextColor(WHITE);
}

void displayPreheating(int secLeft) {
display.setTextSize(2);
display.println("PREHEATING");
display.setTextSize(1);
display.println();
display.setTextSize(5);
display.print(" ");
display.print(secLeft);
display.display();
}

void displayPPM(long ppm) {
display.setTextSize(2);
display.println("CO2 PPM");
display.setTextSize(1);
display.println();
display.setTextSize(5);
if (ppm < 1000) {
display.print(" ");
}
display.print(ppm);
display.display();
Serial.println(ppm);
}

void loop() {
display.clearDisplay();
display.setCursor(0,0);
if (preheatSec > 0) {
displayPreheating(preheatSec);
preheatSec--;
}
else {
displayPPM(ppm);
}
delay(1000);
}

 

Teniendo esto en cuenta, a la hora de mantener el contacto social los espacios al aire libre se presentan como la mejor alternativa. En espacios cerrados la ventilación es fundamental. No es suficiente con abrir las ventanas 10 minutos cada hora. La ventilación debe ser constante. Por supuesto, en ambos casos la mascarilla sigue siendo un elemento de protección esencial.

 

 

 

 

 

 

 

Controlar un potenciometro con Arduino Iot Cloud


En este post vamos avanzar en las posibilidades de la placa MKR1000 (o MKR 1010) a la nube de Arduino IoT  de modo que podremos hacer cosas mas complejas mas allá de encender o apagar un led  a distancia ( como vimos en este post ). En esta ocasión como ejemplo de la gran potencia de de esta solución  vamos a   leer en remoto las posición de un potenciometro  a través de Internet utilizando el sitio web de Arduino IoT Cloud.

Si le  interesa  como hacerlo, vera que es muy sencillo,  pues como vamos a ver  casi todo esta hecho, pero antes, volvamos a  ver  las semejanzas   y diferencias de ambas placas,  y después veremos paso a paso como lograrlo.

Arduino MKR1000

Arduino MKR1000 es una placa diseñada para ofrecer una solución práctica y rentable para cualquiera que busque agregar conectividad WiFi a sus proyectos con una experiencia mínima en redes.  Su precio no es excesivo  teniendo en cuenta que integra la conectividad  wifi (unos 38€ en Amazon).

El diseño incluye un circuito de carga Li-Po que permite que el Arduino MKR1000 funcione con una  batería o 5V externos, cargando la batería Li-Po mientras funciona con energía externa: el cambio de una fuente a otra se realizara automáticamente  y por tanto no tendremos que preocuparnos de nada más.

El MKR1000 tiene un procesador Arm Cortex-M0 + de 32 bits  corriendo a 2.4ghz ,  y cuenta con  el rico conjunto habitual de interfaces de E / S . Sin duda uno de su punto fuertes  es que integra  WiFi de baja potencia con un chip criptográfico para una comunicación segura.

Una de las grandes ventajas  es que puede programarlo utilizando el software Arduino (IDE) al que estamos  todos familiarizados  siendo muy  fácil de usar.

Todas estas características hacen de esta placa la opción preferida para los proyectos emergentes que funcionan con baterías de IoT en un factor de forma compacto.

 

 Como   se puede  ver en la imagen de  mas abajo , los pines disponibles son casi los mismos que los que solemos tener en un Arduino convencional  : los pines A0  a A6   para entradas  y salidas analógicas , los pines 0 al 14  para entradas salidas binarias y los típicos de alimentación externa(VIN,VCC 5v y GND)   , la referencia (AREF )  y  RESET.

 

Si le interesa esta placa la puede comprar en Amazon por unos 38€

Arduino MKR1010

Hablamos ahora de una placa muy similar a la anterior   algo mas barata que la la Mkr1000 ( unos  33€  en Amazon , es decir unos 5€ mas barato que la MKR1000)

Esta placa  está compuesta por tres bloques principales:

  • Microchip ATSAMD21 MCU basado en un procesador Arm Cortex-M0 
  • Serie u-blox NINA-W10 de baja potencia 2.4GHz IEEE 802.11 b / g / n Wi-Fi ECC508 CryptoAuthentication
  • El diseño incluye un Li-Po Circuito de carga que permite que Arduino MKR WiFi 1010 funcione con batería o 5V externos, cargando la batería Li-Po mientras funciona con energía externa. El cambio de una fuente a otra se realiza automáticamente.

Como  vemos , la gran diferencia  es  el Microcontrolador que es menos potente  pues  cuenta con el  Microchip ATSAMD21 (procesador Arm Cortex-M0 +)  en contraste  con el Arm Cortex-M0 + de 32 bits  corriendo a 2.4ghz del MKR100.

Respecto a la conectividad,  es similar al  MKR1000  contando con WiFi u-blox NINA-W102 (ESP32)

La alimentación se puede hacer con una fuente de alimentación externa de 5v DC  bien por  USB  o bien por el pin VIN , pero  cuenta   además  con conexión para Batería compatible (*) Li-Po de celda única, 3,7 V, 700 mAh  siendo el voltaje mínimo de funcionamiento del circuito 3,3 V .

 

Como   se puede  ver en la imagen de  mas abajo , los pines disponibles son casi los mismos que los que solemos tener en un Arduino convencional  ( y los mismo que el  MKR100)   : los pines A0  a A6   para entradas  y salidas analógicas , los pines 0 al 14  para entradas salidas binarias y los típicos de alimentación externa(VIN,VCC 5v y GND)   , la referencia (AREF )  y  RESET.

Si le interesa esta placa la puede comprar en Amazon por unos 33€

Agregar un potenciómetro 

Ahora que tenemos confirmación de todo lo que funciona ( como vimos en este post ), podemos agregar nuevas propiedades a nuestra Cosa. Vincularemos la nueva propiedad a un potenciómetro que necesita ser añadido al circuito. El potenciómetro está conectado a la alimentación y a tierra a través de sus respectivos pines y el pin de señal está conectado al Pin analógico A1 de la placa Arduino.

Adding an analog sensor to our breadboard

Para agregar una nueva propiedad vamos a proceder como lo hicimos anteriormente: mientras que en nuestra vista de propiedades de Thing, hagamos clic en el botón + y cree una propiedad denominada .

Establezca el tipo en Int con valor mínimo y valor máximo establecido en 0 y 270 respectivamente.

El permiso debe establecerse en Solo lectura y la propiedad debe actualizarse cuando cambie el valor;

Asimismo podemos establecer un valor Delta mayor que cero si queremos introducir alguna tolerancia para la actualización (por ejemplo: si establecemos Delta en 5, el valor de propiedad se actualizará a través de la nube solo cuando la diferencia entre el nuevo valor y el valor antiguo sea mayor que 5, de lo contrario se omitirá el cambio).

Al hacer clic en CREATE, se agregará la nueva propiedad a nuestra cosa y nos traerá de vuelta a la vista de edición de la propiedad.

Aunque no lo vemos, nuestro boceto se ha actualizado para reflejar los cambios, así que hagamos clic en EDIT CODE para volver al editor.

Mirando thingProperties.h, nos daremos cuenta de que se han añadido dos nuevas líneas:

int angle;

Esta linea declara la variable que representa la propiedad que acabamos de crear

ArduinoCloud.addProperty(angle, READ, ON_CHANGE, NULL, 5.000000);

Este código conecta la variable a su propiedad correspondiente, con permisos READ (es decir: no vamos a poder establecerla desde el panel). Debido al permiso de solo lectura, no se generará ninguna función de devolución de llamada y el penúltimo argumento del método se establece en . El último argumento representa el valor Delta descrito anteriormente.

Para hacer que el potenciómetro interactúe con la nube necesitamos definir el pin al que está conectado:

#define POTENTIOMETER_PIN A1

Luego, en la función, leemos la entrada analógica del potenciómetro y la mapeamos a la variable. De este modo, al girar el potenciómetro se refleja, se cambia el valor de propiedad correspondiente en el panel de la nube.

int angleSensor = analogRead(POTENTIOMETER_PIN);
angle = map(angleSensor, 0, 1023, 0, 270);

Vamos a subir nuestro boceto de nuevo y ver lo que sucede en el tablero de nuestra cosa cuando giramos la perilla del potenciómetro. Deberíamos ver el valor subiendo y bajando de 0 a 270 (esto puede variar con la calidad de construcción del potenciómetro).

Por último, vamos a agregar una última propiedad.  Esta nueva propiedad se asociará a un botón pulsador agregado al circuito anterior como se muestra en los esquemas siguientes: un pin del botón está conectado al riel de alimentación positivo (Vcc), el otro pin está conectado al pin digital 5 (a través del cable blanco) y a tierra a través de una resistencia desplegable de 10k.

Esta configuración fuerza un nivel lógico LOW en nuestro pin cuando el botón está en reposo, mientras que rutea Vcc a través cuando se presiona (nivel lógico HIGH).

Desde el editor, vaya a IOT CLOUD y cree una nueva propiedad denominada , con Tipo ON/OFF (Boolean),Solo lectura de permisos y Actualizar cuando cambie el valor. toggle

Una vez más EDIT CODE y volveremos al editor. Un vistazo rápido a thingProperties.h mostrará que una nueva variable se ha definido y asociado a su propiedad a través de .ToggleArduinoCloud.addProperty(...)

En nuestro archivo .ino definiremos el nuevo pin y dos variables relacionadas con el estado del botón : es decir el estad actual ( btnState) y el estado anterior(btnPrevState) .btnPrevState es necesario porque queremos que la propiedad se actualice solo una vez cuando se presiona el botón y no cuando se libera.

#define BUTTON_PIN 5
int btnState;
int btnPrevState = 0;

Entonces,es importante destacar   la linea que establece como entrada  este pin para

pinMode(BUTTON_PIN, INPUT);

Y finalmente añadimos estas líneas hacia el final de la loop()

btnState = digitalRead(BUTTON_PIN);
if (btnPrevState == 0 && btnState == 1) {
 toggle = !toggle;
}
btnPrevState = btnState;

Con este sencillo código  el botón actúa como un interruptor y al presionarlo debemos ver el interruptor en la nube cambiando en consecuencia alternando  entre ON y OFF.

En este código hay un pequeño problema  pues como puede adivinar no hay gestión de los rebotes (debounce en ingles  )  , es decir la cantidad de ruido ocurrido tras el flanco cuando actuamos sobre el pulsador(en esencia, en el rango de unos microsegundos la señal es puro ruido) . Todos esos picos pueden provocar disparos múltiples de una interrupción. Disponemos de dos formas de aplicar el rebote :añadiendo dispositivos electrónicos que filtren la señal o modificando nuestro código para eliminar el rebote 

 Vamos a ir más allá y simplificar nuestro código de administración de botones usando una biblioteca adicional.

 Usar una biblioteca de anti-rebotes

El código que hemos visto se basa en variables temporales porque necesitábamos almacenar el estado anterior del botón, lo que no hace que el boceto sea sencillo de implementar  , pero  la cosa se complica con los efectos de los rebotes  o la necesidad  de utilizar varios botones ( que añadiría muchas variables).

Una solución fácil es utilizar una biblioteca de rebote,y vamos a confiar en FTDebouncer que se puede instalar a través del Administrador de bibliotecas.

Simplemente vamos a Bibliotecas desde el menú de la barra lateral, ingresamos “FTDebouncer” en el campo de búsqueda en la parte superior y presionamos Intro: aparecerá la biblioteca y podemos añadirla a nuestro boceto pulsando el botón INCLUIR.

Esto agregará la siguiente línea a la pestaña seleccionada actualmente

#include <FTDebouncer.h>

Antes de esto podemos  reemplazar la definición de variables relacionadas con el estado del botónsetup()

int btnState;
int btnPrevState = 0;

con la declaración de una variableFTDebouncer

FTDebouncer buttons;

a continuación, reemplazar la línea donde inicializamos el pin del botón

pinMode(BUTTON_PIN, INPUT);

con las siguientes dos líneas

buttons.addPin(BUTTON_PIN, LOW);
buttons.init();

Al principio le podemos a añadimos este comando antes de loop()

buttons.update();

y eliminar todo el código escrito previamente relacionado con el botón

btnState = digitalRead(BUTTON_PIN);
if (btnPrevState == 0 && btnState == 1) {
    toggle = !toggle;
}
btnPrevState = btnState;

Finalmente, al final del boceto vamos a añadir una función

void onPinActivated(uint8_t pinNr){
	Serial.println(pinNr);
	toggle = !toggle;
}
void onPinDeactivated(uint8_t pinNr){
	Serial.println(pinNr);
}

Gracias a la biblioteca, se llamará a la función (sólo una vez) cuando se pulse el botón. Cuando esto suceda, le diremos a nuestra propiedad que cambie a su valor opuesto. Si es cierto, se volverá falso y viceversa. Esta acción la realiza el operador “!”,también conocido como LogicalNOToperator.FTDebounceronPinActivated()toggle

Si queremos que se ejecute algún código cuando se suelte el botón, la biblioteca llamará a la siguiente función cuando eso suceda. 

 

IoT Cloud


En este post vamos a a ver conectar una placa MKR1000 (o MKR 1010) a la nube de Arduino IoT  de modo que podremos controlar y supervisar  las entradas  o salidas de estas places a través de Internet utilizando el sitio web de Arduino IoT Cloud.

Para ello simplemente seguiremos tres pasos,:

  • Agregaremos nuestra placa a Arduino IoT Cloud como una cosa( Thing) , es decir  una representación de nuestra placa en la nube.
  • A continuación, le daremos a nuestra cosa un conjunto de propiedades que representan sensores, LEDs, motores y muchos otros componentes en el proyecto al que queremos acceder desde la nube.
  • Subiremos a nuestra placa el código que nos propone Arduino IoT Cloud personalizado para nuestra red wifi

Si le  interesa  como hacerlo , vera que es muy sencillo,  pues como vamos a ver  casi todo esta hecho, pero antes, veremos las semejanzas   y diferencias de ambas placas  y después veremos paso a paso como lograrlo.

Arduino MKR1000

Arduino MKR1000 es una placa diseñada para ofrecer una solución práctica y rentable para cualquiera que busque agregar conectividad WiFi a sus proyectos con una experiencia mínima en redes.  Su precio no es excesivo  teniendo en cuenta que integra la conectividad  wifi (unos 38€ en Amazon)

El diseño incluye un circuito de carga Li-Po que permite que el Arduino MKR1000 funcione con una  batería o 5V externos, cargando la batería Li-Po mientras funciona con energía externa: el cambio de una fuente a otra se realizara automáticamente  y por tanto no tendremos que preocuparnos de nada más.

El MKR1000 tiene un procesador Arm Cortex-M0 + de 32 bits  corriendo a 2.4ghz ,  y cuenta con  el rico conjunto habitual de interfaces de E / S . Sin duda uno de su punto fuertes  es que integra  WiFi de baja potencia con un chip criptográfico para una comunicación segura.

Una de las grandes ventajas  es que puede programarlo utilizando el software Arduino (IDE) al que estamos  todos familiarizados  siendo muy  fácil de usar.

Todas estas características hacen de esta placa la opción preferida para los proyectos emergentes que funcionan con baterías de IoT en un factor de forma compacto.

 Desafortunadamente, Arduino aún no lo ha integrado en su IDE, por lo que la configuración no es tan fácil como lo es para la mayoría de sus otras placas ,sin embargo, siga algunos pasos para configurarlo y podrá ponerlo a prueba: –

  • Instale el último IDE de Arduino 
  •  Haga clic en Herramientas | Puerto – Seleccione el puerto COM (no se mostrará ninguna placa) 
  • Ahora haga clic en Herramientas | Junta | Obtener información del tablero. Verá información con “Tablero desconocido” como tipo
  •  A continuación, haga clic en Herramientas | Junta | Gerente de la Junta
  • Instale el paquete Arduino SAMD Boards (ARM Cortex-M0 + de 32 bits) que incluye MKR WiFi 1010, Genuino Zero, MKR1000, etc.
  • Reinicie el IDE para que surta efecto el nuevo paquete de placa
  • En este punto, puede desconectar y volver a conectar la placa para que el IDE lo vea
  • Haga clic en Herramientas | Información del tablero; esta vez verá “Arduino / Genuino MKR1000” !!! ¡No olvides este siguiente paso o no podrás subir tu boceto!
  • Haga clic en Herramientas | Tablero: 
  • Seleccione Arduino / Genuino MKR1000 . En este punto, yaa puede cargar un boceto en su tablero  como  por ejemplo el que vamos a ver en este post para controlar un led desde Internet

Como   se puede  ver en la imagen de  mas abajo , los pines disponibles son casi los mismos que los que solemos tener en un Arduino convencional  : los pines A0  a A6   para entradas  y salidas analógicas , los pines 0 al 14  para entradas salidas binarias y los típicos de alimentación externa(VIN,VCC 5v y GND)   , la referencia (AREF )  y  RESET.

Si le interesa esta placa la puede comprar en Amazon por unos 38€

Arduino MKR1010

Hablamos ahora de una placa muy similar a la anterior   algo mas barata que la la Mkr1000 ( unos  33€  en Amazon , es decir unos 5€ mas barato que la MKR1000)

Esta placa  está compuesta por tres bloques principales:

  • Microchip ATSAMD21 MCU basado en un procesador Arm Cortex-M0 
  • Serie u-blox NINA-W10 de baja potencia 2.4GHz IEEE 802.11 b / g / n Wi-Fi ECC508 CryptoAuthentication
  • El diseño incluye un Li-Po Circuito de carga que permite que Arduino MKR WiFi 1010 funcione con batería o 5V externos, cargando la batería Li-Po mientras funciona con energía externa. El cambio de una fuente a otra se realiza automáticamente.

Como  vemos , la gran diferencia  es  el Microcontrolador que es menos potente  pues  cuenta con el  Microchip ATSAMD21 (procesador Arm Cortex-M0 +)  en contraste  con el Arm Cortex-M0 + de 32 bits  corriendo a 2.4ghz del MKR100.

Respecto a la conectividad,  es similar al  MKR1000  contando con WiFi u-blox NINA-W102 (ESP32)

La alimentación se puede hacer con una fuente de alimentación externa de 5v DC  bien por  USB  o bien por el pin VIN , pero  cuenta   además  con conexión para Batería compatible (*) Li-Po de celda única, 3,7 V, 700 mAh  siendo el voltaje mínimo de funcionamiento del circuito 3,3 V .

 

Como   se puede  ver en la imagen de  mas abajo , los pines disponibles son casi los mismos que los que solemos tener en un Arduino convencional  ( y los mismo que el  MKR100)   : los pines A0  a A6   para entradas  y salidas analógicas , los pines 0 al 14  para entradas salidas binarias y los típicos de alimentación externa(VIN,VCC 5v y GND)   , la referencia (AREF )  y  RESET.

Si le interesa esta placa la puede comprar en Amazon por unos 33€

 

1. Crear una cosa y controlar un LED a través de la nube

Para empezar vamos a crear un circuito simple que consiste en un LED conectado a la placa Arduino MKR1000  (o MKR 1010).

Como se muestra en el esquema, simplemente conectaremos la pata positiva del LED al Pin digital 2 de la placa y la pata negativa a tierra a través de una resistencia de 150 ohmios.

Observe que la potencia de la placa de pan proviene del Vcc, no del pin de 5V de la placa MKR1000 pues  si lo conectamos al pin de 5V, podríamos dañar la placa  cuando por ejemplo  agreguemos  un botón.

An LED connected to Digital Pin 2 of an Arduino MKR1000

Ahora que hemos conectado nuestro LED, podremos  habilitado para IoT pero antes de eso, tendremos que configurar una placa Arduino para que pueda comunicarse con la nube.

Para este proyecto, podemos elegir un MKR1000 o un MKR  1010.  Una vez que nuestra placa está configurada, necesitaremos crear a una cuenta Arduino  ( ai aún no la tenemos creada, y hecho ya nos iremos a Arduino IoT Cloud y comenzaremos  con el  viaje a través de IoT 

Asi pues nos  iremos  Arduino IoT Cloud que comenzara con el proceso guiado de introducción  que nos ayudará a configurar nuestra placa, darle un nombre e instalar las claves que le permitirán conectarse de forma segura a nuestra nube mediante un canal cifrado.

Getting Started Wizard
Este es el asistente de introducción
Select a supported board
Seleccionaremos  una placa compatible
Let's make it connect securely to IoT Cloud
Haremos que se conecte de forma segura a IoT Cloud
Time to plug our board into our computer, it will be recognised automatically
Es hora de conectar nuestra placa a nuestro ordenador, se reconocerá automáticamente
Let's give it a name...
Vamos a darle un nombre…
and click on CONFIGURE
Ahora  haremos clic en CONFIGURAR
After a little time all is done, and we can get BACK TO CLOUD
Después de un poco de tiempo todo está hecho, y podemos llegar DE VUELTA A CLOUD

Al hacer clic en el botón “BACK TO CLOUD” podremos crear nuestra primera Cosa.

Nuestra placa MKR recién configurada se seleccionará automáticamente para ser asociada con nuestra Cosa, por lo que todo lo que queda es darle un nombre. Elegimos llamarlo IoTCloud_Tutorial_Thing pero puede nombrarlo como desee.

 

Our board is preselected ->
Nuestra placa está preseleccionada ->
Let's name it...
Vamos a nombrarlo…
and click the CREATE button
y haga clic en el botón CREAR

Ahora seremos redirigidos a nuestra vista de edición de Thing, donde podremos crear y modificar sus Propiedades – la representación de sensores y actuadores a los que queremos acceder a través de la nube.

Nuestro objetivo es encender y apagar el LED a través de Cloud cuando alternamos un interruptor gráfico en nuestro navegador. Para hacerlo, tenemos que crear una propiedad, así que haga clic en el botón + como se muestra en la imagen de abajo.

Time to create our first Property
Es hora de crear nuestra primera propiedad

Usaremos como nombre significativo que lo represente  (este nombre se reflejará en el nombre de la variable que usaremos en el boceto) como por ejemplo dado que va ser un led   de  “.light"

El Tipo de esta propiedad debe ser “ON/OFF (Boolean)”.

Our properties details are set, let's CREATE it
Nuestros detalles de propiedades están establecidos  así que vamos vamos a crearlo

Podemos dejar El permiso establecido en “Leer y escribir” – para que podamos encender y apagar el LED desde el navegador. 

También deje Actualizar en “Cuando cambie el valor”, lo cual  asegurará de que siempre que el valor de la propiedad/variable cambie dentro del boceto de la placa, dicho valor se enviará inmediatamente a la nube.

Finalmente haga clic en CREAR.

Property Edit view
Vista de edición de propiedades
Dashboard view
Vista del panel

 

Desde la vista Editar podemos hacer clic en “EDITAR CODE”. Esto nos redirigirá al Editor mostrando un boceto ya hecho que se ha generado para nuestra Cosa.

En este caso de ejemplo se generará el siguiente código que tendremos que cargar en nuestra placa:

 

*
Sketch generated by the Arduino IoT Cloud Thing "testThing"
https://create.arduino.cc/cloud/things/d276ab77-67cb-420b-9ea4-bd34cdf385d9



Arduino IoT Cloud Properties description



The following variables are automatically generated and updated when changes are made to the Thing properties



bool switchState;
int potentiometerValue;
bool ledState;



Properties which are marked as READ/WRITE in the Cloud Thing will also have functions
which are called when their values are changed from the Dashboard.
These functions are generated with the Thing and added at the end of this sketch.
*/



include "thingProperties.h"



include



define LED_PIN 2



define POT_PIN A1



define BUTTON_PIN 5



FTDebouncer buttons;



void setup() {
pinMode(LED_PIN, OUTPUT);
buttons.addPin(BUTTON_PIN, LOW);
buttons.init();



/*
The following function allows you to obtain more information
related to the state of network and IoT Cloud connection and errors
the higher number the more granular information you’ll get.
The default is 0 (only errors).
Maximum is 3
*/
setDebugMessageLevel(2);



// Initialize serial and wait for port to open:
Serial.begin(9600);
// This delay gives the chance to wait for a Serial Monitor without blocking if none is found
delay(1500);



// Defined in thingProperties.h
initProperties();



// Connect to Arduino IoT Cloud
ArduinoCloud.begin(ArduinoIoTPreferredConnection);
}



void loop() {
buttons.update();
ArduinoCloud.update();
// Your code here
int angleSensor = analogRead(A1);
angle = map(angleSensor, 0, 1023, 0, 270);
}



void onLightChange() {
digitalWrite(LED_PIN, light);
Serial.print("The light is ");
if (light) {
Serial.println("ON");
} else {
Serial.println("OFF");
}
}



void onPinActivated(uint8_t pinNr) {
// do something according to the _pinNR that is triggered. For instance:
Serial.println(pinNr);
toggle = !toggle;
}



void onPinDeactivated(uint8_t pinNr) {
// do something according to the _pinNR that is triggered. For instance:
Serial.println(pinNr);
}

 

El boceto se denominará exactamente igual que nuestra Cosa, más la fecha de creación y, finalmente, un número si ya existe un boceto con nombre .

Aparte del archivo .ino principal , verá tres archivos más:

  • ReadMe.adoc: se trata de un archivo de texto sin formato que contiene información sobre el boceto, el autor y el propio proyecto.
  • thingProperties.h: este es el código generado por Arduino IoT Cloud cuando agregamos nuestra propiedad. No necesitamos editar este código, pero es útil verlo ya que muestra qué variablesde nuestro archivo de boceto principal (.ino) se sincronizarán con la nube.light
  • En la Pestaña Secreto: Detalles de la conexión WiFi,  esta pestaña nos permite rellenar los valores  como  son el nombre y la contraseña de la red WiFi a la que se conectará nuestra placa.SECRET_SSIDSECRET_PASS

 

Vamos a profundizar en cada línea de este boceto para entender lo que hacen los difrentes ficheros qeu lo compone:

Fichero thingProperties.h

#include <ArduinoIoTCloud.h>

Importa la biblioteca ArduinoIoTCloud, que es necesaria para sincronizar nuestras variables de boceto locales con sus propiedadesde IoT Cloud.

#include <Arduino_ConnectionHandler.h>

El WiFiConnectionManager se utiliza para gestionar la conexión WiFi y la reconexión sin problemas.

char ssid[] = SECRET_SSID;
char pass[] = SECRET_PASS;

Estos valores se extraen de la pestaña Secreto.

#define THING_ID "d276ab77-67cb-420b-9ea4-bd34cdf385d9"

El código de identificación único de la cosa.

void onLightChange();

Esta línea declara una función que se llamará cada vez que se cambia el valor de nuestra propiedad en el panel. Este tipo de función se conoce como devolución de llamada.light

bool light;

Declaración de la variable.light

void initProperties()

Esta función se llamará dentro del bloque de nuestro archivo *.ino. setup()

ArduinoCloud.setThingId(THING_ID);

Le dice a nuestro boceto a qué cosa conectarse.

ArduinoCloud.addProperty(light, READWRITE, ON_CHANGE, onLightChange);

Este código pues le indica al sketch que trate la variable como una propiedad de nuestra cosa y que ejecute la función de devolución de llamada cada vez que se cambie el valor de propiedad de Arduino IoT Cloud.

Los permisos se establecen para esta propiedad porque esto es lo que seleccionamos al crear esta propiedad.lightonLightChangeREADWRITE

 

El resto de codigo es  el siguiente:

void onLightChange();

bool toggle;
int angle;
bool light;

void initProperties(){
ArduinoCloud.setThingId(THING_ID);
ArduinoCloud.addProperty(toggle, READ, ON_CHANGE, NULL);
ArduinoCloud.addProperty(angle, READ, ON_CHANGE, NULL, 3.000000);
ArduinoCloud.addProperty(light, READWRITE, ON_CHANGE, onLightChange);
}

WiFiConnectionHandler ArduinoIoTPreferredConnection(ssid, pass);

 

Este código Inicializa Connection Manager con el nombre de punto de acceso WiFi (SECRET_SSID) y la contraseña (SECRET_PASS)que establecemos en la pestaña Secreto

 

Fichero *.ino

Al igual que en cualquier Arduino Sketch, hay dos funciones principales, y . Se llama una sola vez; cuando el croquis se inicia o se restablece. El se ejecuta continuamente siempre y cuando la placa esté siendo alimentada.void setup(){...}void loop() {...}setup()loop()

#include "thingProperties.h"

Importa variables y funciones declaradas en thingProperties.h, así como en otras bibliotecas importadas.

setDebugMessageLevel(2);

Establece el nivel deseado de mensajes de registro que se imprimirán en el Monitor serie. En este momento el nivel se establece en 2, pero podemos cambiarlo de0 (que registra sólo errores) hasta 3 (que registra TODO!). Si algo no está funcionando con la conexión a WiFi o Cloud, será más fácil encontrar el problema si se establece en un nivel superior. Por ahora, podemos dejarlo como está.

Serial.begin(9600);

Inicializa el monitor seriepara imprimir lo y leer deél.

delay(1500);

Espera 1,5 segundos para dar al Monitor serie el tiempo necesario para inicializar.

initProperties();

Inicializa las propiedades tal como se definen en thingProperties.h.

ArduinoCloud.begin(ArduinoIoTPreferredConnection);

InicializatheArduinoCloudusingthe mencionado anteriormente ConnectionManager.

Dentro de lo que encontramosloop()

ArduinoCloud.update();

Maneja muchas cosas en segundo plano, incluyendo la sincronización de los valores de las propiedades entre la nube y la placa, checkingtheconnectiontonetworkyCloudy otra lógica. Si el valor de una propiedad cambia en el boceto, la biblioteca la detectará automáticamente y notificará a la nube, de modo que dicho valor se reflejará en nuestro Arduino IoT Cloud Dashboard. Del mismo modo, cuando se cambia el valor de una propiedad en el panel, la biblioteca actualizará el valor correspondiente en el dispositivo.

void onLightChange() {...}

La implementación de nuestra devolución de llamada que se llamará en cualquier momento que cambie el valor de la propiedad. Aquí agregaremos cualquier código que queramos que se ejecute cuando cambie la propiedad de nuestro panel.light

Y ahora, con el fin de encender y apagar el LED desde el Arduino IoT Cloud Dashboard, necesitamos escribir algunas líneas de código. Primero definimos el pin al que está conectado nuestro LED. Agregue este código justo encima de la funciónsetup()

#define LED_PIN 2

En la función, necesitamos inicializar este pin para que sea una SALIDA:setup()

pinMode(LED_PIN, OUTPUT);

Por último, en la función, agregamos un poco de lógica para rastrear el estado en el monitor serie y para encender y apagar el LED. Tenga en cuenta que esta función de devolución de llamada se genera automáticamente cada vez que se agrega una nueva propiedad con permisos de lectura y escritura.onLightChange()light

void onLightChange() {
    digitalWrite(LED_PIN, light);
    Serial.print("The light is ");
    if (light) {
        Serial.println("ON");
    } else {
        Serial.println("OFF");
    }
}

 

Pruebas

Una vez preparados los ficheros  anteriores  podemos cargar el boceto desde el IDE de Arduino haciendo clic en el botón Cargar y luego abra el Monitor Serie a la izquierda para ver si todo funciona.

Debido a que hemos establecido el nivel de registro en 2, el Monitor serie nos mostrará información sobre el progreso de nuestra placa que se conecta a IoT Cloud.

Una vez conectado con éxito a nuestro WiFi, logró obtener una dirección e inició un enlace seguro, la placa se conectará a IoT Cloud y comenzará a intercambiar datos con ella.

[ 144313 ] Connecting to "FT Mobile"
[ 148284 ] Connected to "FT Mobile"
[ 148284 ] Acquiring Time from Network
....
[ 148690 ] Network Time: 1550057496
[ 148910 ] Connecting to Arduino IoT Cloud...
[ 152212 ] Connected to Arduino IoT Cloud

Si alguno de los pasos anteriores falla, recibiremos un error. Si eso sucede, podemos restablecer el tablero e intentarlo de nuevo. Si los pasos anteriores se han seguido cuidadosamente, es un caso poco probable 🙂

Al hacer clic en el botón GO TO IOT CLOUD seremos redirigidos a la página de nuestra Cosa en Arduino IoT Cloud. Desde aquí haremos clic en el botón del panel.

Dasboard view
En la Vista de Dasboard ya deberíamos ver un widget que muestra el estado de la propiedad que creamos, y debe establecerse en OFF.light

Vamos a hacer clic en él un par de veces y vamos a ver el LED encender y apagar… y ON… y OFF de nuevo…

¡Misión cumplida!