Cliente MQTT del ESP8266
Cliente MQTT del ESP8266
En esta entrada se recoge la implementación del cliente MQTT para el ESP8266. Primero es necesario exponer que el protocolo MQTT es un protocolo utilizado en la comunicación máquina a máquina (machine to machine, M2M) en Internet de las cosas. El protocolo está orientado a la comunicación entre sensores o nodos de sensores, debido a que consume pocos recursos.
La arquitectura de MQTT sigue una topología de estrella, en el centro de la estrella se encuentra un nodo llamado Broker, el cuál es el encargado de gestionar la red y transmitir lo mensajes. Para la presente práctica se ha decidido utilizar el Broker público HiveMQ.
La comunicación mediante este protocolo se basa en "Topics", que el cliente puede crear y suscribirse, para enviar un mensaje el cliente debe usar un mensaje tipo publish y para suscribirse se lo comunica al nodo central y lo hace mediante la instrucción o mensaje subscribe.
Los Topics establecen una estructura jerárquica, la cual separa cada parte por el caracter "/". La estructura deseada para el proyecto actual es la siguiente:
El nodo base de la estructura es iiot2018, el cuál tiene 2 subtopics, que son conectado y detectado. Conectado fue utilizado en pruebas para comprobar que se conectaba el dispositivo, detectado indica que hay un cambio en el sistema, posee 2 subtopics a su vez, los cuales indican en que plaza se ha producido el cambio, los cambios se puede hacer en plaza 1 y plaza2 (actualmente se utiliza mediante la consola web, ya que solo se usa para pruebas). Al final del mensaje que incluya iiot2018/detectado/plaza1 o iiot2018/detectado/plaza2, se incluye un campo denominado en la estructura ocupación, el cual realmente es que ocupa la plaza, teniendo las posibilidades de Suelo, Bicicleta, Coche y Camión, todas ellas las salidas del sistema difuso que se encuentra en este blog.
Como se ha comentado anteriormente, el Broker utlizado en esta práctica es hivemq, el cual tendrá dos clientes, uno es un ESP8266 mediante la librería PubSubClient y el otro es un monitor implementado en python que también se encuentra disponible en este blog.
El código es el siguiente (puede descargarlo completo aquí):
//Incorporación de las librerías necesarias
#include <PubSubClient.h>
#include <stdlib.h>
#include <ESP8266WiFi.h>
#include <stdlib.h>
#include <ESP8266WiFi.h>
#include "Controlador_difuso.h"
Declaración de variables globales
//Conexión a AP
const char* ssid = "*****";
const char* password = "*******";
//Declaración del broker a utilizar
const char* mqtt_server = "broker.mqttdashboard.com";
//array de carácteres para almacenar el mensaje
char pub_str[100];
//Creación del cliente para el ESP8266
WiFiClient espClient;
//Creación del cliente de MQTT
PubSubClient client(espClient);
//Declaración de pines para utilizar el ultrasonido
#define echoPin D7 // Echo Pin
#define trigPin D6 // Trigger Pin
//Declaración de variables a reutilizar
long duration; // Duration used to calculate distance
float distance;
float solAnt = 0;
int ldrMedida;
int datos = 0;
//Declaración del controlador difuso a utilizar
Controlador_difuso controlador;
//Metodo setup de arduino donde se inicializa todas las variables necesarias
void setup() {
Serial.begin(115200);
delay(1000);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(A0, INPUT);
Serial.println(ssid);
//Preparando la conexión con el AP
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print("-");
}
Serial.println();
Serial.println("WiFi Connected");
Serial.println("WiFi got IP");
Serial.println();
Serial.println(WiFi.localIP());
//Conexión a servidor MQTT
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
reconnect();
}
//Bucle loop arduino
void loop() {
float sol;
//Lectura de las variables reales
leerUltraSonido();
leerLDR();//*/
Serial.print("medida Ultrasonido: "); Serial.print(distance);
Serial.print(" medida LDR: "); Serial.print(ldrMedida); ///*
//Llamada al controlador difuso para obtener salida clasificada
sol = controlador.Controlador(distance, ldrMedida);
//Si se ha desconetado el cliente MQTT volver a conectar
if (!client.connected()) {
reconnect();
}
//Dependiendo de la solución copia la salida correspondiente al array de carácteres pub_str
if (sol == 1) {
Serial.println(" Salida: Suelo");
strcpy(pub_str, "Suelo");
} else if (sol == 2) {
Serial.println(" Salida: Bicicleta");
strcpy(pub_str, "Bicileta");
} else if (sol == 3) {
Serial.println(" Salida: Coche");
strcpy(pub_str, "Coche");
} else {
Serial.println(" Salida: Camion");
strcpy(pub_str, "Camion");
}
//Si cambia la salida se envía el tipo de obstáculo que se encuentra en la plaza 1
if (sol != solAnt) {
solAnt = sol;
client.publish("iiot2018/detectado/plaza1", pub_str);
}
delay(1000);
client.loop();//*/
}
//Método para leer el ultrasonido
void leerUltraSonido() {
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
//Calculate the distance (in cm) based on the speed of sound.
distance = duration / 58.2;
}
//Metodo para leer el LDR
void leerLDR() {
ldrMedida = analogRead(A0);
}
//Metodo para la recepción de los mensajes MQTT
void callback(char* topic, byte* payload, unsigned int length)
{
Serial.print("Message arrived : ");
Serial.print(topic);
}
//Metodo para conectarse al broker MQTT
void reconnect()
{
while (!client.connected()) {
Serial.println("Attempting MQTT connection");
if (client.connect("clientId-FANySPqlvv"))//Identificador obtenido a través de la consola HiveMQ
{
Serial.println("Connected");
Serial.print("subscribed!");
}
else
{
Serial.print("Failed, rc = ");
Serial.print(client.state());
Serial.println("Waiting for 5 seconds to try again");
delay(5000);
}
}
}

Comentarios
Publicar un comentario