Your Business
Your Business
  • Home
  • Arduino Projects
    • List of projects
    • Traffic lights
    • L298N Motor driver
    • Ir Car
    • LCD
    • Led remote control
    • Ultrasonic Detector
  • ESP 32 Projects
    • ESP32 & 1.28 display
    • Weather Station
  • More
    • Home
    • Arduino Projects
      • List of projects
      • Traffic lights
      • L298N Motor driver
      • Ir Car
      • LCD
      • Led remote control
      • Ultrasonic Detector
    • ESP 32 Projects
      • ESP32 & 1.28 display
      • Weather Station
  • Home
  • Arduino Projects
    • List of projects
    • Traffic lights
    • L298N Motor driver
    • Ir Car
    • LCD
    • Led remote control
    • Ultrasonic Detector
  • ESP 32 Projects
    • ESP32 & 1.28 display
    • Weather Station

Esp32 Weather Station

DIY ESP32 Weather Station | ESP32-C3 + DHT11 + 3D Printed Ca

Esp32 weather station

 

  • Build time: ~15 min wiring  |  ~3 min flashed sketch
  • Cost: under €15 (ESP32 + dht11 )  |  no level‑shifters required
  •  Parts used: ESP32-C3- https://amzn.to/3QXNZhADHT11 
  • Sensor- https://amzn.to/4tuK6ixJumper 
  • Wires 
  • USB Power
  •  3D Printed Case 

Wiring (ESP32 ⇄ dht11)

Power goes to 3.3 volts.
Ground to ground.
And the data pin connects to GPIO 2. 


The Code

  

#include <WiFi.h>
#include <WebServer.h>
#include <SimpleDHT.h>

// =====================
// ESP32-C3 WIFI ACCESS POINT
// =====================
const char* apSSID = "Alex3dWorks-Weather";
const char* apPassword = "esp32weather";

// =====================
// DHT11 SENSOR
// =====================
int pinDHT11 = 2;
SimpleDHT11 dht11(pinDHT11);

// =====================
// WEB SERVER
// =====================
WebServer server(80);

// =====================
// WEBPAGE
// =====================
const char MAIN_page[] PROGMEM = R"rawliteral(
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ESP32-C3 Weather Station</title>

<style>
  * {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: Arial, sans-serif;
  }

  body {
    min-height: 100vh;
    background: linear-gradient(135deg, #0f172a, #1e293b);
    color: white;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
  }

  .dashboard {
    width: 100%;
    max-width: 900px;
    background: rgba(255,255,255,0.08);
    border: 1px solid rgba(255,255,255,0.15);
    border-radius: 28px;
    padding: 28px;
    box-shadow: 0 20px 40px rgba(0,0,0,0.35);
  }

  .header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 16px;
    flex-wrap: wrap;
    margin-bottom: 28px;
  }

  .logo {
    display: flex;
    align-items: center;
    gap: 14px;
  }

  .icon {
    width: 56px;
    height: 56px;
    border-radius: 18px;
    background: linear-gradient(135deg, #38bdf8, #22c55e);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 26px;
  }

  h1 {
    font-size: 32px;
    line-height: 1.1;
  }

  .subtitle {
    color: #94a3b8;
    margin-top: 4px;
  }

  .live {
    background: rgba(34,197,94,0.15);
    border: 1px solid rgba(34,197,94,0.35);
    color: #bbf7d0;
    padding: 10px 16px;
    border-radius: 999px;
    font-weight: bold;
  }

  .cards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 18px;
  }

  .card {
    background: rgba(255,255,255,0.07);
    border: 1px solid rgba(255,255,255,0.12);
    border-radius: 24px;
    padding: 24px;
  }

  .label {
    color: #94a3b8;
    text-transform: uppercase;
    letter-spacing: 1px;
    font-size: 14px;
    margin-bottom: 14px;
  }

  .value {
    font-size: 54px;
    font-weight: bold;
    line-height: 1;
  }

  .unit {
    font-size: 22px;
    color: #94a3b8;
  }

  .desc {
    color: #cbd5e1;
    margin-top: 14px;
    font-size: 15px;
  }

  .bar {
    width: 100%;
    height: 14px;
    background: rgba(255,255,255,0.12);
    border-radius: 999px;
    overflow: hidden;
    margin-top: 18px;
  }

  .fill {
    height: 100%;
    width: 0%;
    background: linear-gradient(90deg, #38bdf8, #22c55e);
    transition: width 0.4s ease;
  }

  .footer {
    margin-top: 24px;
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
  }

  .tag {
    background: rgba(255,255,255,0.07);
    border: 1px solid rgba(255,255,255,0.12);
    padding: 10px 14px;
    border-radius: 999px;
    color: #cbd5e1;
    font-size: 14px;
  }

  @media(max-width: 600px) {
    h1 {
      font-size: 26px;
    }

    .value {
      font-size: 44px;
    }

    .dashboard {
      padding: 22px;
    }
  }
</style>
</head>

<body>
  <div class="dashboard">
    <div class="header">
      <div class="logo">
        <div class="icon">☁️</div>
        <div>
          <h1>ESP32-C3 Weather Station</h1>
          <div class="subtitle">Live temperature and humidity dashboard</div>
        </div>
      </div>
      <div class="live" id="status">LIVE</div>
    </div>

    <div class="cards">
      <div class="card">
        <div class="label">Temperature</div>
        <div class="value"><span id="temperature">--</span><span class="unit"> °C</span></div>
        <div class="desc" id="tempDesc">Waiting for data...</div>
      </div>

      <div class="card">
        <div class="label">Humidity</div>
        <div class="value"><span id="humidity">--</span><span class="unit"> %</span></div>
        <div class="bar"><div class="fill" id="humidityBar"></div></div>
        <div class="desc" id="humDesc">Waiting for data...</div>
      </div>

      <div class="card">
        <div class="label">Last Update</div>
        <div class="value" style="font-size:36px;"><span id="time">--:--:--</span></div>
        <div class="desc">Updates every 2 seconds</div>
      </div>
    </div>

    <div class="footer">
      <div class="tag">ESP32-C3 Access Point</div>
      <div class="tag">DHT11 Sensor</div>
      <div class="tag">Alex3dWorks Project</div>
    </div>
  </div>

<script>
function tempText(t) {
  if (t < 15) return "Cold environment";
  if (t < 23) return "Fresh and comfortable";
  if (t < 28) return "Comfortable temperature";
  return "Warm environment";
}

function humText(h) {
  if (h < 30) return "Air is dry";
  if (h < 60) return "Good humidity level";
  if (h < 75) return "Humid air";
  return "Very humid environment";
}

async function updateData() {
  try {
    const response = await fetch("/data");
    const data = await response.json();

    document.getElementById("temperature").innerText = data.temperature;
    document.getElementById("humidity").innerText = data.humidity;
    document.getElementById("humidityBar").style.width = data.humidity + "%";

    document.getElementById("tempDesc").innerText = tempText(data.temperature);
    document.getElementById("humDesc").innerText = humText(data.humidity);

    document.getElementById("time").innerText = new Date().toLocaleTimeString();
    document.getElementById("status").innerText = "LIVE";
  } catch (error) {
    document.getElementById("status").innerText = "OFFLINE";
  }
}

updateData();
setInterval(updateData, 2000);
</script>

</body>
</html>
)rawliteral";

// =====================
// ROUTES
// =====================
void handleRoot() {
server.send(200, "text/html", MAIN_page);
}

void handleData() {
  byte temperature = 0;
  byte humidity = 0;
int err = SimpleDHTErrSuccess;

  err = dht11.read(&temperature, &humidity, NULL);

if (err != SimpleDHTErrSuccess) {
server.send(500, "application/json", "{\"error\":\"DHT11 read failed\"}");
return;
}

  String json = "{";
  json += "\"temperature\":" + String((int)temperature) + ",";
  json += "\"humidity\":" + String((int)humidity);
  json += "}";

server.send(200, "application/json", json);
}

// =====================
// SETUP
// =====================
void setup() {
Serial.begin(115200);
delay(1000);

Serial.println();
Serial.println("Starting ESP32-C3 Weather Station...");

WiFi.softAP(apSSID, apPassword);

Serial.print("WiFi name: ");
Serial.println(apSSID);

Serial.print("WiFi password: ");
Serial.println(apPassword);

Serial.print("Open this address: ");
Serial.println(WiFi.softAPIP());

server.on("/", handleRoot);
server.on("/data", handleData);

server.begin();

Serial.println("Web server started.");
}

// =====================
// LOOP
// =====================
void loop() {
server.handleClient();
}

Using the badge

 

  1. Connect your phone to Alex3dWorks-Weather (password esp32weather).
  2. Browse to 192.168.4.1.



Copyright © 2025 Alex3dworks - All rights reserved

Powered by

  • Politica sulla privacy

This website uses cookies.

We use cookies to analyze website traffic and optimize your website experience. By accepting our use of cookies, your data will be aggregated with all other user data.

DeclineAccept