top of page

Web Server Based Weather Monitor using DHT 11 & Rain Sensor

In this project, we’ll learn how to make a featured weather station using an ESP8266, DHT11 and Rain sensors.


The rain sensor module is Vary easy tool for rain detection. It can be used as a switch when raindrop falls through the raining board and also for measuring rainfall intensity. The module features, a rain board and the control board that is separate for more convenience, power indicator LED and an adjustable sensitivity though a potentiometer.

Raindrop sensor is basically a board on which nickel is coated in the form of lines. It works on the principal of resistance. When there is no rain drop on board. Resistance is high so we gets high voltage according to V=IR. When rain drop present it reduces the resistance because water is conductor of electricity and presence of water connects nickel lines in parallel so reduced resistance and reduced voltage drop across it.

It consists of two parts one is a black board with nickel layers on it and other is an integrated chip provided with some output pins.Board has 2 output pin and chip has 6 pin.

The analog output is used in detection of drops in the amount of rainfall. Connected to 3,3V power supply, the LED will turn Off when induction board has no rain drop, and output is Low. When dropping a little amount water, output is High, the switch indicator will turn on. Brush off the water droplets, and when restored to the initial state, outputs high level.When no rain digital output is 1 and analog output gives 1023 max value. When rain is present digital output is 0 and analogue output is much less than 1023.

Hygrometer (DHT11)- A hygrometer measures relative humidity. Relative humidity is the quantity or percentage of water vapor (water in gas form) in the air. Humidity influences environmental factors and calculations like precipitation, fog, dew point and heat index. In addition, maintaining proper humidity indoors has implications for your health and home.



Circuit Diagram

Components Required

ESP8266 12E- 1 no

DHT11 - 1 no

Rain sensor - 1 no


Rain drop Sensor Module



Raindrop Sensor is a tool used for sensing rain. It consists of two modules, a rain board that detects the rain and a control module, which compares the analog value, and converts it to a digital value. The raindrop sensors can be used in the automobile sector to control the windshield wipers automatically, in the agriculture sector to sense rain and it is also used in home automation systems.





Pin Configuration of Rain Sensor:

Pin Name Function

1 VCC Connects supply voltage- 5V

2 GND Connected to ground

3 D0 Digital pin to get digital output

4 A0 Analog pin to get analog output

he control module of the raindrop sensor has 4 outputs. VCC is connected to a 5V supply. The GND pin of the module is connected to the ground. The D0 pin is connected to the digital pin of the microcontroller for digital output or the analog pin can be used. To use the analog output, the A0 pin can be connected to the ADC pin of a microcontroller. In the case of Arduino, it has 6 ADC pins, so we can use any of the 6 pins directly without using an ADC converter. The sensor module consists of a potentiometer, LN393 comparator, LEDs, capacitors and resistors. The pinout image above shows the components of the control module. The rainboard module consists of copper tracks, which act as a variable resistor. Its resistance varies with respect to the wetness on the rainboard. The below fig shows the rain board module.


The circuit diagram of a raindrop sensor module

The R1 resistor and the rain board module will act as a voltage divider. Capacitors C1 and C2 are used as a biasing element. The input for the Non-inverting terminal is taken from the connection point of the R1, and rain board module. Another point is taken from this connection and connected to the A0 terminal of the control module.

The input to the inverting terminal of the LM393 is taken from the potentiometer (R2). The R2 resistor acts as a voltage divider, and by varying R2 we can vary the input voltage to the inverting terminal, which in turn affects the sensitivity of the control module. The connections are shown in the above fig. The resistors R3 and R4 will act as current limiting resistors, while resistor R5 will act as a pull-up resistor to keep the bus in a high state when not in use.


Working of Rain Sensor:

Case1: When the input of the inverting terminal is higher than the input of the non-inverting terminal.

Case2: If the input of the inverting terminal is lower than the input of the non-inverting terminal.

The input to the inverting terminal is set to a certain value by varying the potentiometer and the sensitivity is set. When the rain board module’s surface is exposed to rainwater, the surface of the rainboard module will be wet, and it offers minimum resistance to the supply voltage. Due to this, the minimum voltage will be appearing at the non-inverting terminal of LM393 Op-Amp. The comparator compares both inverting and non-inverting terminal voltages. If the condition falls under case(1), the output of the Op-Amp will be digital LOW. If the condition falls under case(2), the output of the Op-Amp will be digital HIGH. The below diagram shows the equivalent circuit of both the conditions.


When the A0 pin is connected to the microcontroller, an additional analog to digital converter (ADC) circuit is used. In the case of Arduino, it consists of 6 ADC pins, which can be directly used for calculation purposes.

Applications of Rain sensor:

  • Automatic windshield wipers

  • Smart Agriculture

  • Home-Automation

Download datasheet

DHT11–Temperature and Humidity Sensor

The DHT11 is a commonly used Temperature and humidity sensor. The sensor comes with a dedicated NTC to measure temperature and an 8-bit microcontroller to output the values of temperature and humidity as serial data. The sensor is also factory calibrated and hence easy to interface with other microcontrollers.

The sensor can measure temperature from 0°C to 50°C and humidity from 20% to 90% with an accuracy of ±1°C and ±1%. So if you are looking to measure in this range then this sensor might be the right choice for you.


Download datasheet

NodeMCU Code for Weather Station

Program is divided in two parts. first part contains ESP8266 WiFi and Hardware related functions i.e. .ino file. Second part is HTML and user interface GUI. it is index.h file.


The index.h files copy here below.

const char MAIN_page[] PROGMEM = R"=====(

<!DOCTYPE html>

<html>

<head>

<title>Dofbot Widgets</title>

</head>

<style>

@import url(https://fonts.googleapis.com/css?family=Montserrat);

@import url(https://fonts.googleapis.com/css?family=Advent+Pro:400,200);

*{margin: 0;padding: 0;}


body{

background:#ffcc00;

font-family:Montserrat,Arial,sans-serif;

}

h2{

font-size:14px;

}

.widget{

box-shadow:0 40px 10px 5px rgba(0,0,0,0.4);

margin:100px auto;

height: 330px;

position: relative;

width: 500px;

}


.upper{

border-radius:5px 5px 0 0;

background:#f5f5f5;

height:200px;

padding:20px;

}


.date{

font-size:40px;

}

.year{

font-size:30px;

color:#c1c1c1;

}

.place{

color:#222;

font-size:40px;

}

.lower{

background:#292826;

border-radius:0 0 5px 5px;

font-family:'Advent Pro';

font-weight:200;

height:130px;

width:100%;

}

.clock{

background:#ffcc00;

border-radius:100%;

box-shadow:0 0 0 15px #292826,0 10px 10px 5px rgba(0,0,0,0.3);

height:150px;

position:absolute;

right:25px;

top:-35px;

width:150px;

}


.hour{

background:#292826;

height:50px;

left:50%;

position: absolute;

top:25px;

width:4px;

}


.min{

background:#292826;

height:65px;

left:50%;

position: absolute;

top:10px;

transform:rotate(100deg);

width:4px;

}


.min,.hour{

border-radius:5px;

transform-origin:bottom center;

transition:all .5s linear;

}


.infos{

list-style:none;

}

.info{

color:#fff;

float:left;

height:100%;

padding-top:10px;

text-align:center;

width:33%;

}

.info span{

display: inline-block;

font-size:40px;

margin-top:20px;

}

.weather p {

font-size:20px;padding:10px 0;

}

.anim{animation:fade .8s linear;}


@keyframes fade{

0%{opacity:0;}

100%{opacity:1;}

}


a{

text-align: center;

text-decoration: none;

color: white;

font-size: 15px;

font-weight: 500;

}

</style>

<body>



<div class="widget">

<div class="clock">

<div class="min" id="min"></div>

<div class="hour" id="hour"></div>

</div>

<div class="upper">

<div class="date" id="date">21 March</div>

<div class="year">Temperature</div>

<div class="place update" id="temperature">23 &deg;C</div>

</div>

<div style="text-align: center;"><a href="LIVE WEATHER STATION" style="align:center">LIVE WEATHER STATION</a></div>

<div class="lower">

<ul class="infos">

<li class="info temp">

<h1 class="title">TEMPERATURE</h1>

<span class='update' id="temp">21 &deg;C</span>

</li>

<li class="info humidity">

<h1 class="title">HUMIDITY</h1>

<span class='update' id="humidity">23%</span>

</li>

<li class="info wind">

<h1 class="title">RAIN</h1>

<span class='update' id="rain">0%</span>

</li>

</ul>

</div>

</div>


<script>

setInterval(drawClock, 2000);

function drawClock(){

var now = new Date();

var hour = now.getHours();

var minute = now.getMinutes();

var second = now.getSeconds();

//Date

var options = {year: 'numeric', month: 'long', day: 'numeric' };

var today = new Date();

document.getElementById("date").innerHTML = today.toLocaleDateString("en-US", options);

//hour

var hourAngle = (360*(hour/12))+((360/12)*(minute/60));

var minAngle = 360*(minute/60);

document.getElementById("hour").style.transform = "rotate("+(hourAngle)+"deg)";

//minute

document.getElementById("min").style.transform = "rotate("+(minAngle)+"deg)";


//Get Humidity Temperature and Rain Data

var xhttp = new XMLHttpRequest();

xhttp.onreadystatechange = function() {

if (this.readyState == 4 && this.status == 200) {

var txt = this.responseText;

var obj = JSON.parse(txt); //Ref: https://www.w3schools.com/js/js_json_parse.asp

document.getElementById("rain").innerHTML = obj.Rain + "%";

document.getElementById("temperature").innerHTML = Math.round(obj.Temperature) + "&deg;C";

document.getElementById("temp").innerHTML = Math.round(obj.Temperature) + "&deg;C";

document.getElementById("humidity").innerHTML = Math.round(obj.Humidity) + "%";

}

};

xhttp.open("GET", "readADC", true); //Handle readADC server on ESP8266

xhttp.send();

}

</script>

</body>

</html>

)=====";


Weather Station Software Working

Software consists of following parts.

  1. Connecting to WiFi

  2. Server Creation

  3. Getting Data from Sensors

  4. Sending GUI to user

  5. Updating Sensors values on web page

Weather Station Hardware

Hardware part is simple we are using only two sensors DHT11 and Rain Sensor. You can add more sensors like BMP180 barometric pressure sensor.

Rain sensor analog output is connected to Analog input of ESP8266 through a voltage divider. which drops the output of rain sensor to suit ESP8266 analog input maximum range.

DHT11 gives us humidity and temperature readings. It is digital sensor gives output in serial stream of data. For this sensor interfacing we are using DHTesp library which takes care of all communication with DHT11 sensor. DHT11 is connected to NodeMCU pin D5 which is GPIO14.


Connecting to WiFi

Connection to you wifi is made by ESP8266 using below code. First we define wifi ssid and password.


const char* ssid = "xxxxx";

const char* password = "xxxxx";

Then we try to connect with wifi using WiFi.begin(ssid, password) and wait until connection successful using while (WiFi.status() != WL_CONNECTED).

Once we connect to wifi successfully we print IP address assigned by you WiFi Router on Serial monitor using WiFi.localIP() function.

Next part is to create web server on ESP8266. for this we are including web server library #include <ESP8266WebServer.h>

Then we create server instance using below function. Web uses default port 80, so we defined it as port 80.

ESP8266WebServer server(80); //Server on port 80

After this in setup() we create client request handling functions, one for displaying GUI and another which sends the sensor data to user using AJAX and JSON. AJAX is part of web page.


server.on("/", handleRoot); //Which routine to handle at root location. This is display page

server.on("/readADC", handleADC); //This page is called by java Script AJAX

server.begin(); //Start server

Serial.println("HTTP server started");


When user enters ESP8266 IP it requests root page. That request is served by handleRoot() function. It sends web page (HTML) to user (web browser).


void handleRoot() {

String s = MAIN_page; //Read HTML contents

server.send(200, "text/html", s); //Send web page

}


Once the web page is loaded it contains javascript with AJAX code which sends data request to ESP8266 webserver at /readADC.

This readADC request is handled by handleADC() function. as shown below. Handled ADC sends data first to web client and after that it reads DHT11 sensor to prevent data lags. In this you can clearly see data variable holds the JSON of sensor values. Many escape characters are uses as we are using double quotes in JSON.


void handleADC() {

int rain = analogRead(A0);

//Create JSON data

String data = "{\"Rain\":\""+String(rain)+"\", \"Temperature\":\""+ String(temperature) +"\", \"Humidity\":\""+ String(humidity) +"\"}";

digitalWrite(LED,!digitalRead(LED)); //Toggle LED on data request ajax

server.send(200, "text/plane", data); //Send ADC value, temperature and humidity JSON to client ajax request


//Get Humidity temperatue data after request is complete

//Give enough time to handle client to avoid problems

delay(dht.getMinimumSamplingPeriod());


humidity = dht.getHumidity();

temperature = dht.getTemperature();


Installing the arduino Library

Download DHT sensor library for ESPx


After downloading the .zip files, add the libraries in Arduino IDE by clicking on


To install the library navigate to the Sketch > Include Library > Manage Libraries… Wait for Library Manager to download libraries index and update list of installed libraries.


Subscribe and download code.


Arduino Code:

#include <ESP8266WiFi.h>

#include <WiFiClient.h>

#include <ESP8266WebServer.h>

#include "index.h" //Our HTML webpage contents with javascripts

#include "DHTesp.h" //DHT11 Library for ESP

#define LED 2 //On board LED

#define DHTpin 14 //D5 of NodeMCU is GPIO14


DHTesp dht;


// Replace with your SSID and Password here

const char* ssid = "XXXXX";

const char* password = "XXXXXXXX";

ESP8266WebServer server(80); //Server on port 80

void handleRoot() {

String s = MAIN_page; //Read HTML contents

server.send(200, "text/html", s); //Send web page

}


float humidity, temperature;


void handleADC() {

int rain = analogRead(A0);

//Create JSON data

String data = "{\"Rain\":\""+String(rain)+"\", \"Temperature\":\""+ String(temperature) +"\", \"Humidity\":\""+ String(humidity) +"\"}";

digitalWrite(LED,!digitalRead(LED));

server.send(200, "text/plane", data);

delay(dht.getMinimumSamplingPeriod());


humidity = dht.getHumidity();

temperature = dht.getTemperature();


Serial.print("H:");

Serial.println(humidity);

Serial.print("T:");

Serial.println(temperature); //dht.toFahrenheit(temperature));

Serial.print("R:");

Serial.println(rain);

}


void setup()

{

Serial.begin(115200);

Serial.println();


dht.setup(DHTpin, DHTesp::DHT11); //for DHT11 Connect DHT sensor to GPIO 17



WiFi.begin(ssid, password); //Connect to your WiFi router

Serial.println("");

pinMode(LED,OUTPUT);

// Wait for connection

while (WiFi.status() != WL_CONNECTED) {

delay(500);

Serial.print(".");

}


Serial.println("");

Serial.print("Connected to ");

Serial.println(ssid);

Serial.print("IP address: ");

Serial.println(WiFi.localIP()); //IP address assigned to your ESP

server.on("/", handleRoot); //Which routine to handle at root location. This is display page

server.on("/readADC", handleADC); //This page is called by java Script AJAX

server.begin(); //Start server

Serial.println("HTTP server started");

}



void loop()

{

server.handleClient(); //Handle client requests

}



After uploading open serial monitor and get the ip address.

Open IP address in Web Browser. After opening it in web browser, you will see that on board blue LED will Blink. this led toggles when it receives http request from web browser.

bottom of page