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.

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

Following this guide you will be able to PUBLISH and SUBSCRIBE data to/from Ubidots using the ESP32 in just a couple of minutes!

Requirements

Step-By-Step

  1. Set up your ESP32 with the Arduino IDE
  2. Publish values to a variable
  3. Publish values to a variable (with context)
  4. Subscribe to a variable
  5. Summary

1. Set up your ESP32 with the Arduino IDE

To start this tutorial, we will begin by connecting your ESP32 to your computers USB port to program the device.

1. Begin by downloading the Arduino IDE, if you have not done so already.

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 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 be 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, the link describes how to verify serial communication should you want to.

6. Next, download and install the PubSubClient Library. For a detailed explanation of how to install libraries using the Arduino IDE, refer to this guide.

2. Publish values to a variable

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

1. To publish your first value in Ubidots, open the Arduino IDE and paste the sample code below. Once you have pasted the code, you must assign your unique Ubidots TOKEN, MQTTCLIENTNAME, SSID (WiFi Name) and Password of the available network.

NOTE: The MQTT client name should be a random 8 - 12 alphanumeric character ASCII String.  

/****************************************
 * 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);
}

2. Verify your code within the Arduino IDE. To do this, in the top left corner of our Arduino IDE you will see the "Check Mark" icon; press it to verify your code. 

3. Upload the code into your ESP32 Dev Module. To do this, choose the "right-arrow" icon beside the "check mark" icon. 

4. To verify the connectivity of the device and the data sent, open the serial monitor by selecting the "magnifying glass" icon in the top right corner of the Arduino IDE to see the connectivity logs. 

NOTE: If no response is seen, try unplugging your ESP32 and then plugging it again. Make sure the baud rate of the Serial monitor is set to the same one specified in your code 115200

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

3. Publish values to a variable (with context) 

Using the following example code you will be able to publish data with context to Ubidots. It will create the variable automatically with the label assigned by the code.

1. To publish a value with context in Ubidots, open the Arduino IDE and paste the sample code below. Once you have pasted the code, you must assign your unique Ubidots TOKEN, MQTTCLIENTNAME, SSID (WiFi Name) and Password of the available network.

/****************************************
 * 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);
}

2. Verify your code within the Arduino IDE. To do this, in the top left corner of our Arduino IDE you will see the "Check Mark" icon; press it to verify your code. 

3. Upload the code into your ESP32 Dev Module. To do this, choose the "right-arrow" icon beside the "check mark" icon. 

4. To verify the connectivity of the device and the data sent, open the serial monitor by selecting the "magnifying glass" icon in the top right corner of the Arduino IDE to see the connectivity logs. 

NOTE: If no response is seen, try unplugging your ESP32 and then plugging it again. Make sure the baud rate of the Serial monitor is set to the same one specified in your code 115200

Now you should see the published data in your Ubidots account, inside the device called "ESP32". 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. 

4. Subscribe to a variable

With the following sample code you will be able to subscribe a value from Ubidots to start controlling any asset you desire. 

1. To begin getting values from Ubidots, open the Arduino IDE and paste the sample code below. Once you have pasted the code, be sure to assign the following parameters:

  • SSID (WiFi Name) & Password of the available network connection.
  • Ubidots TOKEN
  • MQTT client name a random 8 - 12 alphanumeric character ASCII String. 
  • Device Label of the device which contains the variable to want to GET.
  • Variable Label of the variable you want to GET
/****************************************
 * 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];
char topicSubscribe[100];

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

  sprintf(topicSubscribe, "/v1.6/devices/%s/%s/lv", DEVICE_LABEL, VARIABLE_LABEL_SUBSCRIBE);
 
  client.subscribe(topicSubscribe);
}

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

2. Verify & Upload the code into the board following the same steps provided in the PUBLISH step above.

3. To verify the connectivity of the device and the data which is being received, open the serial monitor by selecting the "magnifying glass" icon in the top right corner of the Arduino IDE to see the connectivity logs. 

NOTE: If no response is seen, try unplugging your ESP32 and then plugging it again. Make sure the baud rate of the Serial monitor is set to the same one specified in your code 115200.

4. In the serial monitor, you will be able to see the last value received in Ubidots of the variable specified in the firmware.  Also, you will be able to control any actuator connected to the pin 16. 

5. Summary  

With this simple tutorial you are able to PUBLISH & SUBSCRIBE data to/from Ubidots with the ease of the Arduino IDE and an ESP32.

Now its time to create Ubidots Dashboards to visualize your data and deploy your IoT solution!  Happy Hacking! :) 

Other readers have also found useful...

Did this answer your question?