Arduino DHT11 Temperature & Humidity Monitoring System
1. Project Overview
This project uses an Arduino UNO and DHT11 sensor to measure temperature and humidity and display the readings on a live web dashboard using Python Flask.
Technologies Used
- Arduino UNO
- DHT11 Temperature and Humidity Sensor
- Arduino IDE
- Python
- Flask
- PySerial
- HTML, CSS and JavaScript
System Architecture
DHT11 Sensor
|
v
Arduino UNO
|
v
USB Serial Communication
|
v
Python Flask Application
|
v
Web Dashboard
|
v
Live Temperature & Humidity
2. Hardware Requirements
| Component | Quantity |
|---|---|
| Arduino UNO | 1 |
| DHT11 Sensor | 1 |
| Jumper Wires | 3 |
| USB Cable | 1 |
| Computer/Laptop | 1 |
DHT11 Connections
| DHT11 Pin | Arduino UNO |
|---|---|
| VCC | 5V |
| DATA | Digital Pin 2 |
| GND | GND |
For a bare four-pin DHT11 sensor, check its pinout and use the required pull-up resistor. Three-pin modules often include this resistor.
3. Arduino IDE Setup
Step 1: Install Arduino IDE
Download Arduino IDE:
https://www.arduino.cc/en/software
Install and open Arduino IDE.
Step 2: Install DHT11 Library
- Open Arduino IDE.
- Navigate to Sketch → Include Library → Manage Libraries.
- Search for
DHT sensor library. - Install DHT sensor library by Adafruit.
- Install Adafruit Unified Sensor if requested.
Step 3: Arduino Code
Create a new Arduino sketch and upload the following code.
#include <DHT.h>
// Sensor configuration
#define DHTPIN 2
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
void setup() {
// Start serial communication
Serial.begin(9600);
// Initialize DHT11
dht.begin();
}
void loop() {
// Read sensor values
float temperature = dht.readTemperature();
float humidity = dht.readHumidity();
// Check sensor readings
if (isnan(temperature) || isnan(humidity)) {
Serial.println("ERROR");
}
else {
// Send data to Python
Serial.print(temperature);
Serial.print(",");
Serial.println(humidity);
}
delay(2000);
}
Expected Serial Output
28.00,65.00
29.00,64.00
30.00,63.00
The first value represents temperature in Celsius, and the second represents humidity in percentage.
4. Python Environment Setup
Step 1: Install Python
Download Python from:
https://www.python.org/downloads/
During installation, select Add Python to PATH.
Verify installation:
python --version
Step 2: Create Project Folder
Open PowerShell or Command Prompt.
mkdir DHT11_Website
cd DHT11_Website
Step 3: Create Python Virtual Environment
A virtual environment keeps project dependencies separate from other Python projects.
python -m venv venv
Step 4: Activate Virtual Environment
Windows PowerShell:
.\venv\Scripts\Activate.ps1
If PowerShell blocks activation, run:
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
Then activate again:
.\venv\Scripts\Activate.ps1
Windows Command Prompt:
venv\Scripts\activate.bat
After successful activation, you should see:
(venv) C:\...\DHT11_Website>
Step 5: Install Required Libraries
pip install flask pyserial
Verify installed packages:
pip list
Step 6: Save Dependencies
pip freeze > requirements.txt
5. Project Structure
The project will contain one Python application file.
DHT11_Website/
│
├── venv/
│
├── app.py
│
└── requirements.txt
The HTML, CSS and JavaScript code will be included inside app.py, so a separate HTML file is not required.
6. Create the Python Application
Create a file named app.py.
Copy the following complete code:
from flask import Flask, jsonify, render_template_string
import serial
import threading
import time
app = Flask(__name__)
# Arduino Configuration
SERIAL_PORT = "COM3"
BAUD_RATE = 9600
# Sensor Variables
temperature = 0
humidity = 0
connection_status = "Disconnected"
last_updated = "--"
# =====================================
# ARDUINO SERIAL COMMUNICATION
# =====================================
def read_arduino():
global temperature, humidity
global connection_status, last_updated
while True:
try:
print("Connecting to Arduino...")
arduino = serial.Serial(
SERIAL_PORT,
BAUD_RATE,
timeout=2
)
time.sleep(2)
connection_status = "Connected"
print("Arduino Connected!")
while True:
line = arduino.readline().decode(
"utf-8",
errors="ignore"
).strip()
if not line or line == "ERROR":
continue
try:
values = line.split(",")
if len(values) == 2:
temp = float(values[0])
hum = float(values[1])
temperature = temp
humidity = hum
last_updated = time.strftime("%H:%M:%S")
print(
f"Temperature: {temp} C | "
f"Humidity: {hum} %"
)
except ValueError:
continue
except Exception as error:
connection_status = "Disconnected"
print("Arduino Error:", error)
time.sleep(3)
# =====================================
# HTML DASHBOARD
# =====================================
HTML_PAGE = """
<!DOCTYPE html>
<html>
<head>
<title>DHT11 Monitoring System</title>
<meta name="viewport"
content="width=device-width, initial-scale=1">
<style>
* {
box-sizing: border-box;
}
body {
margin: 0;
font-family: Arial, sans-serif;
background: #eef2f7;
color: #172554;
}
header {
background: #172554;
color: white;
padding: 30px 15px;
text-align: center;
}
header h1 {
margin: 0 0 10px;
}
.container {
max-width: 900px;
margin: 50px auto;
padding: 15px;
}
.cards {
display: flex;
justify-content: center;
gap: 25px;
flex-wrap: wrap;
}
.card {
background: white;
width: 300px;
padding: 35px 20px;
border-radius: 18px;
text-align: center;
box-shadow: 0 5px 20px #0001;
}
.icon {
font-size: 45px;
}
.value {
font-size: 48px;
font-weight: bold;
margin: 20px 0;
}
.temperature {
color: #ef4444;
}
.humidity {
color: #2563eb;
}
.status-box {
background: white;
padding: 22px;
border-radius: 15px;
margin-top: 30px;
text-align: center;
}
.connected {
color: #16a34a;
}
.disconnected {
color: #dc2626;
}
footer {
text-align: center;
padding: 25px;
color: #64748b;
}
</style>
</head>
<body>
<header>
<h1>🌡️ DHT11 Monitoring System</h1>
<p>Live Temperature and Humidity Dashboard</p>
</header>
<div class="container">
<div class="cards">
<div class="card">
<div class="icon">🌡️</div>
<h2>Temperature</h2>
<div class="value temperature"
id="temperature">
-- °C
</div>
<p>Room Temperature</p>
</div>
<div class="card">
<div class="icon">💧</div>
<h2>Humidity</h2>
<div class="value humidity"
id="humidity">
-- %
</div>
<p>Air Humidity</p>
</div>
</div>
<div class="status-box">
<h3>
Arduino Status:
<span id="status" class="disconnected">
Checking...
</span>
</h3>
<p>
Last Updated:
<span id="updated">--</span>
</p>
</div>
</div>
<footer>
Arduino UNO + DHT11 | Python Flask IoT Dashboard
</footer>
<script>
async function updateData() {
try {
const response = await fetch("/data");
const data = await response.json();
document.getElementById("temperature").innerText =
data.temperature + " °C";
document.getElementById("humidity").innerText =
data.humidity + " %";
const status =
document.getElementById("status");
status.innerText = data.status;
status.className =
data.status === "Connected"
? "connected"
: "disconnected";
document.getElementById("updated").innerText =
data.updated;
}
catch (error) {
document.getElementById("status").innerText =
"Connection Error";
}
}
updateData();
// Update every two seconds
setInterval(updateData, 2000);
</script>
</body>
</html>
"""
# =====================================
# FLASK ROUTES
# =====================================
@app.route("/")
def home():
return render_template_string(HTML_PAGE)
@app.route("/data")
def get_data():
return jsonify({
"temperature": temperature,
"humidity": humidity,
"status": connection_status,
"updated": last_updated
})
# =====================================
# START APPLICATION
# =====================================
if __name__ == "__main__":
thread = threading.Thread(
target=read_arduino,
daemon=True
)
thread.start()
app.run(
host="127.0.0.1",
port=5000,
debug=False
)
7. Configure Arduino COM Port
Before running the application, identify the Arduino COM port.
- Open Arduino IDE.
- Connect Arduino UNO.
- Select Tools → Port.
- Note the COM port number.
For example:
SERIAL_PORT = "COM3"
If your Arduino uses COM5, change it to:
SERIAL_PORT = "COM5"
Important: Close Arduino IDE Serial Monitor before running the Python application because both applications cannot normally access the same serial port simultaneously.
8. Run the Application
Make sure your virtual environment is activated.
python app.py
Expected terminal output:
Connecting to Arduino...
Arduino Connected!
Temperature: 28.0 C | Humidity: 65.0 %
Temperature: 29.0 C | Humidity: 64.0 %
Running on http://127.0.0.1:5000
Open your web browser:
http://127.0.0.1:5000
Your live dashboard will display the temperature, humidity and Arduino connection status.
9. Troubleshooting
| Problem | Possible Solution |
|---|---|
| COM port error | Check the correct Arduino COM port |
| Access denied | Close Arduino Serial Monitor |
| Arduino disconnected | Check USB cable and connection |
| No sensor readings | Check DHT11 wiring and library installation |
| Website not opening | Check whether Flask is running on port 5000 |
| Python module not found | Activate virtual environment and install dependencies |
10. Useful Commands
| Task | Command |
|---|---|
| Create virtual environment | python -m venv venv |
| Activate environment | venv\Scripts\activate |
| Install Flask | pip install flask |
| Install PySerial | pip install pyserial |
| Save dependencies | pip freeze > requirements.txt |
| Run application | python app.py |
| Deactivate environment | deactivate |
11. Future Improvements
After completing the basic project, students can extend it with:
- Live temperature and humidity graphs.
- Historical sensor data storage using SQLite.
- Download sensor readings as CSV.
- Temperature threshold alerts.
- Multiple sensor monitoring.
- Professional IoT dashboard design.
- Remote access through a suitable network deployment.
Project Conclusion: This project demonstrates how Arduino hardware, sensor technology, serial communication and Python web development can be integrated to create a simple real-time IoT monitoring system.
Comments
Join the discussionNo comments yet. Be the first to comment.