Introduction: Publishing Wireless Pressure Sensor Data Using MQTT

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.

  • Giving WiFi and MQTT credentials using Captive Portal.
  • Publishing and Subscribing multiple Sensor data to UbiDots.
  • Reading the Sensor data from Wireless Pressure and Temperature Sensor
  • Hosting a web form from the ESP32 .
  • Reading and Writing from SPIFFS ESP32 .

Step 1: Hardware and Software Specification

Hardware Specification

  • ESP32 WiFi/BLE
  • Wireless Pressure and Temperature Sensor

Software Specification

  • Arduino IDE
  • XCTU
  • Labview Utility

Step 2: Wireless Pressure and Temperature Sensors

Features

  • Industrial Grade Sensor Long Range Wireless Pressure Temperature Sensor
  • Operating Range 0 to 14000 mbar -40° to +85°C (-40° to 185°F)
  • Configurable Internal Calculation Pressure Resolution 0.012 to 0.065 mbar
  • Configurable Internal Calculation Temperature Resolution 0.002 to 0.012 °C
  • Accuracy ±2.5 mbar, ±2 °C
  • Absolute Pressure, Relative Pressure and Relative Altitude Change outputs
  • 2 Mile Line-of-Sight Range with On-Board Antenna
  • Superior LOS Range of up to 28 Miles with High-Gain Antennas
  • Interface to Raspberry Pi, Microsoft® Azure®, Arduino and More
  • Wireless Mesh Networking using DigiMesh®

Configuring Wireless Pressure and Temperature Sensor Using Labview Utility and XCTU

The Sensor run in two modes

  • Configuration Mode: Configure the Pan ID, delay, No. of retries etc. More on this is beyond the scope of this instructable and will be explained in next instructable.
  • Run Mode: We are running the device in Run mode. And to analyze these value we are using the Labview Utility

This Labview UI shows the values in nice graphs. It shows the current as well as past values. You can go to this link to download the Labview UI. click on the Run icon from the landing page menu to go to run mode.

Step 3: Connecting to WiFi

We are using the captive portal to save the WiFi credentials and to hover through the IP settings. For the detailed introduction on the captive portal, you can go through the following instructable.

The captive portal gives us the option to choose between Static and DHCP settings. Just enter the credentials like Static IP, Subnet Mask, gateway and the Wireless Sensor Gateway will get configured on that IP.

A webpage is being hosted where a list showing available WiFi networks and there RSSI. Select the WiFi network and password and enter submit. The credentials will be saved in the EEPROM and the IP setting will be saved in the SPIFFS. More on this can be found in this instructable.

Step 4: Setting Up UbiDots on ESP32

Here we are using Wireless Pressure and Temperature 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.
<p>#define _TASK_TIMEOUT<br>#include 
Scheduler ts;
//---------Tasks------------//
Task tSensor(4 * TASK_SECOND, TASK_FOREVER, &taskSensorCallback, &ts, false, NULL, &taskSensorDisable);
Task tWiFi(10* TASK_SECOND, TASK_FOREVER, &taskWiFiCallback, &ts, false, NULL, &taskWiFiDisable);</p><br>
  • Task 1 is for reading the sensor value this task runs for 1 second till it reaches the 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 the actual temperature and Humidity data.
if (Serial1.available())  
{    data[0] = Serial1.read();    
delay(k);   
if(data[0]==0x7E)    {    
while (!Serial1.available());   
for ( i = 1; i< 36; i++)      {      
data[i] = Serial1.read();      
delay(1);      
}    
if(data[15]==0x7F)  /////// to check if the recive data is correct      
{  if(data[22]==0x06)  //////// make sure the sensor type is correct  
{  int cTemp = ((((data[24]) * 256) + data[25]));  
int16_t abs_pressure = ((((uint16_t)(data[26])<<8)| data[27])*0.001);  
int rlt_pressure = ((((data[28]) * 256) + data[29])*0.001);  
int16_t delta_alt = ((((uint16_t)(data[30])<<8)| data[31])*0.01);  
float battery = ((data[18] * 256) + data[19]);  
float voltage = 0.00322 * battery;  
Serial.print("Sensor Number  ");  
Serial.println(data[16]);  
Serial.print("Sensor Type  ");  
Serial.println(data[22]);  
Serial.print("Firmware Version  "); 
Serial.println(data[17]);  
Serial.print("Temperature in Celsius :");  
Serial.print(cTemp);  
Serial.println(" C");  
Serial.print("Absolute Pressure :");  
Serial.println(abs_pressure);  
Serial.print(" mbar");  
Serial.print("Relative Pressure :");  
Serial.println(rlt_pressure);  
Serial.print(" mbar");  
Serial.print("Delta Altitude :");  
Serial.println(delta_alt);  
Serial.print(" meter");  
Serial.print("ADC value:");  
Serial.println(battery);  
Serial.print("Battery Voltage:");  
Serial.print(voltage);  
Serial.println("\n");  
if (voltage < 1)         
{    Serial.println("Time to Replace The Battery");          
}          
}      
}else{      
for ( i = 0; i< 36; i++)    
{      Serial.print(data[i]);      
Serial.print(" , ");      
delay(1);    
}}    
} 
}



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, the token ID
#define TOKEN "BBFF-************************************" // Your Ubidots TOKEN<br>#define MQTT_CLIENT_NAME "****************************"</p><p>char mqttBroker[]  = "things.ubidots.com";
char payload[100];
char topic[150];
//create variable to store token ID
toke

Step 5: Publishing Sensor Readings to UbiDots

  • 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 6: 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 7: Overall Code

The Over code for HTML and ESP32 can be found in this GitHub repository.

Credits

  • ncd ESP32 breakout board.
  • ncd Wireless Pressure and Temperature Sensors
  • pubsubclient
  • UbiDots
  • Task Scheduler