ESP8266: El Arduino con WiFi

1. Instalación del entorno de programación

Arduino es una plataforma de hardware libre y de código abierto que se utiliza para desarrollar proyectos electrónicos interactivos. Para empezar a programar con Arduino, necesitas instalar su entorno de programación en tu ordenador.

A continuación, te explicamos los pasos para instalar el entorno de programación de Arduino:

Descarga el software de Arduino desde su sitio web oficial: https://www.arduino.cc/en/software

image-1682416823209.png

Descargaremos la versión 2 del software que corresponda con tu sistema operativo. Recomendable que sea la instalación

image-1682417013662.png

Si quieres puedes colaborar en el desarollo del proyecto o descargar directamente. 

image-1682417220555.png

Abre el archivo descargado y sigue las instrucciones de instalación. El proceso es muy sencillo y solo tienes que seguir los pasos que te indica el instalador.

Una vez finalizada la instalación, abre el entorno de programación de Arduino. Verás una pantalla en blanco con algunas opciones en la barra de herramientas.

image-1682418701953.png

Ahora vamos a instalar el núcleo de librerias para poder utilizar el ESP8266 con el entorno de programación de Arduino. 

En tu Arduino IDE, ve a Archivo > Preferencias.

Ingrese http://arduino.esp8266.com/stable/package_esp8266com_index.json en el campo "URLs adicionales de gestor de placas:" como se muestra en la figura a continuación. Luego, haga clic en el botón "Aceptar":

image-1682419841360.png

Ahora, en tu Arduino IDE, ve a Herramientas > Placas > Gestor de Placas. Y en el filtro escribe esp y haga clic en el botón "Instalar" en la placa esp8266 como aparece en la imagen.

image-1682419963692.png

Para probar que hemos instalado correctamente la placa y ver un ejemplo de código de programación. Vamos en tu Arduino IDE, ve a Archivo > Ejemplos > 01.Basics > Blink. Y se abrirá la ventana con código escrito del ejemplo.

El código para el ejemplo de Blink es muy simple y consta de dos funciones: setup() y loop(). En la función setup() se configura el pin del Arduino que se va a utilizar para conectar el LED y se establece como salida. En la función loop() se hace que el LED parpadee encendiéndolo durante un tiempo determinado y luego apagándolo durante otro tiempo determinado.

Para subirlo, pulsaremos la flecha y nos pedirá que seleccionemos una placa, en este caso utilizaremos para el taller LOLIN(WEMOS) D1 R2 & mini. Si te aparecen más puertos y no sabes muy bien cuál de ellos seleccionar, un truco es desconectar y conectar la placa, y ver que nuevo puerto aparece.

image-1682420262244.png

Por último, subimos el código y vemos el resultado.

 

 

2. Instalación de una librería en el entorno de programación

¿Que es una librería de codigo?

Una librería de código, también conocida como biblioteca o framework, es un conjunto de funciones, clases y/o módulos que se pueden utilizar para facilitar la programación de una aplicación o sistema. Estas librerías pueden estar escritas en diferentes lenguajes de programación y se utilizan para realizar tareas comunes de programación, como el procesamiento de datos, la gestión de redes, la creación de interfaces gráficas de usuario, entre otras.

Las librerías de código son una herramienta importante para los desarrolladores, ya que les permiten reutilizar código ya existente y ahorrar tiempo en la creación de nuevas aplicaciones. Además, las librerías de código también pueden mejorar la calidad del software al proporcionar funciones ya probadas y optimizadas por otros desarrolladores.

¿Como la instalo?

Abrimos el entorno de programación y vamos a Skecth > Incluir biblioteca > Gestionar bibliotecas

install_lib.png

En el lateral se abrirá un nuevo menu en el cuál podremos buscar la libreria que nos interese, en este caso os invitamos a instalar la libreria para el uso del sensor DHT11, un sensor que nos permite medir temperatura y humedad.

install_lib_2.png

En este caso os sugerimos instalar la siguiente DHT sensor library de Adafruit,pulsamos INSTALAR, si aparece un menu como el siguiente INSTALAR TODO, ya que quizás la librería por bajo necesita de otras más principales para funcionar.

install_lib_3.png

¿Como elegir una libreria?

Elegir una librería adecuada puede ser una tarea importante en el desarrollo de una aplicación. A continuación, se presentan algunos consejos para seleccionar la librería adecuada:

  1. Identifica tus necesidades: Antes de buscar una librería, es importante tener claro qué funcionalidades necesitas en tu aplicación. De esta manera, podrás buscar una librería que ofrezca exactamente lo que necesitas.

  2. Investiga las opciones disponibles: Hay muchas librerías disponibles en línea, por lo que es importante investigar y comparar diferentes opciones. Revisa documentación, ejemplos de uso, popularidad y estabilidad.

  3. Comprueba la compatibilidad: Es importante asegurarte de que la librería sea compatible con tu sistema operativo, lenguaje de programación y otros elementos que se estén utilizando en tu proyecto.

  4. Revisa la comunidad y soporte: Una comunidad activa y un soporte adecuado pueden ser clave para resolver problemas en el futuro, asegúrate de que la librería elegida tenga una comunidad activa y actualizaciones recientes.

  5. Evalúa el rendimiento: La velocidad y la eficiencia son importantes en cualquier aplicación, así que es recomendable evaluar el rendimiento de la librería antes de integrarla en tu proyecto.

  6. Considera el coste: Algunas librerías pueden tener costos asociados, como licencias o suscripciones. Asegúrate de considerar los costos y beneficios antes de tomar una decisión.

  7. Prueba la librería: Antes de integrar la librería en tu proyecto, es recomendable hacer una prueba en un ambiente de pruebas para verificar que cumpla con tus expectativas y necesidades.

Ten en cuenta que la elección de una librería dependerá de las necesidades específicas de tu proyecto, por lo que es importante evaluar cada opción en función de sus características y ventajas.

3. Montaje del circuito de sensores para el ESP8266, con dos LEDS, un sensor de temperatura y humedad, y un sensor fotorresistivo (LDR)

¿Como conectar un led a un esp8266? ¿Porque lleva una resistencia?

Para conectar un LED a un ESP8266, es necesario conectar el ánodo (patita más larga) del LED a uno de los pines de salida digital del ESP8266, y el cátodo (patita más corta) a través de una resistencia de limitación de corriente a la tierra (GND).

La resistencia de limitación de corriente es necesaria para evitar que el LED reciba más corriente de la que puede soportar, lo que puede dañar el LED o el ESP8266. La resistencia limita la corriente que fluye a través del LED, asegurándose de que la corriente esté dentro de los límites seguros. La resistencia que se utiliza dependerá del tipo de LED y del voltaje de alimentación utilizado, y se puede calcular utilizando la ley de Ohm.

Por ejemplo, si se utiliza un LED con una caída de voltaje de 2V y una corriente máxima de 20mA, y el voltaje de alimentación es de 3.3V, la resistencia de limitación de corriente necesaria sería de aproximadamente (3.3V - 2V) / 0.02A = 65 ohmios. Sin embargo, como los valores comerciales de resistencia no son exactos, se puede utilizar una resistencia comercial estándar de 68 ohmios, por ejemplo. Normalmente, utilizando una resistencia de 220 o 330 ohmios suele funcionar.

En resumen, para conectar un LED a un ESP8266 se debe conectar el ánodo del LED a un pin de salida digital, el cátodo a través de una resistencia de limitación de corriente a tierra, y elegir una resistencia adecuada para limitar la corriente que fluye a través del LED.

¿Como conectar un LDR a un esp8266? ¿Como leo su valor?

Para conectar un LDR (resistencia dependiente de la luz) a un ESP8266, primero se debe conectar uno de los terminales del LDR a un pin analógico del ESP8266, y el otro terminal del LDR a una fuente de voltaje, como el pin de 3.3V o 5V del ESP8266. Además, hay que colocar una resistencia en serie con el terminal del LDR conectado al pin analógico y otro pin de la resistencia conectado a toma de tierra GND. El valor dependerá de la resistencia del LDR, se suele utilizar el mismo valor que el proporcionado por el LDR, por ejemplo, 10K ohmios. (Concepto de divisor resistivo)

Una vez que se ha conectado el LDR al ESP8266, se puede leer su valor utilizando una de las entradas analógicas del ESP8266. El ESP8266 tiene un ADC (A0) (conversor analógico a digital) integrado que puede medir la tensión en el pin analógico. La lectura del ADC se puede realizar utilizando la función analogRead() en el código del ESP8266. Esta función devuelve un valor entero entre 0 y 1023, que representa la tensión medida en el pin analógico.

Para leer el valor del LDR, es necesario realizar una lectura analógica utilizando analogRead() y luego convertir ese valor en una medida de la luminosidad. La relación entre la resistencia del LDR y la luminosidad no es lineal, por lo que se debe calibrar la lectura del LDR para obtener una medida precisa de la luminosidad. La calibración se puede realizar midiendo el valor del LDR en diferentes condiciones de iluminación y ajustando una fórmula que convierta la lectura del LDR en una medida de la luminosidad en unidades apropiadas (por ejemplo, lux).

¿Como conecto el modulo DHT11?

Para conectar un módulo DHT11 al ESP8266, se deben seguir los siguientes pasos:

  1. Conectar el pin VCC del módulo DHT11 al pin de 3.3V o 5V del ESP8266.
  2. Conectar el pin GND del módulo DHT11 al pin GND del ESP8266.
  3. Conectar el pin DATA del módulo DHT11 al pin GPIO del ESP8266 (puede ser cualquier pin GPIO disponible).

Una vez conectado el módulo DHT11 al ESP8266, se puede leer la temperatura y la humedad utilizando una biblioteca específica para el DHT11. El módulo DHT11 utiliza el protocolo OneWire para transmitir los datos de temperatura y humedad a través de un solo pin de datos. El módulo tiene un chip interno que convierte la información de los sensores en una señal digital, que luego es transmitida a través del pin de datos utilizando el protocolo OneWire.

El protocolo OneWire es un protocolo de comunicación serial que permite la transferencia de datos a través de un solo cable. Es utilizado en una variedad de dispositivos electrónicos, incluyendo sensores de temperatura y humedad como el DHT11.

El protocolo OneWire funciona mediante la transmisión de pulsos de voltaje a través del pin de datos. La transmisión de datos se inicia con una señal de inicio enviada por el dispositivo maestro (en este caso, el ESP8266). Luego, el dispositivo esclavo (el DHT11) responde con una señal de presencia para indicar que está listo para recibir los datos. A continuación, el dispositivo maestro envía una serie de pulsos de sincronización y datos, y el dispositivo esclavo responde con un bit de confirmación después de cada dato recibido.

ESP8266_MQTT_SCHEMATIC_TALLER.png

¿Como funciona un divisor resistivo?

Un divisor resistivo es un circuito formado por dos resistencias conectadas en serie entre una fuente de voltaje y tierra (GND). La tensión de salida se toma de la conexión entre las dos resistencias.

El principio de funcionamiento del divisor resistivo se basa en la ley de Ohm, que establece que la corriente que fluye a través de una resistencia es proporcional a la diferencia de potencial (voltaje) entre los extremos de la resistencia. En un divisor resistivo, la corriente que fluye a través de ambas resistencias es la misma, ya que están conectadas en serie. Por lo tanto, la tensión en cada resistencia es proporcional a su resistencia.

Resistive_divider.png

La tensión de salida del divisor resistivo se calcula como la tensión en la resistencia de salida (la que está conectada al pin de salida) en relación con la tensión total en el circuito. Esto se puede expresar matemáticamente como:

Vout = Vin * R2 / (R1 + R2)

Donde Vin es la tensión de entrada, R1 es la resistencia conectada al pin de entrada, R2 es la resistencia conectada al pin de salida, y Vout es la tensión de salida.

En resumen, un divisor resistivo funciona al dividir la tensión de entrada en dos partes, proporcionalmente a las resistencias utilizadas. La tensión de salida se toma de la conexión entre las dos resistencias y se puede calcular utilizando la fórmula mencionada anteriormente.

4. Testeando los sensores y LEDs

¿Como leer un sensor analógico?

Para leer un sensor analógico con Arduino, debes seguir los siguientes pasos:

  1. Conectar el sensor: Conecta el sensor analógico a un pin analógico en la placa Arduino. Asegúrate de que los pines del sensor estén conectados correctamente al pin analógico de la placa. Además, algunos sensores pueden requerir una conexión adicional de VCC y GND.

  2. Leer el valor: Se utiliza la función analogRead() para leer el valor del pin analógico. Esta función devuelve un valor entre 0 y 1023 que representa el voltaje en el pin. El valor 0 representa 0 voltios, mientras que el valor 1023 representa la referencia de voltaje de la placa, que en ESP8266 es de 3.3V.

  3. Convertir el valor: A veces, el valor devuelto por la función analogRead() no es el valor que se necesita para el cálculo. Por ejemplo, algunos sensores pueden requerir una conversión de voltaje a temperatura. En este caso, se puede usar una ecuación de conversión para convertir el valor leído a la unidad de medida necesaria.

Aquí hay un ejemplo de código para leer un sensor analógico conectado al pin A0:

int sensorValue = 0; // Variable para almacenar el valor del sensor

void setup() {
  Serial.begin(115200); // Inicia la comunicación serial a una velocidad de 115200 baudios
}

void loop() {
  sensorValue = analogRead(A0); // Lee el valor del sensor en el pin A0
  Serial.println(sensorValue);  // Imprime el valor en el monitor serial
  delay(100);                  // Espera un tiempo para evitar la sobrecarga del puerto serie
}

En este ejemplo, la función analogRead() se usa para leer el valor del pin A0 y luego se imprime en el monitor serial. El comando delay() se utiliza para esperar un tiempo antes de leer el valor del sensor de nuevo y enviarlo al monitor serial para evitar la sobrecarga del puerto serial.

¿Como encender un led con Arduino?

Para encender un LED con Arduino, sigue los siguientes pasos:

  1. Conecta un extremo de la resistencia a un pin digital del Arduino y el otro extremo a la protoboard.
  2. Conecta el cátodo (pata más corta) del LED a la misma fila de la protoboard en la que conectaste la resistencia.
  3. Conecta el ánodo (pata más larga) del LED a otra fila de la protoboard.
  4. Conecta un cable desde la fila de la protoboard donde está el ánodo del LED a una fuente de voltaje (por ejemplo, 3.3V).
  5. Conecta un cable desde la fila de la protoboard donde está la resistencia a un pin GND del Arduino.
  6. En el código de Arduino, usa la función pinMode para establecer el pin digital donde conectaste la resistencia como una salida: pinMode(PIN, OUTPUT);.
  7. En el código de Arduino, usa la función digitalWrite para establecer el estado del pin digital donde conectaste la resistencia a HIGH o LOW para encender o apagar el LED, respectivamente: digitalWrite(PIN, HIGH);.

Por ejemplo, el siguiente código encendería y apagaría un LED conectado al pin digital D2:

void setup() {
  pinMode(D2, OUTPUT); //establecer el pin 13 como salida
}

void loop() {
  digitalWrite(D2, HIGH); //encender el LED
  delay(1000); //esperar un segundo
  digitalWrite(D2, LOW); //apagar el LED
  delay(1000); //esperar un segundo
}
¿Como leer el sensor DHT11 con la librería Adafuit y Arduino?

Para leer el sensor de temperatura y humedad DHT11 con la librería de Adafruit y Arduino, debes seguir los siguientes pasos:

  1. Descarga e instala la librería de Adafruit DHT desde el administrador de librerías de Arduino. Puedes hacerlo yendo al menú "Sketch -> Incluir librería -> Administrar librerías" y buscando "DHT".

  2. Conecta el pin de datos del sensor DHT11 a uno de los pines digitales de la placa Arduino. En el ejemplo a continuación, se utiliza el pin D7.

  3. En el código, primero debes incluir las librerías necesarias:

#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>
  1. Luego, define el pin de datos y el tipo de sensor que estás utilizando:

#define DHTPIN  D7     // Pin digital conectado al sensor DHT
#define DHTTYPE DHT11  // DHT 11

DHT_Unified dht(DHTPIN, DHTTYPE);

  1. En la función setup(), inicializa el dispositivo DHT y realiza una impresión por consola de los detalles del sensor:
    void setup() {
      dht.begin(); // Inicializar dispositivo DHT
      Serial.begin(115200);
      Serial.println(F("Sensor DHT11"));
      // Imprime los detalles del sensor de temperatura.
      sensor_t sensor;
      dht.temperature().getSensor(&sensor);
      Serial.println(F("------------------------------------"));
      Serial.println(F("Sensor de Temperatura"));
      Serial.print  (F("Valor Max:   ")); Serial.print(sensor.max_value); Serial.println(F("°C"));
      Serial.print  (F("Valor Min:   ")); Serial.print(sensor.min_value); Serial.println(F("°C"));
      Serial.print  (F("Resolucion:  ")); Serial.print(sensor.resolution); Serial.println(F("°C"));
      // Imprime los detalles del sensor de humedad.
      dht.humidity().getSensor(&sensor);
      Serial.println(F("Sensor de Humedad"));
      Serial.print  (F("Valor Max:   ")); Serial.print(sensor.max_value); Serial.println(F("%"));
      Serial.print  (F("Valor Min:   ")); Serial.print(sensor.min_value); Serial.println(F("%"));
      Serial.print  (F("Resolucion:  ")); Serial.print(sensor.resolution); Serial.println(F("%"));
      Serial.println(F("------------------------------------"));
    }
  2. En la función loop(), puedes obtener los valores de temperatura y humedad del sensor DHT11 y mostrarlos por consola:
    void loop() {
      sensors_event_t event;
      dht.temperature().getEvent(&event);
      if (isnan(event.temperature)) {
        Serial.println(F("¡Error al leer la temperatura!"));
      }
      else {
        Serial.print(F("Temperatura: "));
        Serial.print(event.temperature);
        Serial.println(F("°C"));
      }
      dht.humidity().getEvent(&event);
      if (isnan(event.relative_humidity)) {
        Serial.println(F("¡Error al leer la humedad!"));
      }
      else {
        Serial.print(F("Humedad: "));
        Serial.print(event.relative_humidity);
        Serial.println(F("%"));
      }
      delay(2000);
    }

¡Ahora es tu turno! Realiza el código completo con los siguientes ingredientes hardware para que todo el sistema funcione.

El programa deberá utilizar un sensor DHT11 para medir la temperatura y humedad del ambiente y un sensor LDR para medir la intensidad de luz. También incluir dos LEDs que parpadean de manera alterna cada segundo.

En la función setup(), se inicializan los puertos de entrada y salida para los sensores y los LEDs, se imprime información detallada acerca del sensor DHT11 y se configura la velocidad de comunicación del puerto serie a 115200 bauds.

En la función loop(), se leen los valores del sensor LDR y se imprimen en el monitor serie junto con los valores de temperatura y humedad del sensor DHT11, si están disponibles. Los LEDs parpadean alternadamente cada segundo. 



Código Completo

Solución

#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>

#define DHTPIN  D7     // Pin digital conectado al sensor DHT
#define DHTTYPE DHT11  // DHT 11
DHT_Unified dht(DHTPIN, DHTTYPE);

#define LED_ROJO D5
#define LED_VERDE D6

#define LDR_PIN A0
int sensorLDRValue = 0;  // variable para almacenar el valor proveniente del sensor LDR

// la función de setup() se ejecuta una vez cuando presionas el botón de reset o enciendes la placa
void setup() {

  Serial.begin(115200);        // inicializa el puerto serie (USB - COM) en una velocidad de comunicación de 115200 bauds
  Serial.println("\n\n");

  pinMode(LED_ROJO, OUTPUT);   // inicializa el pin digital LED_ROJO como salida.
  pinMode(LED_VERDE, OUTPUT);  // inicializa el pin digital LED_VERDE como salida.

  dht.begin(); // Inicializar dispositivo DHT
  Serial.println(F("Sensor DHT11"));
// Imprime los detalles del sensor de temperatura.
  sensor_t sensor;
  dht.temperature().getSensor(&sensor);
  Serial.println(F("------------------------------------"));
  Serial.println(F("Sensor de Temperatura"));
  Serial.print  (F("Valor Max:   ")); Serial.print(sensor.max_value); Serial.println(F("°C"));
  Serial.print  (F("Valor Min:   ")); Serial.print(sensor.min_value); Serial.println(F("°C"));
  Serial.print  (F("Resolucion:  ")); Serial.print(sensor.resolution); Serial.println(F("°C"));
// Imprime los detalles del sensor de humedad.
  dht.humidity().getSensor(&sensor);
  Serial.println(F("Sensor de Humedad"));
  Serial.print  (F("Valor Max:   ")); Serial.print(sensor.max_value); Serial.println(F("%"));
  Serial.print  (F("Valor Min:   ")); Serial.print(sensor.min_value); Serial.println(F("%"));
  Serial.print  (F("Resolucion:  ")); Serial.print(sensor.resolution); Serial.println(F("%"));
  Serial.println(F("------------------------------------"));
}

// la función de loop() se ejecuta una y otra vez para siempre
void loop() {
  digitalWrite(LED_ROJO, HIGH);   // enciende el LED (HIGH es el nivel alto de voltaje - 3.3V)
  digitalWrite(LED_VERDE, LOW);   // apaga el LED haciendo que el voltaje sea bajo (LOW)
  delay(1000);                    // espera un segundo - 1000 ms (milisegundos)
  digitalWrite(LED_ROJO, LOW);    // apaga el LED haciendo que el voltaje sea bajo (LOW)
  digitalWrite(LED_VERDE, HIGH);  // enciende el LED (HIGH es el nivel alto de voltaje - 3.3V)
  delay(1000);                    // espera un segundo - 1000 ms (milisegundos)

  // read the value from the sensor:
  sensorLDRValue = analogRead(LDR_PIN);
  Serial.print(F("LDR: "));
  Serial.print(sensorLDRValue);

  mostrar_datos_sensor_DHT11();

  Serial.println();
}

void mostrar_datos_sensor_DHT11(){
  // Obtenga si hay evento de temperatura e imprima su valor.
  sensors_event_t event;
  dht.temperature().getEvent(&event);
  if (isnan(event.temperature)) {
    Serial.print(F("\t"));
    //Serial.println(F("¡Error al leer la temperatura!"));
  }
  else {
    Serial.print(F("\t"));
    Serial.print(F("Temperatura: "));
    Serial.print(event.temperature);
    Serial.print(F("°C"));
  }
  // Obtenga si hay evento de humedad e imprima su valor.
  dht.humidity().getEvent(&event);
  if (isnan(event.relative_humidity)) {
    Serial.print(F("\t"));
    //Serial.println(F("¡Error al leer la humedad!"));
  }
  else {
    Serial.print(F("\t"));
    Serial.print(F("Humedad: "));
    Serial.print(event.relative_humidity);
    Serial.print(F("%"));
  }
}


Descargar el código de ejemplo completo

5. Comunicación de los datos utilizando MQTT

¿Que es MQTT?

MQTT (Message Queuing Telemetry Transport) es un protocolo de comunicación ligero y de publicación-suscripción que se utiliza comúnmente en aplicaciones de Internet de las cosas (IoT). 

MQTT se basa en un modelo de mensajería de publicación/suscripción, en el que los clientes pueden publicar mensajes en un tema (topic) y otros clientes pueden suscribirse a ese tema para recibir los mensajes. Los temas son cadenas de caracteres que representan un canal de comunicación en particular. Los clientes pueden suscribirse a un tema específico y recibir los mensajes que se publican en ese tema.

MQTT se utiliza comúnmente en aplicaciones IoT debido a su baja sobrecarga y su capacidad para funcionar en redes con ancho de banda limitado y alta latencia. También es compatible con la seguridad a nivel de transporte mediante TLS/SSL, lo que lo hace adecuado para entornos empresariales y de seguridad crítica.

¿Cómo hago un primer ejemplo?


Este código es un ejemplo básico de cómo conectar un dispositivo ESP8266 a un broker MQTT usando la biblioteca PubSubClient de Arduino.

En la función setup(), se inicializan los pines del dispositivo y se configura la conexión Wi-Fi. A continuación, se establece la conexión con el servidor MQTT mediante el método setServer() de la biblioteca PubSubClient. También se establece la función callback() para manejar los mensajes entrantes.

En la función loop(), se verifica si el cliente MQTT está conectado. Si no lo está, se intenta una reconexión llamando a la función reconnect(). Luego, se llama a la función loop() del cliente para procesar los mensajes entrantes y salientes.

Finalmente, en la función loop(), se envía un mensaje al broker MQTT cada dos segundos mediante el método publish() del cliente, y se incrementa el valor de la variable value para que cada mensaje tenga un número de secuencia único.

En resumen, este código muestra cómo establecer una conexión básica entre un dispositivo ESP8266 y un broker MQTT y cómo enviar mensajes a través de la red MQTT.

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

// Update these with values suitable for your network.
const char* ssid = "wifi_name";
const char* password = "wifi_password";
const char* mqtt_server = "mqtt.makersupv.com";
#define USER "makersupv"
#define PASS "makersupv"
String TEAM = "t00";
String OUT_TOPIC = "taller/" + TEAM + "/outTopic";
String IN_TOPIC = "taller/" + TEAM + "/inTopic";

WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastMsg = 0;
#define MSG_BUFFER_SIZE	(64)
char msg[MSG_BUFFER_SIZE];
int value = 0;

void setup_wifi() {

  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  randomSeed(micros());

  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 active 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...");
    String client_id = "";
    // Attempt to connect
    if (client.connect(client_id.c_str(), USER, PASS)) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish(OUT_TOPIC.c_str(), "hello world");
      // ... and resubscribe
      client.subscribe(IN_TOPIC.c_str());
    } 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() {
  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);
}

void loop() {

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

  unsigned long now = millis();
  if (now - lastMsg > 2000) {
    lastMsg = now;
    ++value;
    snprintf (msg, MSG_BUFFER_SIZE, "hello world #%ld", value);
    Serial.print("Publish message: ");
    Serial.println(msg);
    client.publish(OUT_TOPIC, msg);
  }
}

Para poder verificar que estaís recibiendo información podeís descargaros una aplicación en vuestro movil como MyMQTT esta disponible para iOS y Android. Con esta aplicación podréis debuggear lo que está suciendo, si recibis mensajes, también si podéis actuar sobre los diferentes componentes.

Solución
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>

#define DHTPIN  D7     // Pin digital conectado al sensor DHT
#define DHTTYPE DHT11  // DHT 11
DHT_Unified dht(DHTPIN, DHTTYPE);

#define LED_ROJO D5
#define LED_VERDE D6

#define LDR_PIN A0
int sensorLDRValue = 0;  // variable para almacenar el valor proveniente del sensor LDR


// Update these with values suitable for your network.
const char* ssid = "makersupv";
const char* password = "makersupv";
const char* mqtt_server = "mqtt.makersupv.com";
#define USER "makersupv"
#define PASS "makersupv"
String TEAM = "TEAM_MAKERS";
String OUT_TOPIC_TEMP = "taller/" + TEAM + "/sens/DHT11/temp";
String OUT_TOPIC_HUM = "taller/" + TEAM + "/sens/DHT11/hum";
String OUT_TOPIC_LDR = "taller/" + TEAM + "/sens/LDR";
String IN_TOPIC_LED_VERDE = "taller/" + TEAM + "/leds/verde";
String IN_TOPIC_LED_ROJO = "taller/" + TEAM + "/leds/rojo";

WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastMsg = 0;
#define MSG_BUFFER_SIZE	(64)
char msg[MSG_BUFFER_SIZE];
int value = 0;

void setup_wifi() {

  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  randomSeed(micros());

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

  if(topic == IN_TOPIC_LED_VERDE.c_str()){
    // Switch on the LED if an 1 was received as first character
    if ((char)payload[0] == '0') {
      digitalWrite(LED_VERDE, LOW);   // Turn the LED on (Note that LOW is the voltage level
    } else if ((char)payload[0] == '1'){
      digitalWrite(LED_VERDE, HIGH);  // Turn the LED off by making the voltage HIGH
    }
  }

  if(topic == IN_TOPIC_LED_ROJO.c_str()) {
    // Switch on the LED if an 1 was received as first character
    if ((char)payload[0] == '0') {
      digitalWrite(LED_ROJO, LOW);   // Turn the LED on (Note that LOW is the voltage level
    } else if ((char)payload[0] == '1'){
      digitalWrite(LED_ROJO, 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...");
    String client_id = "";
    // Attempt to connect
    if (client.connect(client_id.c_str(), USER, PASS)) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      //client.publish(OUT_TOPIC.c_str(), "hello world");
      // ... and resubscribe
      client.subscribe(IN_TOPIC_LED_VERDE.c_str());
      client.subscribe(IN_TOPIC_LED_ROJO.c_str());
      //client.subscribe(OUT_TOPIC_HUM.c_str());

    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}



// la función de setup() se ejecuta una vez cuando presionas el botón de reset o enciendes la placa
void setup() {

  Serial.begin(115200);        // inicializa el puerto serie (USB - COM) en una velocidad de comunicación de 115200 bauds
  Serial.println("\n\n");

  pinMode(LED_ROJO, OUTPUT);   // inicializa el pin digital LED_ROJO como salida.
  pinMode(LED_VERDE, OUTPUT);  // inicializa el pin digital LED_VERDE como salida.

  dht.begin(); // Inicializar dispositivo DHT
  Serial.println(F("Sensor DHT11"));
// Imprime los detalles del sensor de temperatura.
  sensor_t sensor;
  dht.temperature().getSensor(&sensor);
  Serial.println(F("------------------------------------"));
  Serial.println(F("Sensor de Temperatura"));
  Serial.print  (F("Valor Max:   ")); Serial.print(sensor.max_value); Serial.println(F("°C"));
  Serial.print  (F("Valor Min:   ")); Serial.print(sensor.min_value); Serial.println(F("°C"));
  Serial.print  (F("Resolucion:  ")); Serial.print(sensor.resolution); Serial.println(F("°C"));
// Imprime los detalles del sensor de humedad.
  dht.humidity().getSensor(&sensor);
  Serial.println(F("Sensor de Humedad"));
  Serial.print  (F("Valor Max:   ")); Serial.print(sensor.max_value); Serial.println(F("%"));
  Serial.print  (F("Valor Min:   ")); Serial.print(sensor.min_value); Serial.println(F("%"));
  Serial.print  (F("Resolucion:  ")); Serial.print(sensor.resolution); Serial.println(F("%"));
  Serial.println(F("------------------------------------"));

  pinMode(BUILTIN_LED, OUTPUT);     // Initialize the BUILTIN_LED pin as an output
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
}

// la función de loop() se ejecuta una y otra vez para siempre
void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();

  unsigned long now = millis();
  if (now - lastMsg > 2000) {
    lastMsg = now;

    // read the value from the sensor:
    sensorLDRValue = analogRead(LDR_PIN);
    Serial.print(F("LDR: "));
    Serial.print(sensorLDRValue);
    snprintf (msg, MSG_BUFFER_SIZE, "%ld", sensorLDRValue);
    client.publish(OUT_TOPIC_LDR.c_str(), msg);

    mostrar_datos_sensor_DHT11();

    Serial.println();

  }
}

void mostrar_datos_sensor_DHT11(){
  // Obtenga si hay evento de temperatura e imprima su valor.
  sensors_event_t event;
  dht.temperature().getEvent(&event);
  if (isnan(event.temperature)) {
    Serial.print(F("\t"));
    //Serial.println(F("¡Error al leer la temperatura!"));
  }
  else {
    Serial.print(F("\t"));
    Serial.print(F("Temperatura: "));
    Serial.print(event.temperature);
    snprintf (msg, MSG_BUFFER_SIZE, "%ld", (int) event.temperature);
    client.publish(OUT_TOPIC_TEMP.c_str(), msg);
    Serial.print(F("°C"));
  }
  // Obtenga si hay evento de humedad e imprima su valor.
  dht.humidity().getEvent(&event);
  if (isnan(event.relative_humidity)) {
    Serial.print(F("\t"));
    //Serial.println(F("¡Error al leer la humedad!"));
  }
  else {
    Serial.print(F("\t"));
    Serial.print(F("Humedad: "));
    Serial.print(event.relative_humidity);
    snprintf (msg, MSG_BUFFER_SIZE, "%ld", (int) event.relative_humidity);
    client.publish(OUT_TOPIC_HUM.c_str(), msg);
    Serial.print(F("%"));
  }
}

Ahora te toca a ti, coge el ejemplo del tutorial 4 y combinalo con el ejemplo anterior para poder enviar y recibir datos de los sensores.

Estos son los temas (topics) que debes usar:

Tipo

Descripción Unidades Topic MQTT
Sensor Lectura sensor temperatura DHT11 ºC taller/tXX/sens/DHT11/temp
Sensor Lectura sensor humedad relativa DHT11 %rh taller/tXX/sens/DHT11/hum
Sensor Lectura sensor luminosidad LDR Volts taller/tXX/sens/LDR
Actuador LED Indicador LED Verde   taller/tXX/leds/verde
Actuador LED Indicador LED Rojo   taller/tXX/leds/rojo

Recuerda cambiar t00 por el número de tu equipo

6. (Opcional) Comunicación de los datos utilizando el broker de MQTT de HiveMQ

¡¡NIVEL MEDIO!!

Para ejecutar este tutorial se debe utilizar la versión 1 del IDE de Arduino.

¿Porque HiveMQ Cloud?

Un agente gratuito de Cloud MQTT que le permite conectar hasta 100 dispositivos.

A free Cloud MQTT Broker that enables you to connect up to 100 devices.

https://www.hivemq.com/downloads/

Registrarse en el enlace anterior. Una vez registrado, nos aparece las siguientes opciones, los primeros datos hacen referencia a los datos de conexión del servidor.

server_info.png

El segundo apartado trata de rellenar los datos de conexión con un usuario y una contraseña robusta.

credenciales.png

Por último, accede al tutorial de arduino, justamente un tutorial para ESP8266.

select_option.png

tutorial_1.png

tutorial_2.png

EXAMPLE FILES - CERTS.AR AND SKETCH

tutorial_3.png

 

tutorial_4.png