Introduction: UbiDots-Connecting an ESP32 and Publishing Multiple Sensor Data

About: For Remote Supervision

ESP32 andESP 8266are very familiar SoC in the field of IoT. These are kind of kind of a boon for the IoT projects.ESP 32 is a device with integrated WiFi and BLE. Just give your SSID, password and IP configurations and integrate the things into the cloud. Here in this instructable, We will ponder through some of the basic terms of IoT like IoT platform, MQTT, Captive portals etc. So let us go through it

  • The IoT Architecture in very simple words consists of an embedded device and IoT platform to put the device in the cloud. Here we are using UbiDots IoT platform to visualize the sensor data.
  • Managing the IP settings and User credentials can be a headache to the user. What if the User wants to change the WiFi credentials? What if the user wants to switch the DHCP/Static IP settings? Flashing the ESP32 everytime is not reliable and not even the solution for these problems. So we will be going through the captive portal to save the WiFi credentials and others configurations.
  • MQTT is now becoming a very common term in the IoT world. it has overpassed request and responses(HTTP) by Publish and Subscribe because of the fast, robust and lean architecture.

Here in this instructable, we will be going to demonstrate.

Step 1: Hardware and Software Specification

Step 2: Creating a Captive Portal

A captive portal is a web page that is displayed to newly connected users before they are granted broader access to network resources. Here we are serving three web pages to select between DHCP and Static IP Settings. we can define the IP address to ESP in two ways.

  • DHCP IP address- it is a way to dynamically assign the IP address to the device. The ESP's default IP address is
  • The static IP address- assigning a permanent IP Adress to our network device. to provide the static IP to the device we need to define the IP address, gateway address, and subnet mask.

The first webpage is being hosted at Here the User is provided with the radio buttons to select between DHCP and Static IP settings. In the next webpage, we have to provide the IP related information to proceed further.


The HTML code for web pages can be found in this Github repository.
You can use any IDE or text editor like Sublime or notepad++ to make HTML web pages.

  • First Create an HTML webpage containing two radio buttons to choose between DHCP and Static IP Settings.
  • Now create the button to submit your response
  • Give some name to radio buttons.
  • The ESP Web server class will take these names as arguments and get the response of the radio buttons using these arguments
  • Now insert a ' SUBMIT ' button to send the response to the device.In the other web pages, we have text boxes.
  • Give the name value and Input type to the text box and add a submit button to ' SUBMIT ' submit the response.
  • Create a ' RESET ' button to reset the content of the text field.

Step 3: Providing WiFi and UbiDots Credentials

The main problem occurs while managing the WiFi credentials. Even though we have WiFiMulti library for that where we can give multiple SSIDs and passwords to the device and the device will connect to the network available. But, what if the network available is not in the WiFiMulti list. Flashing the ESP32 device all the time is not a reliable solution.

To resolve this problem, We are hosting a webpage where the user can submit the SSID and Password of the available network. It works as follows.

  • The webpage is hosted at the static IP or DHCP IP as chosen by the user from the captive portal
  • This Webpage contains text fields to enter SSID, password, and UBIDOTS token ID to connect the device to UbiDots.
  • Enter the SSID and password of your local WiFi in the input fields, Enter UbiDot's token Id and enter SUBMIT
  • These credentials are saved in ESP32's EEPROM
  • After 60-sec Device will automatically disconnect from AP

  • Next time when you turn on the device, The user doesn't have to follow this procedure, The device will automatically fetch the user credentials from EEPROM and continue with publishing the sensor readings to UbiDots.

Step 4: Publishing Sensor Readings to UbiDots

Here we are using Wireless Temperature and Humidity Sensors with the ESP 32 device to get the temperature and Humidity data. We are sending the data to UbiDots using the MQTT protocol. MQTT follows a publish and subscribe mechanism rather that request and response. It is faster and reliable than HTTP. This works as follows.

  • We are making use of Task Scheduler to Schedule the task like fetching data from sensors, Publishing the sensor readings, Subscribing to MQTT topic.
  • First, include the Task Scheduler header files, it's instance and schedules the tasks.
  • We have scheduled two tasks referring to two different control operations.

#include <TaskScheduler.h>

Scheduler ts;

Task tSensor(4 * TASK_SECOND, TASK_FOREVER, &taskSensorCallback, &ts, false, NULL, &taskSensorDisable); Task tWiFi(10* TASK_SECOND, TASK_FOREVER, &taskWiFiCallback, &ts, false, NULL, &taskWiFiDisable);

  • Task 1 is for reading the sensor value this task runs for 1 second till it reaches timeout of 10 secs.
  • When the Task1 reaches its time out We are connecting to local Wifi and MQTT broker.

  • Now Task 2 is enabled and we are disabling Task 1

  • Task 2 is for publishing the sensor data to UbiDots MQTT broker this task runs for 20 seconds till it reaches timeout of 20 secs

  • When the Task2 reaches its time out Task 1 is enabled again and Task2 is disabled. Here again, we are getting the updated value and the process goes on.

Reading the I2C Sensor Data

  • We are getting a 29-byte frame from the Wireless Temperature and Humidity Sensors. This frame is manipulated to get actual temperature and Humidity data.
uint8_t data[29];

data[0] =;
delay(k); //chck for start byte if(data[0]==0x7E) { while (!Serial1.available()); for ( i = 1; i< 29; i++) { data[i] =; delay(1); } if(data[15]==0x7F) /////// to check if the recive data is correct { if(data[22]==1) //////// make sure the sensor type is correct {

humidity = ((((data[24]) * 256) + data[25]) /100.0);
humidity /=10.0; cTempint = (((uint16_t)(data[26])<<8)| data[27]); cTemp = (float)cTempint /100.0; cTemp /= 10.0; fTemp = cTemp * 1.8 + 32; fTemp /= 10.0; battery = random(100,327); voltage = battery/100; nodeId = data[16];}

Connecting to UbiDots MQTT API

  • Include the header file for the MQTT process.
#include <PubSubClient.h>
  • define other variables for MQTT like client name, broker address, token ID(We are fetching the token ID from EEPROM)

#define MQTT_CLIENT_NAME "ClientVBShightime123"

char mqttBroker[] = "";

char payload[100];
char topic[150];

//create variable to store token ID

String tokenId;

  • Create variables to store different sensor data and create a char variable to store topic

#define VARIABLE_LABEL_TEMPF "tempF" // Assing the variable label
#define VARIABLE_LABEL_TEMPC "tempC" // Assing the variable label #define VARIABLE_LABEL_BAT "bat" #define VARIABLE_LABEL_HUMID "humid" // Assing the variable label

char topic1[100]; char topic2[100]; char topic3[100];

  • publish the data to the mentioned MQTT topic the payload will look like { "tempc" : {value: "tempData"}}

sprintf(topic1, "%s","");
sprintf(topic1, "%s%s", "/v1.6/devices/", DEVICE_LABEL); sprintf(payload, "%s", ""); // Cleans the payload sprintf(payload, "{\"%s\":", VARIABLE_LABEL_TEMPC); // Adds the value sprintf(payload, "%s{\"value\":%s}", payload, str_cTemp); // Adds the value sprintf(payload, "%s}", payload); // Closes the dictionary brackets Serial.println(payload); Serial.println(client.publish(topic1,payload) ? "published" : "notpublished");

//Do same for other topic as well
  • client.publish() publishes the data to UbiDots.

Step 5: Visualizing the Data

  • Go to Ubidots and Login to your account.
  • Navigate to the Dashboard from the Data tab listed on the top.
  • Now click the "+" icon to add the new widgets.
  • Select a widget from the list and add a variable and devices.
  • The sensor data can be visualized on the dashboard using different widgets.

Step 6: Overall Code