06-12-2017, 07:02 PM
Estoy dandole vueltas a hacer una especie de curso de IoT en el foro. He hecho esta guía sin profundizar en exceso y como ejemplo de lo que podría ser el contenido del SpainLabs IoT 2018. Dejo esta guía sobre el famoso módulo wifi ESP8266, pero en su versión integrada con todo lo necesario para funcionar NODEMCU LOLIN (existen varias versiones del NodeMCU), esta versión incorpora la revision esp-12E. Mas abajo pongo enlaces a todo el material usado. A este módulo wifi le vamos a añadir un sensor de temperatura, humedad y presión, todo esto en un solo sensor de 2mmx2mm! que podremos controlar vía I2C (existe también versión en SPI). Posteriormente, lo que vamos a hacer es visualizar por el monitor serie las medidas y enviarlas a un broker MQTT. Vamos a programar todo como si estuviéramos usando un arduino, gracias al framework que se ha ido creando por la comunidad. El protocolo MQTT es un protocolo usado para establecer comunicaciones con un consumo de datos mínimo. Tiene un uso generalizado en IoT, pero aplicaciones como Facebook también lo usan para su funcionamiento.
Fuente: prometec.net
Material:
NodeMCU LOLIN v3 CH340 (sobre 3€): http://*****.com/e/yZ7aeyb
Sensor BME280 en versión I2C (sobre 4€): http://*****.com/e/QFQfQzV
Existen 2 versiones del sensor ya soldadas en PCB. Una es para SPI y la otra I2C. El sensor en ambos casos es exactamente el mismo, pero según como lo configuremos, los pines van conectados de distinta forma.
Datasheet del sensor BME280: https://www.embeddedadventures.com/datas...BME280.pdf
¿Qué es el ESP8266 y el NodeMCU?
El ESP8266 es un chip con WiFi integrado, producido por la compañía china Espressif Systems, y que se ha vuelto muy popular en los últimos dos años debido a su bajo costo y a la posibilidad de usarse sin necesidad de un microcontrolador externo, ya que cuenta con su propio procesador y memoria interna, brindando la posibilidad de crear dispositivos IoT muy pequeños y de bajo costo.
Por su parte, el NodeMCU es un firmware de código abierto que permite programar fácilmente el ESP8266 en lenguaje Lua, y el NodeMCU dev kit, es la placa de desarrollo oficial de NodeMCU.El corazón del NodeMCU dev kit es el módulo ESP-12E, el cual pertenece a la familia ESP-XX de la compañía All-Thinker. La serie ESP-XX es una familia de módulos basados en el chip ESP8266, que cuenta con más de 10 modelos con características distintas adaptadas a cada necesidad. Se diferencian por el número de pines, cantidad de memoria interna, conector para antena externa en algunos casos, y otras características que debemos tener en cuenta a la hora de escoger uno para nuestros proyectos.
El NodeMCU dev kit está diseñado para facilitar el desarrollo de proyectos con ESP8266. La placa de desarrollo NodeMCU dev kit facilita el trabajo del desarrollador porque integra un convertidor FTDI, y un regulador de voltaje de 3,3V, lo cual permite programar el módulo y trabajar con él con solo conectar un cable USB a la computadora, además cuenta con pines para montar en el Protoboard.
Existen tres versiones de la placa NodeMCU:
- NodeMCU dev kit v0.9 o v1– La primera versión comercial.
- NodeMCU dev kit v1.0 o v2– Con módulo ESP-12E (enhanced).
- NodeMCU dev kit v3 – Producido por LoLin.
- Módulo ESP-12E
- Chip USB CH340G
- Conectividad WiFi 2.4GHz 802.11b/g/n
- Soporta seguridad WPA y WPA2
- Soporta tres modos de operación: STA/AP/STA+AP
- Protocolo TCP/IP integrado
- Pueda programarse de forma remota vía OTA
- 16 puertos GPIO (funcionan a 3,3V 15mA max.)
- 1 entrada ADC de 10bits (1,8V máx. pero solo mide hasta 1V)
- CPU 80MHz (default) pudiendo llevarse a 160MHz
- RAM 128Bytes
- ROM 4MBytes
- PWM/I2C/IIC/1-Wire/SPI/SDIO
- Un pin GND otro de 5V extras.
Que es el sensor BME280?
La serie BME280 de Bosch mide la presión barométrica, humedad y temperatura del aire ambiente. Bosch ofrece la serie BME280 que es un sensor ambiental integrado desarrollado específicamente para aplicaciones móviles, donde el tamaño y bajo consumo de energía son las limitaciones fundamentales de diseño. La unidad combina sensores de alta linealidad individual y alta precisión para la presión, humedad y temperatura en un paquete LGA de 2.5 x 2.5 x 0.93 mm³ y de 8 pines con tapa de metal, diseñado para un bajo consumo de corriente (3,6 µA a 1 Hz), estabilidad a largo plazo y alta robustez de EMC.
El sensor de humedad ofrece un tiempo de respuesta extremadamente rápido que soporta los requisitos de rendimiento para las aplicaciones emergentes, tales como la percepción del contexto y aplicaciones de alta precisión en un amplio rango de temperaturas. El sensor de presión es un sensor de presión barométrica absoluta que ofrece precisión excepcionalmente alta y resolución a muy bajo nivel de ruido. El sensor de temperatura integrado se ha optimizado para muy bajo nivel de ruido y alta resolución. Se utiliza principalmente para la compensación de temperatura de los sensores de humedad y presión y puede también ser utilizado para la estimación de la temperatura ambiente. La serie MEB280 admite un conjunto completo de modos de funcionamiento que proporcionan la flexibilidad necesaria para optimizar el consumo de energía del dispositivo, la resolución y el rendimiento del filtro.
Os dejo una comparativa entre varios sensores de temperatura/humedad. El resumen es que los mas destacados son el Sensirion sht71 y el Bme280, siendo el sensirion el mejor. No obstante, a nivel de coste, el Sensirion también puede ser unas 4-5 veces mas caro que el Bme280, que para nuestras aplicaciones típicas, no merece la pena el sobre coste.
Que es el protocolo MQTT?
Para mi primera entrada, voy a hablaros sobre MQTT (Message Queue Telemetry Transport), un protocolo usado para la comunicación machine-to-machine (M2M) en el "Internet of Things". Este protocolo está orientado a la comunicación de sensores, debido a que consume muy poco ancho de banda y puede ser utilizado en la mayoría de los dispositivos empotrados con pocos recursos (CPU, RAM, …). Un ejemplo de uso de este protocolo es la aplicación de Facebook Messenger tanto para android y Iphone. La arquitectura de MQTT sigue una topología de estrella, con un nodo central que hace de servidor o "broker" con una capacidad de hasta 10000 clientes. El broker es el encargado de gestionar la red y de transmitir los mensajes, para mantener activo el canal, los clientes mandan periódicamente un paquete (PINGREQ) y esperan la respuesta del broker (PINGRESP). La comunicación puede ser cifrada entre otras muchas opciones. La comunicación se basa en unos "topics" (temas), que el cliente que publica el mensaje crea y los nodos que deseen recibirlo deben subscribirse a él. La comunicación puede ser de uno a uno, o de uno a muchos. Un "topic" se representa mediante una cadena y tiene una estructura jerárquica. Cada jerarquía se separa con '/'. Por ejemplo, "edificio1/planta5/sala1/raspberry2/temperatura" o "/edificio3/planta0/sala3/arduino4/ruido".
Para profundizar mas, podéis seguir leyendo en: https://geekytheory.com/que-es-mqtt
Que broker vamos a usar?
Podemos o bien instalarnos en nuestro equipo, de forma local, un servidor MQTT, o bien usar uno online gratuito. Vamos a la opción online, dejando la otra para otra ocasión. Tenemos el broker http://www.mqtt-dashboard.com/ al cual podremos enviarle nuestros datos y luego consultarlos con un cliente que comentamos a continuación.
Los datos que le mandemos, los consultaremos desde: http://www.hivemq.com/demos/websocket-client/
Es una aplicación web que nos permite conectarnos al broker y leer los datos que tienen los topics que configuremos para leer los datos que tengan. Para conectarnos al broker, solo tendremos que darle a Conectar y listo! No hay que tocar inicialmente nada mas. Luego nos subscribiremos a los topics para que nos lleguen los datos que envía nuestro NodeMCU.
Como IDE usaremos ATOM + PlatformIO
Presentado todo, vamos a dar un paso mas. Voy a usar el editor para programar ATOM y sobre este voy a aplicar PlatformIO. ATOM es un editor muy flexible y que nos permite ponerle capas para adaptarlo. Hace tiempo salio un grupo que se encarga de reunir todos los tipos de placas, librerías, etc para tenerlo todo disponible bajo el nombre de PlatformIO. Esto es un IDE, pero lleno de contenido y "fácil de usar" (hay que adaptarse un poco). Tiene cada vez mas comunidad detrás y su potencial es muy grande. También es Open Source. No voy a profundizar sobre el editor, pues da para escribir un post exclusivamente de esto, si que os dejare los archivos y librerías, que perfectamente podréis cargar en el IDE de Arduino. Podéis encontrar mas info en su web: http://platformio.org/
En su día escribí sobre ATOM+PlatformIO, aquí podéis echar un vistazo. Trata básicamente de como instalarlo: https://www.spainlabs.com/foros/tema-Pla...formas-mas
Conexión del hardware
Vamos a conectar el sensor bme280 al Nodemcu usando I2C. En total son 4 cables. VCC(3v3), GND, SCL y SDA. Os dejo una imagen para mas claridad:
Librerías
Vamos a instalar las librerías mediante el editor Atom, pues gracias a la capa de software PlatformIO podemos instalar las librerías de forma muy cómoda. Mas abajo os pondré un enlace con las librerías por si no usáis el mismo IDE que yo. Vamos a usar las siguientes librerías:
Adafruit BME280 Library
Adafruit Unified Sensor
PubSubClient
** Aquí podéis descargar las 3 librerías: https://www.dropbox.com/s/26lgragoxl2lt1...s.rar?dl=0
Cada línea es una librería distinta, así que tendremos que instalar cada una por separado. Tras esto, tendremos que añadirlas a nuestro proyecto en dos sitios distintos. Uno de ellos sera como siempre hemos declarado las librerias en cualquier proyecto hecho con el IDE de arduino. El otro punto es que tenemos un archivo en nuestro proyecto llamado "platformio.ini" y dentro de este, tendremos que añadir las librerías. Que tiene esto de bueno, pues que al compilar, automáticamente se añadirán a nuestra carpeta de proyecto las librerías.
Nos quedaría así el archivo:
Para que no me quede un código principal muy largo y quizás algo confuso, he dividido en dos archivos. En el principal he dejado el setup() y el Loop(). En el otro archivo he dejado las funciones necesarias para el funcionamiento y la declaración de librerías.
El código principal [main.cpp] quedaría así:
Código:
#include <Arduino.h>
//Todas las funciones e includes de librerias estan en funciones.h
#include "funciones.h"
void setup() {
pinMode(BUILTIN_LED, OUTPUT); // Initialize the BUILTIN_LED pin as an output
Serial.begin(115200);
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
Serial.println(F("BME280 test"));
//Inicializamos el sensor bme280.
bool status;
// default settings
// (you can also pass in a Wire library object like &Wire2)
status = bme.begin();
if (!status) {
Serial.println("Could not find a valid BME280 sensor, check wiring!");
while (1);
}
Serial.println("-- Default Test --");
delayTime = 1000;
Serial.println();
delay(100); // let sensor boot up
}
void loop() {
//Lectura del sensor y envio de datos al monitor serie.
leerbme();
//Conexión con el broker MQTT.
if (!client.connected()) {
reconnect();
}
client.loop();
long now = millis();
if (now - lastMsg > 2000) {
lastMsg = now;
++value;
snprintf (msg, 75, "Prueba trama #%ld", value);
Serial.print("Publish message: ");
Serial.println(msg);
//Envio del mensaje.
client.publish("bmeesp/test1", msg);
//delay(5000);
float temp = 0.00;
temp = bme.readTemperature();
//Serial.println(String(temp).c_str());
//Envio del mensaje.
client.publish("bmeesp/test1/temp", String(temp).c_str());
float hum = 0.00;
hum = bme.readHumidity();
//Serial.println(String(temp).c_str());
//Envio del mensaje.
client.publish("bmeesp/test1/hum", String(hum).c_str());
}
delay(10000);
}
Y el archivo [funciones.h]:
Código:
// DECLARACION DE FUNCIONES Y LIBRERIAS NECESARIAS PARA EL PROYECTO.
#include <ESP8266WiFi.h> //WIFI ESP8266
#include <PubSubClient.h> // MQTT
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#define SEALEVELPRESSURE_HPA (1034.9)
Adafruit_BME280 bme; // I2C
unsigned long delayTime;
// Update these with values suitable for your network.
const char* ssid = "el nombre de tu wifi";
const char* password = "la clave de tu wifi";
const char* mqtt_server = "broker.mqtt-dashboard.com";
WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;
#define LED_BUILTIN 2
// FUNCIONES.
void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
// Switch on the LED if an 1 was received as first character
if ((char)payload[0] == '1') {
digitalWrite(BUILTIN_LED, LOW); // Turn the LED on (Note that LOW is the voltage level
// but actually the LED is on; this is because
// it is acive low on the ESP-01)
} else {
digitalWrite(BUILTIN_LED, HIGH); // Turn the LED off by making the voltage HIGH
}
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect("ESP8266Client")) {
Serial.println("connected");
// Once connected, publish an announcement...
client.publish("outTopic", "hello world");
// ... and resubscribe
client.subscribe("inTopic");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void leerbme(){
Serial.print("Temperature = ");
Serial.print(bme.readTemperature());
Serial.println(" *C");
Serial.print("Pressure = ");
Serial.print(bme.readPressure() / 100.0F);
Serial.println(" hPa");
Serial.print("Approx. Altitude = ");
Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
Serial.println(" m");
Serial.print("Humidity = ");
Serial.print(bme.readHumidity());
Serial.println(" %");
Serial.println();
delay(delayTime);
}
Comentaros, que la versión de nodemcu trae unos botones para reset y activar el modo programación, pero que no me ha hecho falta usar. No se si con el IDE de arduino hará falta, pero en mi caso ha sido como cargarle un código a arduino.
Pues este montaje, si lo miramos en el monitor serie, veremos algo así:
En el visor del broker elegido, veremos como nos empiezan a llegar los datos del sensor. Yo he elegido enviar un texto de prueba, el valor de la temperatura y el de la humedad.
Esto es todo, aun ha quedado un poco extenso el post. A ver si os gusta la idea, y pienso en alguna cosa para ir poniendo durante el año que viene contenido sobre el mundo IoT. Y a ver si salen seguidores
Si necesitáis que explique alguna parte con mas detalle, comentad lo!
Saludos.