The ESP32, successor to the ESP8266, is a low cost (less than $15), low power systems on a chip microcontroller with integrated Wi-Fi & dual-mode Bluetooth. The ESP32 series employs a Tensilica Xtensa LX6 microprocessor in both dual-core and single-core variations. The ESP32 was created and developed by Espressif Systems, a Shanghai-based Chinese company with a proven record of quality microcontroller production and distribution.

In this guide you will learn how to integrate your ESP32-DevKitC over MQTT to Ubidots. Below are the required steps to:

  • Set up your ESP32 with the Arduino IDE
  • Subscribe to a variable
  • Publish values to a variable
  • Subscribe to a variable and Publish values to a variable
  • Publish values to a variable (with context)

To learn more about the ESP32, reference the device documentation here.

Requirements

Step 1. Setup the Arduino IDE with your device 

To start this tutorial, we will begin by connecting your ESP32 to your computers port and programming your device.

1.- Begin by downloading the Arduino IDE, if you do not already have it.
2.- Next, install the ESP32 Platform to your Arduino IDE. Please reference the following links depending of your operating system. The following Espressif links will be prompt you to install the ESP32 to your computer. 

Note: If you are using Linux or Mac operating systems, an additional step is required as you need to install the ESP32 Platform to the Arduino IDE from your computer's terminal first. Use the below links to execute the required Terminal functions and then return to this guide to continue the ESP32 integration.

Reference image using a MacOS terminal:

3.- After installing the ESP32 platform using the above Espressif Systems links, you will have been prompted to restart the Arduino IDE - be sure to do so.

4.- After the reboot, select your ESP32 Dev Module from Tools > Board menu.

5.- Additionally, we need to be able to communicate with the ESP32, Let's be sure to select the port communication location. Go to Tools > Port >  Select the appropriate PORT for your device.

NOTE: If you are using Windows, you need to establish a serial connection between ESP32 and your computer please reference to this link to install the drivers needed and verify the connection. Also, as a MAC or Linux user, this link you will find how to verify serial communication should you want to.

6.- Next, go to Sketch/Program -> Include Library -> Library Manager and install the PubSubClient library. To simply find the correct library, search PubSubClient within the search bar. 

Note: be sure that you have install the latest version of PubSubClient. 

7.- Close the Arduino IDE and reboot.

Step 2. Set up your Ubidots account with your device

Login into your Ubidots account;
For Educational Licenses click here
For Business or Industrial Licenses click here

a) Subscribe to a variable

1.- Go to the device tab and create a new Device called “ESP32,"

Also you will need to add a variable called “relay”. Once the device is created, click to open and add a variable. Verify that the API labels are the same as their names within your code.

2.- Go to the dashboard tab to create a control widget to be able to control your ESP32. To add the a Widget, click on the "+" icon in the top right of the dashboard. Reference below:

To create the widget click Control > Switch > ESP32 > relay > finish.

Once your Widget is created you should see something like this appear on your Dashboard:  

With your active device, go back to the Arduino IDE and paste the code below. Once you have copied the code, you will need to assign the parameters: Wi-Fi name and password, MQTT client name, plus your individual, unique Ubidots TOKEN. If you don't how get your Ubidots TOKEN, please reference this article below. 

NOTE: You will need to make some adjustments to the first part of the code after you have pasted into Arduino IDE. This is to ensure your ESP32 is connecting to the correct server.

FOR EXAMPLE: Ubidots Code:

COMPARED TO SAMPLE USER´S PARAMETERS

Please copy and paste the below code into the Arduino IDE including your specific user parameters:

  • WiFi SSID
  • WiFi Password
  • Your Ubidots API Token
  • User Generated, Unique 8-12 Alphanumeric MQTT Client Name
/****************************************
 * Include Libraries
 ****************************************/
#include <WiFi.h>
#include <PubSubClient.h>

/****************************************
 * Define Constants
 ****************************************/
#define WIFISSID "Put_your_wifi_name_here" // Put your WifiSSID here
#define PASSWORD "Put_your_wifi_password_here" // Put your wifi password here
#define TOKEN "Put_your_Ubidots_TOKEN_here" // Put your Ubidots' TOKEN
#define MQTT_CLIENT_NAME "Put_your_MQTT_client_name_here" // MQTT client Name, please enter your own 8-12 alphanumeric character ASCII string;
                                           //it should be a random and unique ascii string and different from all other devices

#define VARIABLE_LABEL_SUBSCRIBE "relay" // Assing the variable label
#define DEVICE_LABEL "esp32" // Assig the device label

#define RELAY 16 // Set the GPIO16 as RELAY

char mqttBroker[]  = "things.ubidots.com";
char payload[100];
char topic[150];

/****************************************
 * Auxiliar Functions
 ****************************************/
WiFiClient ubidots;
PubSubClient client(ubidots);

void callback(char* topic, byte* payload, unsigned int length) {
  char p[length + 1];
  memcpy(p, payload, length);
  p[length] = NULL;
  String message(p);
  if (message == "0") {
    digitalWrite(RELAY, LOW);
  } else {
    digitalWrite(RELAY, HIGH);
  }
 
  Serial.write(payload, length);
  Serial.println();
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.println("Attempting MQTT connection...");
   
    // Attemp to connect
    if (client.connect(MQTT_CLIENT_NAME, TOKEN, "")) {
      Serial.println("Connected");
      client.subscribe("/v1.6/devices/"DEVICE_LABEL"/"VARIABLE_LABEL_SUBSCRIBE"/lv");
    } else {
      Serial.print("Failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 2 seconds");
      // Wait 2 seconds before retrying
      delay(2000);
    }
  }
}

/****************************************
 * Main Functions
 ****************************************/
void setup() {
  Serial.begin(115200);
  WiFi.begin(WIFISSID, PASSWORD);
  // Assign the pin as OUTPUT
  pinMode(RELAY, OUTPUT);

  Serial.println();
  Serial.print("Wait for WiFi...");
 
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
 
  Serial.println("");
  Serial.println("WiFi Connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  client.setServer(mqttBroker, 1883);
  client.setCallback(callback);
 
  client.subscribe("/v1.6/devices/"DEVICE_LABEL"/"VARIABLE_LABEL_SUBSCRIBE"/lv");
}

void loop() {
  if (!client.connected()) {
    reconnect();
    client.subscribe("/v1.6/devices/"DEVICE_LABEL"/"VARIABLE_LABEL_SUBSCRIBE"/lv");  
  }
  client.loop();
}

Once you pasted the code and updated the WiFi parameters, you must Verify this within the Arduino IDE. To do this, in the top left corner of our Arduino IDE you will see the below icons. Choose the Check Mark icon to verify any code.

Once the code is verified, you will receive a "Done compiling" message in the Arduino IDE.

Next, your have to upload the code into your ESP32. To do this, choose the right-arrow icon beside the check mark icon. 

Once the code is uploaded, you will receive a "Done uploading" message in the Arduino IDE.

Now you're able to control a variable! Go back to your Ubidots dashboard and change the status of the switch.

If your device sensors are not connected, you can still visualize if your device is responding through the Serial Monitor. To visualize the response of the server and the connectivity of the device open the Serial Monitor of the Arduino IDE. To do this, in the top right corner of our Arduino IDE select the magnifying glass icon to display a serial monitor. If your device is transmitting messages correctly you will begin to see the "0" for off and "1" for on in your Serial Monitor. With this confirmation, we can be sure you devices are connected and operating.

NOTE: if you like, feel free to modify this Device Name and Variable Name to anything friendly for your ease of use. But be sure your API Label is the same "ESP32" for the device and "relay" for the variable. For additional references, please check out this help center article detailing some important aspects of this step.

b) Publish values to a variable

With the following example you will be able to publish ANALOG reading taken from the GPIO12 pin of the ESP32.

To publish the value to Ubidots open a new window in the Arduino IDE and paste the code below. To open a new window select the sheet icon:

Remember change the parameters needed (WIFISSID, PASSWORD, TOKEN, and MQTTCLIENTNAME) as we made on the step before.

/****************************************
 * Include Libraries
 ****************************************/
#include <WiFi.h>
#include <PubSubClient.h>

#define WIFISSID "Put_your_wifi_name_here" // Put your WifiSSID here
#define PASSWORD "Put_your_wifi_password_here" // Put your wifi password here
#define TOKEN "Put_your_Ubidots_TOKEN_here" // Put your Ubidots' TOKEN
#define MQTT_CLIENT_NAME "Put_your_MQTT_client_name_here" // MQTT client Name, please enter your own 8-12 alphanumeric character ASCII string;
                                           //it should be a random and unique ascii string and different from all other devices

/****************************************
 * Define Constants
 ****************************************/
#define VARIABLE_LABEL "sensor" // Assing the variable label
#define DEVICE_LABEL "esp32" // Assig the device label

#define SENSOR 12 // Set the GPIO12 as SENSOR

char mqttBroker[]  = "things.ubidots.com";
char payload[100];
char topic[150];
// Space to store values to send
char str_sensor[10];

/****************************************
 * Auxiliar Functions
 ****************************************/
WiFiClient ubidots;
PubSubClient client(ubidots);

void callback(char* topic, byte* payload, unsigned int length) {
  char p[length + 1];
  memcpy(p, payload, length);
  p[length] = NULL;
  String message(p);
  Serial.write(payload, length);
  Serial.println(topic);
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.println("Attempting MQTT connection...");
   
    // Attemp to connect
    if (client.connect(MQTT_CLIENT_NAME, TOKEN, "")) {
      Serial.println("Connected");
    } else {
      Serial.print("Failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 2 seconds");
      // Wait 2 seconds before retrying
      delay(2000);
    }
  }
}

/****************************************
 * Main Functions
 ****************************************/
void setup() {
  Serial.begin(115200);
  WiFi.begin(WIFISSID, PASSWORD);
  // Assign the pin as INPUT
  pinMode(SENSOR, INPUT);

  Serial.println();
  Serial.print("Wait for WiFi...");
 
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
 
  Serial.println("");
  Serial.println("WiFi Connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  client.setServer(mqttBroker, 1883);
  client.setCallback(callback);  
}

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

  sprintf(topic, "%s%s", "/v1.6/devices/", DEVICE_LABEL);
  sprintf(payload, "%s", ""); // Cleans the payload
  sprintf(payload, "{\"%s\":", VARIABLE_LABEL); // Adds the variable label
 
  float sensor = analogRead(SENSOR);
 
  /* 4 is mininum width, 2 is precision; float value is copied onto str_sensor*/
  dtostrf(sensor, 4, 2, str_sensor);
 
  sprintf(payload, "%s {\"value\": %s}}", payload, str_sensor); // Adds the value
  Serial.println("Publishing data to Ubidots Cloud");
  client.publish(topic, payload);
  client.loop();
  delay(1000);
}

Once you pasted the code and updated the WiFi parameters, you must Verify this within the Arduino IDE. To do this, in the top left corner of our Arduino IDE you will see the below icons. Choose the Check Mark icon to verify any code.

Once the code is verified, you will receive a "Done compiling" message in the Arduino IDE.

Next, your have to upload the code into your ESP32. To do this, choose the right-arrow icon beside the check mark icon. 

Once the code is uploaded, you will receive a "Done uploading" message in the Arduino IDE.

To verify the connectivity of the device open the serial monitor and confirm data is sending. 

Now you should see the published data in your Ubidots account, inside the device called "ESP32".

c) Subscribes to a variable and Publish values to a variable

If you followed the steps prior, you're now able to subscribes and publish data to Ubidots. If you wish to compile both subscribe and publish data using a single code, the code below will provide you with this full functionality. 

Note: if you have skipped the previous 2 steps to Subscribe and Publish, variable will not automatically be created and you will need to do so manually. Please revert back to the Subscribe and Publish steps previously to determine how to create a variable. 

Once you have pasted the code into the Arduino IDE don't forget change the parameters needed (WIFISSID, PASSWORD, TOKEN, and MQTTCLIENTNAME) as we made before.

/****************************************
 * Include Libraries
 ****************************************/
#include <WiFi.h>
#include <PubSubClient.h>

/****************************************
 * Define Constants
 ****************************************/
#define WIFISSID "Put_your_wifi_name_here" // Put your WifiSSID here
#define PASSWORD "Put_your_wifi_password_here" // Put your wifi password here
#define TOKEN "Put_your_Ubidots_TOKEN_here" // Put your Ubidots' TOKEN
#define MQTT_CLIENT_NAME "Put_your_MQTT_client_name_here" // MQTT client Name, please enter your own 8-12 alphanumeric character ASCII string;
                                           //it should be a random and unique ascii string and different from all other devices

#define VARIABLE_LABEL_PUBLISH "sensor" // Assing the variable label
#define VARIABLE_LABEL_SUBSCRIBE "relay" // Assing the variable label
#define DEVICE_LABEL "esp32" // Assig the device label

#define SENSOR 12 // Set the GPIO12 as SENSOR
#define RELAY 16 // Set the GPIO16 as RELAY

char mqttBroker[]  = "things.ubidots.com";
char payload[100];
char topic[150];
// Space to store values to send
char str_sensor[10];

/****************************************
 * Auxiliar Functions
 ****************************************/
WiFiClient ubidots;
PubSubClient client(ubidots);

void callback(char* topic, byte* payload, unsigned int length) {
  char p[length + 1];
  memcpy(p, payload, length);
  p[length] = NULL;
  String message(p);
  if (message == "0") {
    digitalWrite(RELAY, LOW);
  } else {
    digitalWrite(RELAY, HIGH);
  }
  Serial.write(payload, length);
  Serial.println();
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.println("Attempting MQTT connection...");
   
    // Attemp to connect
    if (client.connect(MQTT_CLIENT_NAME, TOKEN, "")) {
      Serial.println("Connected");
      client.subscribe("/v1.6/devices/"DEVICE_LABEL"/"VARIABLE_LABEL_SUBSCRIBE"/lv");
    } else {
      Serial.print("Failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 2 seconds");
      // Wait 2 seconds before retrying
      delay(2000);
    }
  }
}

/****************************************
 * Main Functions
 ****************************************/
void setup() {
  Serial.begin(115200);
  WiFi.begin(WIFISSID, PASSWORD);
  // Assign the pins as INPUT/OUTPUT
  pinMode(SENSOR, INPUT);
  pinMode(RELAY, OUTPUT);

  Serial.println();
  Serial.print("Wait for WiFi...");
 
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
 
  Serial.println("");
  Serial.println("WiFi Connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  client.setServer(mqttBroker, 1883);
  client.setCallback(callback);
 
  client.subscribe("/v1.6/devices/"DEVICE_LABEL"/"VARIABLE_LABEL_SUBSCRIBE"/lv");
}

void loop() {
  if (!client.connected()) {
    reconnect();
    client.subscribe("/v1.6/devices/"DEVICE_LABEL"/"VARIABLE_LABEL_SUBSCRIBE"/lv");  
  }
  sprintf(topic, "%s%s", "/v1.6/devices/", DEVICE_LABEL);  
  sprintf(payload, "%s", ""); // Cleans the payload
  sprintf(payload, "{\"%s\":", VARIABLE_LABEL_PUBLISH); // Adds the variable label
 
  float sensor = analogRead(SENSOR);
 
  /* 4 is mininum width, 2 is precision; float value is copied onto str_sensor*/
  dtostrf(sensor, 4, 2, str_sensor);
 
  sprintf(payload, "%s {\"value\": %s}}", payload, str_sensor); // Adds the value
  Serial.println("Publishing data to Ubidots Cloud");
  client.publish(topic, payload);
  client.loop();
  delay(1000);
}

Once you have pasted the code and updated the WiFi parameters, you must Verify this within the Arduino IDE. To do this, in the top left corner of our Arduino IDE you will see the below icons. Choose the Check Mark icon to verify any code.

Once the code is verified, you will receive a "Done compiling" message in the Arduino IDE.

Next, your have to upload the code into your ESP32. To do this, choose the right-arrow icon beside the check mark icon. 

Once the code is uploaded, you will receive a "Done uploading" message in the Arduino IDE.

d) Publish values to a variable (with context)

Also, using the following example you will be able to publish data with context to Ubidots. It will create the variable automatically with the label assign by you on the code.

Remember change the parameters needed (WIFISSID, PASSWORD, TOKEN, and MQTTCLIENTNAME) as we made on the step before.

/****************************************
 * Include Libraries
 ****************************************/
#include <WiFi.h>
#include <PubSubClient.h>

/****************************************
 * Define Constants
 ****************************************/
#define WIFISSID "Put_your_wifi_name_here" // Put your WifiSSID here
#define PASSWORD "Put_your_wifi_password_here" // Put your wifi password here
#define TOKEN "Put_your_Ubidots_TOKEN_here" // Put your Ubidots' TOKEN
#define MQTT_CLIENT_NAME "Put_your_MQTT_client_name_here" // MQTT client Name, please enter your own 8-12 alphanumeric character ASCII string;
                                           //it should be a random and unique ascii string and different from all other devices

#define VARIABLE_LABEL "sensor" // Assing the variable label
#define DEVICE_LABEL "esp32" // Assig the device label

#define SENSOR 12 // Set the GPIO12 as SENSOR

char mqttBroker[]  = "things.ubidots.com";
char payload[100];
char topic[150];
// Space to store values to send
char str_sensor[10];
char str_lat[6];
char str_lng[6];

/****************************************
 * Auxiliar Functions
 ****************************************/
WiFiClient ubidots;
PubSubClient client(ubidots);

void callback(char* topic, byte* payload, unsigned int length) {
  char p[length + 1];
  memcpy(p, payload, length);
  p[length] = NULL;
  String message(p);
  Serial.write(payload, length);
  Serial.println(topic);
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.println("Attempting MQTT connection...");
   
    // Attemp to connect
    if (client.connect(MQTT_CLIENT_NAME, TOKEN, "")) {
      Serial.println("Connected");
    } else {
      Serial.print("Failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 2 seconds");
      // Wait 2 seconds before retrying
      delay(2000);
    }
  }
}

/****************************************
 * Main Functions
 ****************************************/
void setup() {
  Serial.begin(115200);
  WiFi.begin(WIFISSID, PASSWORD);
  // Assign the pin as INPUT
  pinMode(SENSOR, INPUT);

  Serial.println();
  Serial.print("Wait for WiFi...");
 
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
 
  Serial.println("");
  Serial.println("WiFi Connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  client.setServer(mqttBroker, 1883);
  client.setCallback(callback);  
}

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

  sprintf(topic, "%s%s", "/v1.6/devices/", DEVICE_LABEL);
  sprintf(payload, "%s", ""); // Cleans the payload
  sprintf(payload, "{\"%s\":", VARIABLE_LABEL); // Adds the variable label
 
  float sensor = analogRead(SENSOR);
  float lat = 6.101;
  float lng= -1.293;

  /* 4 is mininum width, 2 is precision; float value is copied onto str_sensor*/
  dtostrf(sensor, 4, 2, str_sensor);
  dtostrf(lat, 4, 2, str_lat);
  dtostrf(lng, 4, 2, str_lng);  
 
  sprintf(payload, "%s {\"value\": %s", payload, str_sensor); // Adds the value
  sprintf(payload, "%s, \"context\":{\"lat\": %s, \"lng\": %s}", payload, str_lat, str_lng); // Adds coordinates
  sprintf(payload, "%s } }", payload); // Closes the dictionary brackets
  Serial.println("Publishing data to Ubidots Cloud");
  client.publish(topic, payload);
  client.loop();
  delay(1000);
}


Once you have pasted the code and updated the WiFi parameters, you must Verify this within the Arduino IDE. To do this, in the top left corner of our Arduino IDE you will see the below icons. Choose the Check Mark icon to verify any code.

Once the code is verified, you will receive a "Done compiling" message in the Arduino IDE.

Next, your have to upload the code into your ESP32. To do this, choose the right-arrow icon beside the check mark icon. 

Once the code is uploaded, you will receive a "Done uploading" message in the Arduino IDE.

Inside the variable called "sensor" you will be able to visualize the context similar to that below.

NOTE: if you desire to change the Device Label and Variable Label you can do so by changing the following lines in the code. Please refer to the this article to understand the difference between the Device Name and Variable Name and the Device Label and Variable Label to make your application more user-nomenclature friendly. 

Result

Now it is time to create a dashboard to control and manage the variables of your ESP32 device. To learn more about Ubidots widgets and events, check out these video tutorials.

Happy hacking :)

Did this answer your question?