Working on Sensors and Modules: NodeMCU Beginners’ Guide
This lesson will explore how to connect and read data from sensors, display this data on a web server, and combine multiple sensors for enhanced functionality. We’ll learn how to build a simple web server using the ESP8266-based NodeMCU to display real-time sensor data. We’ll integrate a DHT11 temperature and humidity sensor and an HC-SR04 ultrasonic distance sensor and create a simple user interface (UI) to visualize the data on a web page.

Components Required
To build this project, you will need:
- NodeMCU (ESP8266)
- DHT11 Temperature and Humidity Sensor
- HC-SR04 Ultrasonic Sensor
- Jumper Wires
- Breadboard
Circuit Diagram & Wiring
Follow this wiring setup to connect the sensors to the NodeMCU:

Code for the Web Server
Below is the complete code to set up the web server and display sensor readings on a simple UI.
/*
* Project: ESP8266 Web Server with DHT11 & HC-SR04
* Author: Manuja Yasanga
* Website: https://mechatronicslearning.com
*
* Description:
* This code sets up a simple web server using NodeMCU (ESP8266) to display real-time
* temperature and distance readings from a DHT11 sensor and an HC-SR04 ultrasonic sensor.
*
* License:
* This is open-source code provided by mechatronicslearning.com.
* You can use, modify, and distribute it for learning and project purposes.
*
* More NodeMCU tutorials available at: https://mechatronicslearning.com
*/
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <DHT.h>
// WiFi Credentials
const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASSWORD";
// Define DHT sensor
#define DHTPIN 2 // GPIO2 (D4)
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
// Define Ultrasonic sensor
#define TRIG 14 // GPIO14 (D5)
#define ECHO 12 // GPIO12 (D6)
// Create web server on port 80
ESP8266WebServer server(80);
// Read temperature
float readTemperature() {
float temp = dht.readTemperature();
return isnan(temp) ? -1 : temp;
}
// Read distance
float readDistance() {
digitalWrite(TRIG, LOW);
delayMicroseconds(2);
digitalWrite(TRIG, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG, LOW);
long duration = pulseIn(ECHO, HIGH);
return duration * 0.034 / 2;
}
// Handle web page
void handleRoot() {
float temp = readTemperature();
float distance = readDistance();
String html = R"rawliteral(
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="refresh" content="3">
<title>ESP8266 Sensor Data</title>
<style>
body {
font-family: Arial, sans-serif;
text-align: center;
background-color: #f4f4f4;
color: #333;
margin: 0;
padding: 20px;
}
.container {
max-width: 400px;
margin: auto;
background: white;
padding: 20px;
border-radius: 10px;
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);
}
h1 {
color: #007BFF;
}
.data {
font-size: 24px;
margin: 10px 0;
padding: 10px;
border-radius: 5px;
}
.temp {
background-color: #ffcccb;
}
.distance {
background-color: #ccffcc;
}
</style>
</head>
<body>
<div class="container">
<h1>ESP8266 Sensor Data</h1>
<p class="data temp">
Temperature: <b>)rawliteral" + String(temp) + R"rawliteral(°C</b></p>
<p class="data distance">
Distance: <b>)rawliteral" + String(distance) + R"rawliteral( cm</b></p>
</div>
</body>
</html>
)rawliteral";
server.send(200, "text/html", html);
}
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
pinMode(TRIG, OUTPUT);
pinMode(ECHO, INPUT);
dht.begin();
Serial.print("Connecting to WiFi...");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nConnected to WiFi: " + WiFi.localIP().toString());
server.on("/", handleRoot);
server.begin();
}
void loop() {
server.handleClient();
}
How the Code Works
Let’s break down the code step by step.
1. Including Libraries
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <DHT.h>
- ESP8266WiFi.h → Allows the NodeMCU to connect to a Wi-Fi network.
- ESP8266WebServer.h → Enables the creation of a web server.
- DHT.h → Handles communication with the DHT11 temperature and humidity sensor.
2. WiFi Credentials
const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASSWORD";
- These variables store your Wi-Fi SSID (network name) and password.
- Replace “YOUR_SSID” and “YOUR_PASSWORD” with your actual Wi-Fi details.
3. Defining Sensors and Pins
#define DHTPIN 2 // GPIO2 (D4)
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
#define TRIG 14 // GPIO14 (D5)
#define ECHO 12 // GPIO12 (D6)
- DHT11 Sensor:
- The data pin of the DHT11 sensor is connected to D4 (GPIO2).
- DHTTYPE DHT11 specifies that we are using the DHT11 sensor.
- DHT dht(DHTPIN, DHTTYPE); initializes the sensor.
- HC-SR04 Ultrasonic Sensor:
- TRIG is set to D5 (GPIO14) → Sends the ultrasonic pulse.
- ECHO is set to D6 (GPIO12) → Receives the echo to calculate distance.
4. Creating a Web Server
ESP8266WebServer server(80);
- This creates a web server on port 80, which is the standard HTTP port.
5. Function to Read Temperature
float readTemperature() {
float temp = dht.readTemperature();
return isnan(temp) ? -1 : temp;
}
- dht.readTemperature(); reads the temperature from the DHT11 sensor.
- If the reading fails (isnan(temp) == true), it returns -1 to indicate an error.
6. Function to Read Distance
float readDistance() {
digitalWrite(TRIG, LOW);
delayMicroseconds(2);
digitalWrite(TRIG, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG, LOW);
long duration = pulseIn(ECHO, HIGH);
return duration * 0.034 / 2;
}
- This function measures distance using the HC-SR04 ultrasonic sensor:
- Sends a 10-microsecond HIGH pulse to TRIG (trigger pin).
- pulseIn(ECHO, HIGH); measures the time it takes for the echo to return.
- duration * 0.034 / 2; converts time into distance (centimeters).
7. Handling Web Page Requests
void handleRoot() {
float temp = readTemperature();
float distance = readDistance();
- Reads temperature and distance when a request is received.
Generating HTML Page
String html = R"rawliteral(
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="refresh" content="3">
<title>ESP8266 Sensor Data</title>
- Basic HTML structure for the webpage.
- <meta http-equiv=”refresh” content=”3″> → The page refreshes every 3 seconds.
CSS Styling
<style>
body {
font-family: Arial, sans-serif;
text-align: center;
background-color: #f4f4f4;
color: #333;
}
.container {
max-width: 400px;
margin: auto;
background: white;
padding: 20px;
border-radius: 10px;
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);
}
h1 {
color: #007BFF;
}
.data {
font-size: 24px;
margin: 10px 0;
padding: 10px;
border-radius: 5px;
}
.temp {
background-color: #ffcccb;
}
.distance {
background-color: #ccffcc;
}
</style>
</head>
- CSS is used to style the webpage.
- .temp { background-color: #ffcccb; } → Red background for temperature.
- .distance { background-color: #ccffcc; } → Green background for distance.
Displaying the Sensor Data
<body>
<div class="container">
<h1>ESP8266 Sensor Data</h1>
<p class="data temp">
Temperature: <b>)rawliteral" + String(temp) + R"rawliteral(°C</b></p>
<p class="data distance">
Distance: <b>)rawliteral" + String(distance) + R"rawliteral( cm</b></p>
</div>
</body>
</html>
)rawliteral";
- This dynamically inserts the latest sensor values into the HTML.
- String(temp) → Converts temperature into a string and inserts it.
- String(distance) → Converts distance into a string and inserts it.
server.send(200, "text/html", html);
- Sends the HTML page as a response to the web browser.
8. Setting Up the NodeMCU (setup function)
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
- Serial.begin(115200); starts serial communication.
- WiFi.begin(ssid, password); connects the NodeMCU to Wi-Fi.
Connecting to Wi-Fi
Serial.print("Connecting to WiFi...");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nConnected to WiFi: " + WiFi.localIP().toString());
- Checks if the NodeMCU is connected to Wi-Fi.
- Prints dots (…..) until the connection is established.
- Displays the IP Address of the NodeMCU.
Starting the Web Server
server.on("/", handleRoot);
server.begin();
- server.on(“/”, handleRoot); → Calls
handleRoot()
when the root URL (/
) is accessed. - server.begin(); → Starts the web server.
9. Running the Web Server (loop function)
void loop() {
server.handleClient();
}
- server.handleClient(); continuously listens for incoming web requests.
Testing the Project
- Upload the code to your NodeMCU using the Arduino IDE.
- Open the Serial Monitor (baud rate 115200) and note the assigned IP address.
- Open a web browser and enter your_nodeMCU_IP_address.
- You should see real-time sensor readings on the web page!
Conclusion
In this project, we learned how to:
- Interface a DHT11 temperature sensor and an HC-SR04 ultrasonic sensor with NodeMCU.
- Build a web server using ESP8266WebServer.
- Create a simple web UI to display real-time sensor data.
This project can be further enhanced by adding humidity readings, more sensors, or even logging the data to a cloud service!