Connecting a DHT11 sensor to the cloud with an ESP8266-based board

Alex Stakhanov
Sep 6, 2019 · 5 min read
DHT11, NodeMCU (ESP8266) board
DHT11, NodeMCU (ESP8266) board


In the previous article, I connected my ESP8266-based NodeMCU board to a Cloud4RPi service. Now, it’s time for a real project!

Hardware requirements

Software and services

Goal: Measure temperature and humidity

I already had a DHT11 sensor, so I decided to use it for temperature and humidity measurements. Let’s choose an Arduino library to read sensor data.

Arduino registry contains several libraries, from which I selected the most popular one.

According to their GitHub repository, we are also required to add an Adafruit Unified Sensor package.

Step 1: Create and configure project

I already described how to create a PlatformIO project and install libraries in the first part. My project is called “MyNodeMCU”. The structure is shown below:

PIO project structure
PIO project structure

This project is a slightly modified Cloud4RPi example.

I decided to store the device token and Wi-Fi credentials in the configuration file instead of code.

The file looks as follows:

default_envs = nodemcuv2

platform = espressif8266
framework = arduino
board = nodemcuv2

Step 2: Install libraries

Libraries installation is quite simple. You can do it from the IDE’s graphical interface, or by adding required library names to the lib_deps section of the file:

; ...lib_deps =
Adafruit Unified Sensor
DHT sensor library
build_flags =

Added libraries will be automatically installed into a project’s subfolder.

The main.cpp header looks as follows:

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <Cloud4RPi.h>
#include "DHT.h"

Step 3: Connect a DHT11 sensor

Adafruit provides a DHTtester.ino example of a sensor connection.

This code initializes a sensor and defines a structure to store the measurement result (in case it was successful):

#define DHTPIN 2      // Digital pin connected to the DHT sensor
#define DHTTYPE DHT11 // DHT 11
// ...struct DHT_Result {
float h;
float t;
DHT_Result dhtResult;

The next function shows how to read sensor data and store it in the data structure described above.

void readSensors() {
float h = dht.readHumidity();
// Read temperature as Celsius (the default)
float t = dht.readTemperature();
// Check if any reads failed and exit early (to try again).
if (isnan(h) || isnan(t)) {
Serial.println(F("Failed to read from DHT sensor!"));
dhtResult.h = h;
dhtResult.t = t;

Step 4: Sending data to the cloud

Once we have that data, the next step is to send it to the Cloud4RPi service.

The Cloud4RPi for Arduino page describes the library API, which is a set of methods used to:

-create, read and update variables,
-send variable values into the cloud using the MQTT protocol.

The library supports three variable types: Bool, Numeric, and String.

The library workflow starts with creating an API instance using the Device Token from the website (refer to the article’s part 1 for details).

#if defined(CLOUD4RPI_TOKEN)
Cloud4RPi c4r("!!!_NO_DEVICE_TOKEN_!!!");

Then, declare variables for DHT11 readings:


Then, get data from the sensor, save them into variables and publish the data to Cloud4RPi:

c4r.setVariable("DHT11_Temp", dhtResult.t);
c4r.setVariable("DHT11_Hum", dhtResult.h);

Temperature and humidity does not change quickly, so sending more than one value per 5 minutes is not required.

Step 5: Diagnostics

Cloud4RPi supports diagnostic data along with variable values. I used uptime, Wi-Fi signal strength, and IP address as diagnostic data:

c4r.declareDiagVariable("RSSI"); // WiFi signal strength

Note: The millis function I use to obtain uptime resets to zero every ~50 days. Which is more than enough for my project.

The following code sets diagnostic variable values:

c4r.setDiagVariable("RSSI", (String)WiFi.RSSI() + " dBm");
c4r.setDiagVariable("IP_Address", WiFi.localIP().toString());
c4r.setDiagVariable("Uptime", uptimeHumanReadable(currentMillis));

The uptimeHumanReadable function converts milliseconds to a convenient form:

String uptimeHumanReadable(unsigned long milliseconds) {
static char uptimeStr[32];
unsigned long secs = milliseconds / 1000;
unsigned long mins = secs / 60;
unsigned int hours = mins / 60;
unsigned int days = hours / 24;
secs -= mins * 60;
mins -= hours * 60;
hours -= days * 24;
sprintf(uptimeStr,"%d days %2.2d:%2.2d:%2.2d", (byte)days, (byte)hours, (byte)mins, (byte)secs);
return String(uptimeStr);

The function outputs a string like this 5 days 10:23:14 instead of a strange big number.

Step 6: Start and debug the project

After compiling the created code and flashing it into NodeMCU, the device connects to a cloud service and starts sending data.

You can increase logging verbosity by setting the CLOUD4RPI_DEBUG preprocessor variable to 1 (add -D CLOUD4RPI_DEBUG=1 to build_flags section in file).

Next, open the site and notice the new device online. Open it to see all variable values received from the device: sensor and diagnostics.

Step 7: Dashboard configuration

At this step, the data connection to the cloud is operational. Now, let’s configure the visual representation of the data.

I used the Dashboard configuration UI to create the following dashboard:

The dashboard is shareable, so I instantly share it with my friend.


The full project’s code is available in the gist.

That’s all for now!

Questions and suggestions are welcome in the comments.

Bonus pics:


Cloud control panel for your IoT projects

Alex Stakhanov

Written by




Cloud control panel for your IoT projects

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade