Implementación de colas: MQTT

Implementación de colas: MQTT

Para continuar con el desarrollo de la práctica, se va a realizar una implementación de colas por MQTT que llevará el control de plazas disponibles del parking enviando y recibiendo información entre los sensores controlados por la placa ESP8266 y un monitor del sistema.

MQTT es 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, …). La arquitectura de MQTT sigue una topología de estrella, con un nodo central que hace de servidor o "broker". El broker es el encargado de gestionar la red y de transmitir los mensajes, para mantener activo el canal. Al broker se conectan los clientes que mandan periódicamente un paquete (PINGREQ) y esperan la respuesta del broker (PINGRESP). La comunicación en el sistema se basa en unos "topics" (temas), que el cliente que publica el mensaje crea y los nodos que deseen recibirlo deben subscribirse a él.



Para el desarrollo de nuestro subsistema, vamos a utilizar como servidor o broker, un Broker público, en esto caso http://www.mqtt-dashboard.com/

Una vez dentro de la web, creamos un nuevo MQTT Websocket client con los datos:

Implementación de MQTT en ESP8266

Una vez creado el Broker público el siguiente paso es configurarlo en nuestra placa ESP8266 para establecer la comunicación con los sensores. Para poder conectarnos al broker necesitamos darle internet a nuestro ESP8266, para ello utilizamos la librería “#include <ESP8266WiFi.h>” y el código sería el siguiente:

#include <ESP8266WiFi.h>

//Wifi Setup
const char* ssid = "SSID_Proyecto_IoT2018";
const char* password = "password_IoT2018";

WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;

void setup() {
 Serial.begin(9600);
 setup_wifi();
 Serial.print("ESP8266 IP ");
 Serial.println(WiFi.localIP());
}
void loop() {
 …. \\Código del funcionamiento con máquina de estados

 if (!client.connected()) {
    reconnect();
 }
 client.loop();
 delay(100);
}

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");
     client.subscribe("PARKING_IOT_MONITOR");
      } else {
          Serial.print("failed, rc=");
          Serial.print(client.state());
          Serial.println(" try again in 5 seconds");
          // Wait 5 seconds before retrying
          delay(5000);
      }
   }
}

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());
}

Una vez que ya le hemos dado conexión a nuestro ESP8266, el siguiente paso es conectarnos al broker público. A continuación se va a mostrar el código necesario para realizar dicha conexión:

#include <PubSubClient.h>

//Wifi Setup
const char* ssid = "SSID_Proyecto_IoT2018";
const char* password = "password_IoT2018";

//Broker
const char* mqtt_server = "broker.hivemq.com"; /// MQTT Broker
int mqtt_port = 1883;

WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;

void setup() {
 Serial.begin(9600);
 setup_wifi();
 client.setServer(mqtt_server, mqtt_port);
 client.setCallback(callback);
 client.subscribe("PARKING_IOT_MONITOR");
 Serial.println("Connected");
 Serial.print("MQTT Server ");
 Serial.print(mqtt_server);
 Serial.print(":");
 Serial.println(String(mqtt_port));
 Serial.print("ESP8266 IP ");
 Serial.println(WiFi.localIP());
}

void loop() {
switch(estado) {
     case inicio:
       if(ValorLDR[0] < limitCoche[0] && PLAZAS_LIBRES > 0) {
         estado = entrando1;
       } else if(ValorLDR[1] < limitCoche[1]) {
         estado = saliendo1;
       }
break; .... 
case entra_coche:
       client.publish("PARKING_IOT", "ENTRA"); /// send char
       Serial.println("Estado: Entra coche");
       estado = inicio;
       break; ....
case sale_coche:
       client.publish("PARKING_IOT", "SALE"); /// send char
       Serial.println("Estado: Sale coche");
       estado = inicio;
       break;
  default:
       estado = inicio;
       break;
 if (!client.connected()) {
    reconnect();
 }
 client.loop();
 delay(100);
}

//Función que se ejecuta cuando se recibe un mensaje nuevo, en este caso, conocer el número de plazas libres
void callback(char* topic, byte* payload, unsigned int length) {
 String s = String((char*)payload);
 PLAZAS_LIBRES = s.toFloat();

 Serial.print("PLAZAS LIBRES => ");
 Serial.println(PLAZAS_LIBRES);
}

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");
     client.subscribe("PARKING_IOT_MONITOR");
      } else {
          Serial.print("failed, rc=");
          Serial.print(client.state());
          Serial.println(" try again in 5 seconds");
          // Wait 5 seconds before retrying
          delay(5000);
      }
   }
}

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());
}

Comentarios

Entradas populares de este blog

Clasificador Difuso del sistema

Cliente MQTT del ESP8266

I2C