# 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

```text
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

1. Open Arduino IDE.
2. Navigate to **Sketch → Include Library → Manage Libraries**.
3. Search for `DHT sensor library`.
4. Install **DHT sensor library by Adafruit**.
5. Install **Adafruit Unified Sensor** if requested.

### Step 3: Arduino Code

Create a new Arduino sketch and upload the following code.

```cpp
#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

```text
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:

```bash
python --version
```

### Step 2: Create Project Folder

Open PowerShell or Command Prompt.

```powershell
mkdir DHT11_Website
cd DHT11_Website
```

### Step 3: Create Python Virtual Environment

A virtual environment keeps project dependencies separate from other Python projects.

```bash
python -m venv venv
```

### Step 4: Activate Virtual Environment

**Windows PowerShell:**

```powershell
.\venv\Scripts\Activate.ps1
```

If PowerShell blocks activation, run:

```powershell
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
```

Then activate again:

```powershell
.\venv\Scripts\Activate.ps1
```

**Windows Command Prompt:**

```cmd
venv\Scripts\activate.bat
```

After successful activation, you should see:

```text
(venv) C:\...\DHT11_Website>
```

### Step 5: Install Required Libraries

```bash
pip install flask pyserial
```

Verify installed packages:

```bash
pip list
```

### Step 6: Save Dependencies

```bash
pip freeze > requirements.txt
```

---

## 5. Project Structure

The project will contain one Python application file.

```text
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:

```python
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.

1. Open Arduino IDE.
2. Connect Arduino UNO.
3. Select **Tools → Port**.
4. Note the COM port number.

For example:

```python
SERIAL_PORT = "COM3"
```

If your Arduino uses COM5, change it to:

```python
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.

```bash
python app.py
```

Expected terminal output:

```text
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:

```text
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:

1. Live temperature and humidity graphs.
2. Historical sensor data storage using SQLite.
3. Download sensor readings as CSV.
4. Temperature threshold alerts.
5. Multiple sensor monitoring.
6. Professional IoT dashboard design.
7. 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.

