miércoles, 11 de enero de 2017

ESP8266 y MQTT

ESP8266 se ha convertido en una de las plataformas más comunes para implementar un dispositivo conectado.

El ESP8266 es un microcontrolador programable por LUA y mediante el IDE de Arduino con la inclusión de un pluggin. Existen varias distribuciones que permiten una programación directa por usb sin necesidad de utilizar un adaptador USB-UART.



Las más comunes son el Wemos d1 (www.prometec.net/wemos-d1-esp8266-wifi/) y el NodeMCU (www.nodemcu.com) , ambas basadas en el ESP8286 ESP12, estas placas disponen de capacidad PWM en todos los pines digitales ya además dispone de I2C y SPI, pero todos los pines son de 3.3V incluyendo el convertido analógico al digital.




Una vez instalado el pluggin  en el IDE Arduino ( aquí.
hay que comprobar que el sistema tiene el driver para el chip  CHG340 (windows: ch341ser_win ,MAC OS aquí , en Linux suelev venir de fábrica)
Seleccionad la placa correspondiente:
Arduino IDE
y el puerto correspondiente y ya esta lista para ser programada. 



Para la conexión a MQTT es necesario haber instalado en nuestro PC o Raspberry el servidor Mosquitto o bien acceder a un servidor WEB de uso público (por ejemplo test.mosquitto.org).

PAra 


El siguiente script se conecta al servidor elegido y espera a recibir un evento bajo el topic "GPIO" con una carga 1 o 0. en caso de ser un "1" enciende un led en el pin 2 y en caso de ser un "0" lo apaga.

Para mostrar que se ha recibido pública de vuelta el resultado de la operación bajo el mismo topic.
desde un terminal con un cliente MQTT podemos mandar dicho evento:
mosquitto_pub  -h 85.119.83.194  -t GPIO -m "1"

mosquitto_pub  -h 85.119.83.194  -t GPIO -m "0"

Dede otro terminal podemos subscribirnos para recibir tanto el envio como las respuestas de la ESP8266

mosquitto_sub -h 85.119.83.194 -v -t "GPIO"
GPIO 1
GPIO Light On
GPIO 0
GPIO Light Off



//ItKindaWorks - Creative Commons 2016//github.com/ItKindaWorks////Requires PubSubClient found here: https://github.com/knolleary/pubsubclient////ESP8266 Simple MQTT light controller

#include <PubSubClient.h>#include <ESP8266WiFi.h>

//EDIT THESE LINES TO MATCH YOUR SETUP#define MQTT_SERVER "85.119.83.194"   //"test.mosquitto.org"const char* ssid = "nombrered";const char* password = "pasword";
//LED on ESP8266 GPIO2const int lightPin = 2;//D9 en la parte de arduino y GPIO2 por detras
char* lightTopic = "GPIO";

WiFiClient wifiClient;PubSubClient client(MQTT_SERVER, 1883, callback, wifiClient);
void setup() { pinMode(lightPin, OUTPUT); digitalWrite(lightPin, LOW);
Serial.begin(115200); delay(100);
WiFi.begin(ssid, password);
reconnect();
    delay(2000);}


void loop(){
if (!client.connected() && WiFi.status() == 3) {reconnect();}
client.loop();
delay(10); }

void callback(char* topic, byte* payload, unsigned int length) {
String topicStr = topic; 
Serial.println("Callback update."); Serial.print("Topic: "); Serial.println(topicStr);
if(payload[0] == '1'){ digitalWrite(lightPin, HIGH); client.publish("GPIO", "Light On");                Serial.println("encendido"); }
else if (payload[0] == '0'){ digitalWrite(lightPin, LOW); client.publish("GPIO", "Light Off");    Serial.println("apagado"); }
}
void reconnect() {
if(WiFi.status() != WL_CONNECTED){ Serial.print("Connecting to "); Serial.println(ssid);
while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); }
Serial.println(""); Serial.println("WiFi connected");   Serial.println("IP address: "); Serial.println(WiFi.localIP()); }
if(WiFi.status() == WL_CONNECTED){
while (!client.connected()) { Serial.print("Attempting MQTT connection...");
String clientName; clientName += "esp8266-"; uint8_t mac[6]; WiFi.macAddress(mac); clientName += macToStr(mac);
if (client.connect((char*) clientName.c_str())) { Serial.print("\tMTQQ Connected"); client.subscribe("GPIO");//lightTopic); }
else{Serial.println("\tFailed."); abort();} } }}
//generate unique name from MAC addrString macToStr(const uint8_t* mac){
  String result;
  for (int i = 0; i < 6; ++i) {    result += String(mac[i], 16);
    if (i < 5){      result += ':';    }  }
  return result;}