Introduction: IBM Watson With ESP32 As Endpoint

About: Do you like technology? Follow my channel on Youtube and my Blog. In them I put videos every week of microcontrollers, arduinos, networks, among other subjects.

I’m posting here today the first video of a series on how to mount an Endpoint device with ESP32, and then send it to a cloud service. In this specific episode, I'll show you how to send information from a DHT22 sensor using the MQTT protocol for IBM Watson.

We’ll first introduce the MQTT, which is a machine-to-machine protocol used in IoT (Internet of Things). We will also send data from the temperature and humidity sensor using this protocol, and then check the graph with this data on a web page.

Step 1: ESP32 Pinout

I placed here the Pinout of ESP32, which we use in our example. However, I want to make it clear that the project also works with ESP8266, and even with the same source code.

Step 2: NodeMCU Pinout

Step 3: MQTT

MQTT is a machine-to-machine protocol used in IoT. It was designed to be lightweight and fast. It uses a subscribe/publish system, where a device "subscribes" to a topic with the specific information of your interest, and then receives the information whenever a device publishes data concerning this topic.

Like a server program, MQTT needs software. This is called a Broker. In this specific case, we will use IBM's Bluemix IoT Service. This service is free for endpoint testing.

Next, we need to have a cell phone or tablet with the Application side, that is, as an MQTT client. We also have the Device side, which is the ESP side with a thermometer. This sends the temperature and humidity data to the Bluemix, which then sends this information to the Application Side.

Step 4: Assembly

Our circuit consists of a 4.7k Ohms resistor between the 3.3v and the data pin, plus a DHT22 connected to the GPIO4 of an ESP32 or NodeMCU. Thus, this is our Endpoint.

Step 5: Diagram

I show here the several ways to work with the MQTT Local Broker. I placed two diagram models. In the video, I talk about a situation using a Raspberry Pi to open a gate, for example.

In the image above, we have the first architecture that uses a local Broker with persistence, and a second architecture below that only communicates with the broker in the cloud.

As shown in the diagram, our sensor then sends the temperature and humidity data to IBM Watson. It’s important to emphasize that IBM Watson is not writing the data in this case, as it’s only being displayed in graphs. This is because we won’t address any database operations in today’s example, but only indicate access to the Quickstart page (https://quickstart.internetofthings.ibmcloud.com/), which will display the status of the Endpoint. The scheme is simple and uses WiFi to send data.

Step 6: Libraries

In the Arduino IDE, go to the Sketch menu -> Include Library -> Manage Libraries ...

On the screen that opens, enter in the search "DHT" and install the lib “DHT sensor library

Then, type "PubSubClient" and install the "PubSubClient" lib.

Step 7: Temperature and Humidity Reading Library

Step 8: MQTT Library

Step 9: MQTT.ino

We start the source code by checking which ESP is being used and importing the corresponding library and WiFi. We still include the MQTT Libs and the Temperature and Humidity Sensor.

//Verifica qual ESP está sendo utilizado
//e importa a lib e wifi correspondente #if defined(ESP8266) #include <ESP8266WiFi.h> #else #include <WiFi.h> #endif //Lib de MQTT #include <PubSubClient.h> //Lib do sensor de temperatura e umidade #include <DHT.h>

Next, we define the following: the interval between data submissions, the MQTT server that will be used, the print information on the chart, and the ID. We also pointed out how the string QUICK_START should be.

//Intervalo entre os envios
#define INTERVAL 1000 //Substitua pelo SSID da sua rede #define SSID "TesteESP" //Substitua pela senha da sua rede #define PASSWORD "87654321" //Server MQTT que iremos utlizar #define MQTT_SERVER "quickstart.messaging.internetofthings.ibmcloud.com" //Nome do tópico que devemos enviar os dados //para que eles apareçam nos gráficos #define TOPIC_NAME "iot-2/evt/status/fmt/json" //ID que usaremos para conectar //QUICK_START deve permanecer como está const String QUICK_START = "d:quickstart:arduino:";

In this step, we define a unique ID. In this example, we use the MAC Address of the device we are using. This will serve as identification on the QuickStart site. Here, we also connect the Quickstart ID with the ID of our device.

//No DEVICE_ID você deve mudar para um id único
//Aqui nesse exemplo utilizamos o MAC Address //do dispositivo que estamos utilizando //Servirá como identificação no site //https://quickstart.internetofthings.ibmcloud.com const String DEVICE_ID = "240ac40e3fd0"; //Concatemos o id do quickstart com o id do nosso //dispositivo const String CLIENT_ID = QUICK_START + DEVICE_ID;

We then configure the MQTT and WiFi, as well as the objects and variables involved with the values of temperature and humidity.

//Cliente WiFi que o MQTT irá utilizar para se conectar
WiFiClient wifiClient; //Cliente MQTT, passamos a url do server, a porta //e o cliente WiFi PubSubClient client(MQTT_SERVER, 1883, wifiClient); //Tempo em que o último envio foi feito long lastPublishTime = 0; //Objeto que realiza a leitura da temperatura e da umidade DHT dht(4, DHT22); //Variável para guardarmos o valor da temperatura float temperature = 0; //Variável para guardarmos o valor da umidade float humidity = 0;

MQTT.ino - setup

In the Setup, we will initialize the DHT, and connect in the WiFi network and MQTT server.

void setup() {
Serial.begin(115200); //Incializamos o dht dht.begin(); //Conectamos à rede WiFi setupWiFi(); //Conectamos ao server MQTT connectMQTTServer(); }

MQTT.ino - loop

In the Loop, we collect the sensor data to create the Json that will be published in the topic that IBM Watson expects to generate the graph.

void loop() {
//Tempos agora em milisegundos long now = millis(); //Se o tempo desde o último envio for maior que o intervalo de envio if (now - lastPublishTime > INTERVAL) { //Atualizamos o tempo em que ocorreu o último envio lastPublishTime = now; //Fazemos a leitura da temperatura e umidade readSensor(); Serial.print("Publish message: "); //Criamos o json que enviaremos para o server mqtt String msg = createJsonString(); Serial.println(msg); //Publicamos no tópico onde o servidor espera para receber //e gerar o gráfico client.publish(TOPIC_NAME, msg.c_str()); } }

MQTT.ino - setupWiFi

Here, we have the function responsible for connecting to the WiFi network.

//Função responsável por conectar à rede WiFi
void setupWiFi() { Serial.println(); Serial.print("Connecting to "); Serial.print(SSID); //Manda o esp se conectar à rede através //do ssid e senha WiFi.begin(SSID, PASSWORD); //Espera até que a conexão com a rede seja estabelecida while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } //Se chegou aqui é porque conectou Serial.println(""); Serial.println("WiFi connected"); }

MQTT.ino - connectMQTTServer

In this step, we use the function responsible for connecting to the MQTT server.

//Função responsável por conectar ao server MQTT
void connectMQTTServer() { Serial.println("Connecting to MQTT Server..."); //Se conecta ao id que definimos if (client.connect(CLIENT_ID.c_str())) { //Se a conexão foi bem sucedida Serial.println("connected"); } else { //Se ocorreu algum erro Serial.print("error = "); Serial.println(client.state()); } }

MQTT.ino - readSensor

The reading of the temperature and humidity data is defined in this function.

//Função responsável por realizar a leitura
//da temperatura e umidade void readSensor(){ float value; //Faz a leitura da temperatura value = dht.readTemperature(); //Se o valor lido é válido if(!isnan(value)){ //Armazena o novo valor da temperatura temperature = value; } //Faz a leitura da umidade value = dht.readHumidity(); //Se o valor for válido if(!isnan(value)){ //Armazena o novo valor da umidade humidity = value; } }

MQTT.ino - createJsonString

Here, we have the function responsible for creating a Json with the data read.

//Função responsável por criar
//um Json com os dados lidos String createJsonString() { String data = "{"; data+= "\"d\": {"; data+="\"temperature\":"; data+=String(temperature); data+=","; data+="\"humidity\":"; data+=String(humidity); data+="}"; data+="}"; return data; }

Step 10: Graphic

To view the sensor graph, go

to https://quickstart.internetofthings.ibmcloud.com

In the Device ID field, enter the DEVICE_ID that you defined in the code.

- It is important to change this Device ID to a unique ID, used only to avoid conflict with data sent by another person.

Finally, accept the terms and click Go.

In this project, we tested our Endpoint on the IBM Watson server. This ensures that our Arduino program is communicating properly with the platform, and that the data we send will be received smoothly by a cloud service if we create an account.

In an upcoming video in this series, I'll show you how to log in to IBM Watson, as well as write in the databank of this or another cloud service, such as Google, Amazon, among others.

Step 11: Files

Download the files:

PDF

INO