ESP32. MQTT. Broker. Publish. Subscribe. ThingSpeak

1.- MQTT.

  • MQTT (Message Queue Telemetry Transport) is a protocol widely used in the Internet of Things (IoT).

  • It uses short data.

  • MQTT Broker is a server where we will send the data for clients to read.

  • Example de Brokers: mqtt.eclipse.org, broker.hivemq.com, io.adafruit, ThingSpeak, Cayenne, mosquitto…

  • It is very common for Raspberry Pi fans to install the mosquitto broker.

  • The way of using it is similar to CloudDB or FireBase, we send a data to the cloud-broker (internet) and the clients read this data in “real time”.

  • A device sends data (Publish) to Broker. Other device receives that data from Broker (Subscribe).

  • ESP32 is connected to our Router by WiFi.

  • ESP32 Publish a topic (juan/temperatura) with a value (payload) to Broker.
    Mobile is Subscribed to that topic, receives that value in “real time”.

1 Like

2.- ESP32 Publish random numbers. App is Subscrited to that topic and receive those numbers.

// Juan A. Villalpando.
// http://kio4.com/arduino/117_Wemos_MQTT.htm

//#include <ESP8266WiFi.h> // Para el ESP8266
#include <WiFi.h> // Para el ESP32
WiFiClient WIFI_CLIENT;
#include <PubSubClient.h>
PubSubClient MQTT_CLIENT;

const char* ssid = "Name_your_WiFi";
const char* password = "Password_WiFi";

void setup() {
Serial.begin(115200);
delay(10);
Serial.println();
Serial.print("Connecting with ");
Serial.println(ssid);

WiFi.begin(ssid, password);

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

Serial.println("");
Serial.print("WiFi conected. IP: ");
Serial.println(WiFi.localIP());
}

void loop() {
// Check MQTT Broker connection,
// en caso de que no tenga, reconecta.
if (!MQTT_CLIENT.connected()) {
reconnect();
}

// Publish topic.
// Convierte el entero a char. Debe ser char.
int aleatorio = random(1,90);
String aleatorioString = String(aleatorio);
char alea[6];
aleatorioString.toCharArray(alea, 6);

MQTT_CLIENT.publish("juan/aleatorio", alea);

// Wait 5 s.
delay(5000);
}


// Reconecta con MQTT broker
void reconnect() {
MQTT_CLIENT.setServer("broker.hivemq.com", 1883);  
//MQTT_CLIENT.setServer("mqtt.eclipse.org", 1883);
MQTT_CLIENT.setClient(WIFI_CLIENT);

// Trying connect with broker.
while (!MQTT_CLIENT.connected()) {
Serial.println("Trying to connect with Broker MQTT.");
MQTT_CLIENT.connect("JuanAntonio"); // it isn't necessary..

// Wait to try to reconnect again...
delay(3000);
}

Serial.println("Conectado a MQTT.");
}

- In Linear MQTT app

App settings…
Server : broker.hivemq.com
Port: 1883
It is not necessary Username, Password.

Value
Name: aleatorio
Sub. topic: juan/aleatorio

Graph
Name: aleatorio
Sub. topic: juan/aleatorio

1 Like

3.- App Publish status Button. ESP32 is Subscripted to that topic and receive that status. LED2 on/off

  • Now we add a button (Switch) to the application, see the image.
  • The application will Publish the status of the Swicht through the topic juan/boton
  • When Swicht button, LED2 on/off [LED2 is LED_BUILTIN in ESP32 board]

// Juan A. Villalpando.
// http://kio4.com/arduino/117_Wemos_MQTT.htm

//#include <ESP8266WiFi.h> // Para el ESP8266
#include <WiFi.h> // Para el ESP32
WiFiClient WIFI_CLIENT;
#include <PubSubClient.h>
PubSubClient MQTT_CLIENT;

const char* ssid = "Name_Net_Wifi";
const char* password = "Password_Wifi";

// const byte led4 = D4; // LED ESP8266
const byte LED2 = 2; // LED ESP32

void setup() {
  pinMode(LED2, OUTPUT);
  Serial.begin(115200);
  delay(10);
  Serial.println();
  Serial.print("Connecting with ");
  Serial.println(ssid);

  
  WiFi.begin(ssid, password);

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

Serial.println("");
Serial.print("WiFi conected. IP: ");
Serial.println(WiFi.localIP());

// Setting Callback.
  MQTT_CLIENT.setCallback(callback);
}

// What to do when it receives the data. 
void callback(char* recibido, byte* payload, unsigned int length) {
  Serial.print("Message received: ");
  Serial.print(recibido);
  Serial.print("   ");
  for (int i=0;i<length;i++) {
    char receivedChar = (char)payload[i];
    Serial.print(receivedChar);
  if (receivedChar == '1') {digitalWrite(LED2, HIGH);}
  if (receivedChar == '0') {digitalWrite(LED2, LOW);}
  }
  Serial.println();
}
 
void loop() {
  if (!MQTT_CLIENT.connected()) {
    reconnect();
  }
  MQTT_CLIENT.loop(); // Check Subscription.
}

// Reconecta con MQTT broker
void reconnect() {
MQTT_CLIENT.setServer("broker.hivemq.com", 1883);  
//MQTT_CLIENT.setServer("mqtt.eclipse.org", 1883);
MQTT_CLIENT.setClient(WIFI_CLIENT);

// Trying connect with broker.
while (!MQTT_CLIENT.connected()) {
Serial.println("Trying to connect with Broker MQTT.");
MQTT_CLIENT.connect("JuanAntonio"); // it isn't necessary..
MQTT_CLIENT.subscribe("juan/boton"); // HERE SUBSCRIBE.

// Wait to try to reconnect again...
delay(3000);
}

Serial.println("Conectado a MQTT.");
}
1 Like

4.- Now the two codes united.

ESP32 Publish: juan/aleatorio
ESP32 Subscript to: juan/boton

App Publish: juan/boton
App Subscript to: juan/aleatorio

// Juan A. Villalpando.
// http://kio4.com/arduino/117_Wemos_MQTT.htm

//#include <ESP8266WiFi.h> // Para el ESP8266
#include <WiFi.h> // Para el ESP32
WiFiClient WIFI_CLIENT;
#include <PubSubClient.h>
PubSubClient MQTT_CLIENT;

const char* ssid = "Nombre_red_Wifi";
const char* password = "Clave_Wifi";

// const byte led4 = D4; // LED4 ESP8266
const byte LED2 = 2; // LED2 ESP32

void setup() {
  pinMode(LED2, OUTPUT);
  Serial.begin(115200);
  delay(10);
  Serial.println();
  Serial.print("Connecting with ");
  Serial.println(ssid);

  
  WiFi.begin(ssid, password);

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

Serial.println("");
Serial.print("WiFi conected. IP: ");
Serial.println(WiFi.localIP());

// Setting Callback.
  MQTT_CLIENT.setCallback(callback);
}

// What to do when it receives the data. 
void callback(char* recibido, byte* payload, unsigned int length) {
  Serial.print("Message received: ");
  Serial.print(recibido);
  Serial.print("   ");
  for (int i=0;i<length;i++) {
    char receivedChar = (char)payload[i];
    Serial.print(receivedChar);
  if (receivedChar == '1') {digitalWrite(LED2, HIGH);}
  if (receivedChar == '0') {digitalWrite(LED2, LOW);}
  }
  Serial.println();
}
 
void loop() {
  if (!MQTT_CLIENT.connected()) {
    reconnect();
  }

// PUBLISH topic.
// Convierte el entero a char. Debe ser char.
int aleatorio = random(1,90);
String aleatorioString = String(aleatorio);
char alea[6];
aleatorioString.toCharArray(alea, 6);

MQTT_CLIENT.publish("juan/aleatorio", alea);

// Wait 2 s.
delay(2000); // DELAY
////////////////////////////////////

// CHECK SUBCRIPTION. 
  MQTT_CLIENT.loop(); // Check Subscription.
}

// Reconecta con MQTT broker
void reconnect() {
MQTT_CLIENT.setServer("broker.hivemq.com", 1883);  
//MQTT_CLIENT.setServer("mqtt.eclipse.org", 1883);
MQTT_CLIENT.setClient(WIFI_CLIENT);

// Trying connect with broker.
while (!MQTT_CLIENT.connected()) {
Serial.println("Trying to connect with Broker MQTT.");
MQTT_CLIENT.connect("JuanAntonio"); // it isn't necessary..
MQTT_CLIENT.subscribe("juan/boton"); // HERE SUBSCRIBE.

// Wait to try to reconnect again...
delay(3000);
}

Serial.println("Conectado a MQTT.");
}
1 Like

5.- Slider.

6.- App Inventor Subscribe to juan/aleatorio and Publish juan/boton.

p117B_mqtt_Extension.aia (74.0 KB)

  • Code for ESP32 is the same as example: 4.- Now the two codes united.

Broker: broker.hivemq.com
Port: 1883

ESP32 Publish: juan/aleatorio
ESP32 Subscribe: juan/boton

App Inventor Publish: juan/boton
App Inventor Subscribe: juan/aleatorio

App Inventor.

1 Like

7.- App on/off LED12 and LED14 of ESP32. App checks status LED12 and LED14.

p117B_mqtt_Extension_Btn_LED.aia (74.8 KB)

  • App Publish boton12 and boton14, and on/off LED12 and LED14
  • ESP32 Subscripted to boton12 and boton14 Publish status LEDs

Broker: broker.hivemq.com
Port: 1883

App Inventor Publish: juan/boton12
App Inventor Publish: juan/boton14
App Inventor Subscribe: juan/led12_status
App Inventor Subscribe: juan/led14_status
App Inventor Subscribe: juan/led12_led14_status

ESP32 Publish: juan/led12_status
ESP32 Publish: juan/led14_status
ESP32 Publish: juan/led12_led14_status
ESP32 Subscribe: juan/boton12
ESP32 Subscribe: juan/boton14


// Juan A. Villalpando.
// http://kio4.com/arduino/117_Wemos_MQTT.htm

//#include <ESP8266WiFi.h> // Para el ESP8266
#include <WiFi.h> // Para el ESP32
WiFiClient WIFI_CLIENT;
#include <PubSubClient.h>
PubSubClient MQTT_CLIENT;

const char* ssid = "Nombre_Red_WiFi";
const char* password = "Clave_Wifi";

#define LED12 12 // LED12 ESP32
#define LED14 14 // LED14 ESP32
String LED12_status = "- ? -";
String LED14_status = "- ? -";
String LED12_LED14_status = "- ? -";

void setup() {
  pinMode(LED12, OUTPUT);
  pinMode(LED14, OUTPUT);
  Serial.begin(115200);
  delay(10);
  Serial.println();
  Serial.print("Connecting with ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

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

Serial.println("");
Serial.print("WiFi conected. IP: ");
Serial.println(WiFi.localIP());

// Setting Callback.
  MQTT_CLIENT.setCallback(callback);
}

// What to do when it receives the data. 
void callback(char* recibido, byte* payload, unsigned int length) {
  Serial.print("Message received: ");
  Serial.print(recibido);
  Serial.print("   ");

  for (int i=0;i<length;i++) {
    char receivedChar = (char)payload[i];
    Serial.println(receivedChar);
  if (receivedChar == '1') {digitalWrite(LED12, HIGH);}
  if (receivedChar == '2') {digitalWrite(LED12, LOW);}
  if (receivedChar == '3') {digitalWrite(LED14, HIGH);}
  if (receivedChar == '4') {digitalWrite(LED14, LOW);}

    if (digitalRead(LED12) == HIGH) {LED12_status = "LED12 ON";} else {LED12_status = "LED12 OFF";}
    if (digitalRead(LED14) == HIGH) {LED14_status = "LED14 ON";} else {LED14_status = "LED14 OFF";}
    LED12_LED14_status = LED12_status + " and " + LED14_status; 
  }
}
 
void loop() {
  if (!MQTT_CLIENT.connected()) {
    reconnect();
  }

  // PUBLISH topic.
// Convierte el entero a char. Debe ser char.
char led12_st[10];
char led14_st[10];
char led12_led14_st[25];
LED12_status.toCharArray(led12_st, 10);
LED14_status.toCharArray(led14_st, 10);
LED12_LED14_status.toCharArray(led12_led14_st, 25);

MQTT_CLIENT.publish("juan/led12_status", led12_st);
  delay(1000);
MQTT_CLIENT.publish("juan/led14_status", led14_st);
  delay(1000);
MQTT_CLIENT.publish("juan/led12_led14_status", led12_led14_st);
  delay(1000);
  
  MQTT_CLIENT.loop(); // Check Subscription.

}

// Reconecta con MQTT broker
void reconnect() {
MQTT_CLIENT.setServer("broker.hivemq.com", 1883);  
//MQTT_CLIENT.setServer("mqtt.eclipse.org", 1883);
MQTT_CLIENT.setClient(WIFI_CLIENT);

// Trying connect with broker.
while (!MQTT_CLIENT.connected()) {
Serial.println("Trying to connect with Broker MQTT.");
MQTT_CLIENT.connect("JuanAntonio"); // it isn't necessary..
MQTT_CLIENT.subscribe("juan/boton12"); // HERE SUBSCRIBE.
MQTT_CLIENT.subscribe("juan/boton14"); // HERE SUBSCRIBE.

// Wait to try to reconnect again...
delay(3000);
}

Serial.println("Conectado a MQTT.");
}
2 Likes

8.- App Inventor Publish a text.

p117B_mqtt_Extension_Texto.aia (73.5 KB)

  • App Publish a text: “Set LED12 ON”, “Set LED12 OFF”,…

// Juan A. Villalpando.
// http://kio4.com/arduino/117_Wemos_MQTT.htm

//#include <ESP8266WiFi.h> // Para el ESP8266
#include <WiFi.h> // Para el ESP32
WiFiClient WIFI_CLIENT;
#include <PubSubClient.h>
PubSubClient MQTT_CLIENT;

const char* ssid = "Nombre_Red_Wifi";
const char* password = "Clave_Wifi";

#define LED12 12 // LED12 ESP32
#define LED14 14 // LED14 ESP32
String message = "";

void setup() {
  pinMode(LED12, OUTPUT);
  pinMode(LED14, OUTPUT);
  Serial.begin(115200);
  delay(10);
  Serial.println();
  Serial.print("Connecting with ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

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

Serial.println("");
Serial.print("WiFi conected. IP: ");
Serial.println(WiFi.localIP());

// Setting Callback.
  MQTT_CLIENT.setCallback(callback);
}

// What to do when it receives the data. 
void callback(char* recibido, byte* payload, unsigned int length) {
  Serial.print("Message received: ");
  Serial.print(recibido);
  Serial.print("   ");
  message = "";
  for (int i=0;i<length;i++) {
    message += (char)payload[i];
  }
   Serial.println(message);
   if (message == "Set LED12 ON") {digitalWrite(LED12, HIGH);}
   if (message == "Set LED12 OFF") {digitalWrite(LED12, LOW);}
   if (message == "Set LED14 ON") {digitalWrite(LED14, HIGH);}
   if (message == "Set LED14 OFF") {digitalWrite(LED14, LOW);}
}
 
void loop() {
  if (!MQTT_CLIENT.connected()) {
    reconnect();
  }

  // PUBLISH topic.
  // Does not Publish.
  
  MQTT_CLIENT.loop(); // Check Subscription.

}

// Reconecta con MQTT broker
void reconnect() {
MQTT_CLIENT.setServer("broker.hivemq.com", 1883);  
//MQTT_CLIENT.setServer("mqtt.eclipse.org", 1883);
MQTT_CLIENT.setClient(WIFI_CLIENT);

// Trying connect with broker.
while (!MQTT_CLIENT.connected()) {
Serial.println("Trying to connect with Broker MQTT.");
MQTT_CLIENT.connect("JuanAntonio"); // it isn't necessary..
MQTT_CLIENT.subscribe("juan/boton12"); // HERE SUBSCRIBE.
MQTT_CLIENT.subscribe("juan/boton14"); // HERE SUBSCRIBE.

// Wait to try to reconnect again...
delay(3000);
}

Serial.println("Conectado a MQTT.");
}
1 Like

9.- App Publish and moves a Servo in ESP32.

p117B_mqtt_Extension_Servo.aia (73.6 KB)

  • Publish juan/mensaje = “increases” —> increases grado +5
  • Publish juan/mensaje = “decreases” —> decreases grado -5
  • Publish juan/mensaje = 90* —> Move Servo to those position

// Juan A. Villalpando.
// http://kio4.com/arduino/117_Wemos_MQTT.htm

//#include <ESP8266WiFi.h> // Para el ESP8266
#include <WiFi.h> // Para el ESP32
WiFiClient WIFI_CLIENT;
#include <PubSubClient.h>
PubSubClient MQTT_CLIENT;

const char* ssid = "Nombre_Red_Wifi";
const char* password = "Clave_Wifi";

// Servo.
#include <Servo.h>
Servo myservo;
#define servoPin  27 // El servo en pin 27
int grado = 90;
String message = "";

void setup() {
  Serial.begin(115200);
  delay(10);
  myservo.attach(servoPin);
  Serial.println();
  Serial.print("Connecting with ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

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

Serial.println("");
Serial.print("WiFi conected. IP: ");
Serial.println(WiFi.localIP());

// Setting Callback.
  MQTT_CLIENT.setCallback(callback);
}

// What to do when it receives the data. 
void callback(char* recibido, byte* payload, unsigned int length) {
  Serial.print("Message received: ");
  Serial.print(recibido);
  Serial.print("   ");
  message = "";
  for (int i=0;i<length;i++) {
    message += (char)payload[i];
  }
   Serial.println(message);
   if (message == "increases") {grado = grado + 5; myservo.write(grado);}
   if (message == "decreases") {grado = grado - 5; myservo.write(grado);}
   if (message.indexOf("*") != -1)  { // if message contain *
   message = message.substring(0, message.length() - 1); // Delete last char *
   grado = message.toInt();
   myservo.write(grado);
   }
}
 
void loop() {
  if (!MQTT_CLIENT.connected()) {
    reconnect();
  }

  // PUBLISH topic.
  // Does not Publish.
  
  MQTT_CLIENT.loop(); // Check Subscription.

}

// Reconecta con MQTT broker
void reconnect() {
MQTT_CLIENT.setServer("broker.hivemq.com", 1883);  
//MQTT_CLIENT.setServer("mqtt.eclipse.org", 1883);
MQTT_CLIENT.setClient(WIFI_CLIENT);

// Trying connect with broker.
while (!MQTT_CLIENT.connected()) {
Serial.println("Trying to connect with Broker MQTT.");
MQTT_CLIENT.connect("JuanAntonio"); // it isn't necessary..
MQTT_CLIENT.subscribe("juan/mensaje"); // HERE SUBSCRIBE.

// Wait to try to reconnect again...
delay(3000);
}

Serial.println("Conectado a MQTT.");
}
  • It is convenient that the Servo is powered by an external power supply.

10.- Mobile chat.

p117B_mqtt_Extension_Chat.aia (73.8 KB)

oooooooooooooo000oooooooooooooo

1 Like

11.- ThingSpeak Broker. ESP32 uploads random numbers to ThingSpeak.

  • It is necessary to register with an email account: ThingSpeak.
  • For users of the free option, the message update interval limit remains limited at 15 seconds.
  • New Channel.
    Field1 = aleatorio.

  • ESP32 generates a random number every 15 seconds and uploads it to ThingSpeak.

  • Library ThingSpeak.

  • Sketch / Include Library / Manage Libraries… ThingSpeak

// Juan A. Villalpando.
// http://kio4.com/arduino/117_Wemos_MQTT.htm

// #include <ESP8266WiFi.h> // Para ESP8266
#include <WiFi.h> // Para ESP32
WiFiClient WIFI_CLIENT;
#include <ThingSpeak.h>

const char* ssid = "Nombre_de_tu_Red_Wifi";
const char* password = "Clave_Wifi";  

unsigned long Channel_ID = 746330;
const char * WriteAPIKey = "SVRKZNDDNS9TÑÑÑÑ";
unsigned long tiempo_actual = 0;

void setup() {
  Serial.begin(115200);

  WiFi.mode(WIFI_STA);   
  ThingSpeak.begin(WIFI_CLIENT);

  Serial.println();
  Serial.print("Connecting with ");
  Serial.println(ssid);
 
  WiFi.begin(ssid, password);
 
  while (WiFi.status() != WL_CONNECTED) {
  delay(500);
  Serial.print(".");
  }
  
  Serial.println("");
  Serial.print("WiFi conected. IP: ");
  Serial.println(WiFi.localIP());
}

void loop() {
  if((millis()-tiempo_actual)>= 16000){ // Each 16 seconds upload.
          int alea = random(0,90);
          tiempo_actual = millis();
          // Send alea to field1.
          int x = ThingSpeak.writeField(Channel_ID, 1, alea, WriteAPIKey);
          if(x == 200){ Serial.println("Upload correct: " + String(alea));}
          else{ Serial.println("Upload failed: " + String(alea)); }
  }
}
1 Like

12.- From App Inventor on/off a Lamp in ThingSpeak.

Remember: updates are every 15 seconds or more.

  • This example does not use ESP32.

  • Channel Settings / Field2 --> lamp
  • Add Widgets --> Lamp

2 Likes

13.- App Inventor sends a number to ThingSpeak and gets last value. WebViewer.

Remember: updates are every 15 seconds or more.

p117_thingspeak_valor.aia (3.2 KB)

esp32_thing22

1 Like

14.- App Inventor Publish, sends values by Extension to ThingSpeak.

  • Now with extension.
  • Subscribe doesn’t work for me.

Subscribe: channels/Channel ID/subscribe/fields/field1/ReadAPIKey

Publish: channels/Channel ID/publish/fields/field1/WriteAPIKey

last value: https://api.thingspeak.com/channels/746330/fields/field1/last

1 Like

15.- Others Dashboards.

https://mydevices.com/cayenne/signup/

https://accounts.adafruit.com/settings/profile

http://www.hivemq.com/demos/websocket-client/

1 Like

great job
muy buena explicacion de todo, hice unas pruebas con cloudmqtt con un wemos d1 esp8266 y funciona perfecto todo.
la extension es muy buena.
gracias por toda la informacion.

16.- Basic example of Subscribe and Publish to HiveMQ.

Normally MQTT is used in IoT, example: a sensor in a hardware sends a short message to a Broker and in real time an app receives it, or an app sends a short message to a Broker and this information is received by a hardware that performs a certain function.

We are going to see a basic example of Publish and Subscribe in the HiveMQ Broker.
We will not use hardware, only the application and the Broker.

  • Do this example! No registration required.

https://www.hivemq.com/

p117B_mqtt_Extension_Hivemq.aia (73.6 KB)






esp32_mqtt6
esp32_mqtt7

17.- Example with Slider.

p117Bi_mqtt_Extension_Hivemq_Slider.aia (83.7 KB)

1 Like

18 .- AccelerometerSensor Publish and Subscribe x, y, z. Send and receive the three variables. HiveMQ.

p117B_mqtt_Extension_Hivemq_Acele.aia (72.0 KB)

AcceleratorSensor "Publish" in HiveMQ xAccel,yAccel,zAccel with topic: juan/acelerometer
and "Subscribe" juan/acelerometer, receive: xAccel,yAccel,zAccel

1 Like

why port at hivemq not same with port at mit app?
if i write at hivemq, host : broker.hivemq.com. , at mit app must be broker: broker.hivemq.com . it right?

the topic at publish should be title that my project right?