Code for Async Web Server
/*
---------------------------------------------------------
Heater Control using Async Web Server
11.02.2023
S. M. ASHIK AL MASHRAFI
https://www.youtube.com/channel/UC9rOCdDHt8ZGFh4IgE7V6fA
---------------------------------------------------------
*/
#include <WiFi.h>
#include <ESPAsyncWebServer.h>
#include <DHT.h>
// DEFINE CONSTANTS ---
#define DHTPIN 4
#define DHTTYPE DHT11
#define StatusPin 19
#define ControlPin 18
const char *ssid = "esp32";
const char *password = "123";
int status = LOW;
// DEFINE DHT ---
DHT dht(DHTPIN, DHTTYPE);
// HEATER STATUS FUNCTION ---
String readStatus(){
status = digitalRead(StatusPin);
if(status == HIGH) { return "Active"; }
else { return "Inactive"; }
}
// HEATER MODES FUNCTIONS ---
String heaterOn(){
digitalWrite(ControlPin, LOW);
return "Heating";
}
String heaterOff(){
digitalWrite(ControlPin, HIGH);
return "Neutral";
}
String heaterAuto(){
if(dht.readTemperature() < 25) { digitalWrite(ControlPin, LOW); }
else { digitalWrite(ControlPin, HIGH); }
return "Auto";
}
// ASYNCRONOUS WEB SERVER STRUCTURE
//----------------------------------------------------------------------
AsyncWebServer server(80);
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Heater Control</title>
<style type="text/css">
*{
font-family: Arial;
}
body{
padding: 1rem;
}
.header{
text-align: center;
margin-bottom: 40px;
color: #777;
}
.heaterStatContainer{
display: flex;
padding: 0 35px;
background: #fff;
box-shadow: 0 0 15px 2px #eee;
border-radius: 1rem;
font-size: 1.2rem;
}
.heaterContent{
width: 50%;
}
.heaterCaption{
color: #999;
margin-top: 30px;
margin-bottom: 0;
}
.heaterStat{
font-size: 1.5rem;
margin-top: 20px;
}
#status{
color: #999;
}
#mode{
color: #999;
}
.thContainer{
margin: 30px 0 35px 0;
display: flex;
justify-content: space-evenly;
}
.thContent{
width: 9.5rem;
height: 9.5rem;
text-align: center;
color: #fff;
border-radius: 100%;
}
.thStat{
font-size: 2rem;
font-weight: bold;
}
.t{
background-image: linear-gradient(to right, #FE656A , #FFBB73);
}
.h{
background-image: linear-gradient(to right, #6EEBF8 , #15C1F7);
}
.thContent > div {
position: relative;
top: 27%;
}
.captionUpper{
margin: 0;
padding: 0;
font-size: 1rem;
opacity: 60%;
}
.thStat{
margin: 5px 0px 3px 0;
}
.captionLower{
margin: 0;
padding: 0;
font-size: 1.5rem;
font-weight: bold;
opacity: 50%;
}
.heaterControl{
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-evenly;
width: 100%;
height: 200px;
}
.heaterControl > div{
align-content: center;
}
button{
width: 100px;
height: 50px;
font-size: 1.2rem;
color: #999;
display: inline-block;
background: #fff;
border: none;
border-radius: 1rem;
box-shadow: 0 0 15px 2px #eee;
cursor: pointer;
transition-duration: 0.4s;
}
button:active{
position: relative;
top: 2px;
}
button:focus{
color: #fff;
background: #FC3191;
box-shadow: 0 0 5px 2px #eee;
}
.cp{
color: #ccc;
text-align: center;
margin-top: 25px;
font-family: cursive;
}
</style>
</head>
<body>
<div class="header">
<h1>Heater Control</h1>
</div>
<div class="heaterStatContainer">
<div class="heaterContent" style="text-align: left;">
<div class="divider"></div>
<p class="heaterCaption" >Heater Status</p>
<p class="heaterStat" id="status">__</p>
</div>
<div class="heaterContent" style="text-align: right;">
<p class="heaterCaption">Heater Mode</p>
<p class="heaterStat" id="mode">N/A</p>
</div>
</div>
<div class="thContainer">
<div class="thContent t">
<div>
<p class="captionUpper">temperature</p>
<p class="thStat" id="temperature">__</p>
<p class="captionLower">°C</p>
</div>
</div>
<div class="thContent h">
<div>
<p class="captionUpper">humidity</p>
<p class="thStat" id="humidity">__</p>
<p class="captionLower">%</p>
</div>
</div>
</div>
<div class="heaterControl">
<div><button id="auto">Auto</button></div>
<div><button id="on">On</button></div>
<div><button id="off">Off</button></div>
</div>
<div class="cp">
© S. M. Ashik Al Mashrafi
</div>
</body>
<script>
// VARIABLES ---
var intervalAuto;
var heaterStat = document.getElementById("status");
var mode = document.getElementById("mode");
var temperature = document.getElementById("temperature");
var humidity = document.getElementById("humidity");
// READ TEMPERATURE
setInterval(function ( ) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
temperature.innerHTML = this.responseText;
}
};
xhttp.open("GET", "/temperature", true);
xhttp.send();
}, 500);
// READ HUMIDITY ---
setInterval(function ( ) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
humidity.innerHTML = this.responseText;
}
};
xhttp.open("GET", "/humidity", true);
xhttp.send();
}, 500);
// READ HEATER STATUS ---
setInterval(function ( ) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
heaterStat.innerHTML = this.responseText;
if (heaterStat.innerHTML == "Active") { heaterStat.style.color ="#32BAAA"; }
else {
heaterStat.style.color ="#999";
clearInterval(intervalAuto);
var xhttp = new XMLHttpRequest();
mode.innerHTML = "N/A";
mode.style.color ="#999";
xhttp.open("GET", "/heaterOff", true);
xhttp.send();
}
}
};
xhttp.open("GET", "/status", true);
xhttp.send();
}, 500);
// HEATER MODE ON ---
document.getElementById('on').addEventListener('click', heaterOn);
function heaterOn( ) {
clearInterval(intervalAuto);
if(heaterStat.innerHTML == "Active"){
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function(){
mode.innerHTML = this.responseText;
mode.style.color = "#FE656A";
}
xhttp.open("GET", "/heaterOn", true);
xhttp.send();
}
}
//HEATER MODE OFF ---
document.getElementById('off').addEventListener('click', heaterOff);
function heaterOff( ) {
clearInterval(intervalAuto);
if(heaterStat.innerHTML == "Active"){
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function(){
mode.innerHTML = this.responseText;
mode.style.color = "#999";
}
xhttp.open("GET", "/heaterOff", true);
xhttp.send();
}
}
//HEATER MODE AUTO ---
document.getElementById('auto').addEventListener('click', heaterAuto);
function heaterAuto( ) {
if(heaterStat.innerHTML == "Active"){
mode.innerHTML = "Auto";
mode.style.color = "#15C1F7";
intervalAuto = setInterval(function(){
var xhttp = new XMLHttpRequest();
xhttp.open("GET", "/heaterAuto", true);
xhttp.send();
}, 500);
}
}
</script>
</html>
)rawliteral";
void setup() {
Serial.begin(115200);
pinMode(StatusPin, INPUT);
pinMode(ControlPin, OUTPUT);
digitalWrite(ControlPin, HIGH);
// SET UP SAP MODE ---
WiFi.softAP(ssid);
IPAddress myIP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(myIP);
// SEND DATA TO LOCAL SERVER ---
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
request->send_P(200, "text/html", index_html);
});
server.on("/humidity", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/plain", String(dht.readHumidity()).c_str());
});
server.on("/temperature", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/plain", String(dht.readTemperature()).c_str());
});
server.on("/status", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/plain", readStatus().c_str());
});
server.on("/heaterOn", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/plain", heaterOn().c_str());
});
server.on("/heaterOff", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/plain", heaterOff().c_str());
});
server.on("/heaterAuto", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/plain", heaterAuto().c_str());
});
server.begin();
}
void loop() {
}
Code for Blynk
/*
---------------------------------------------------------
Heater Control using Blynk
11.02.2023
S. M. ASHIK AL MASHRAFI
https://www.youtube.com/channel/UC9rOCdDHt8ZGFh4IgE7V6fA
---------------------------------------------------------
*/
// CONNECT TO BLYNK ---
#define BLYNK_TEMPLATE_ID "TMPLWCNGs7Dk"
#define BLYNK_DEVICE_NAME "HEATER CONTROL"
#define BLYNK_AUTH_TOKEN "1vSKW_Y82FzmumPUzvRQ4F1t46eoLMv8"
#define BLYNK_PRINT Serial
// HEADER FILES ---
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
#include<DHT.h>
// DEFINE CONSTANTS ---
#define DHTTYPE DHT11
#define DHTPIN 4
#define StatusPin 19
#define ControlPin 18
// WiFi CREDENTIALS ---
char ssid[] = "METALFIST";
char pass[] = "Nobig777";
int timerAuto;
int timerDHT;
// DEFINE DHT ---
DHT dht(DHTPIN, DHTTYPE);
// DEFINE TIMER FOR BLYNK ---
BlynkTimer timer;
// READ AND SEND DHT SENSOR DATA TO BLYNK ---
void readDHT(){
float h = dht.readHumidity();
float t = dht.readTemperature();
Blynk.virtualWrite(V1, t);
Blynk.virtualWrite(V2, h);
}
// LOAD CONTROL ---
int mode;
BLYNK_WRITE(V4){
timerDHT = timer.setInterval(500L, readDHT);
int value = param.asInt();
if(value == 0){
timer.deleteTimer(timerAuto);
digitalWrite(ControlPin, HIGH);
Blynk.virtualWrite(V5, "Neutral");
}
else if(value == 1){
timer.deleteTimer(timerAuto);
digitalWrite(ControlPin, LOW);
Blynk.virtualWrite(V5, "Heating");
}
else{
timerAuto = timer.setInterval(500L, modeAuto);
}
}
void modeAuto(){
float t = dht.readTemperature();
if(t<25){ digitalWrite(ControlPin, LOW); }
else{ digitalWrite(ControlPin, HIGH); }
Blynk.virtualWrite(V5, "Auto");
}
void setup(){
Serial.begin(115200);
pinMode(ControlPin, OUTPUT);
pinMode(StatusPin, INPUT);
digitalWrite(ControlPin, HIGH);
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
dht.begin();
timerDHT = timer.setInterval(500L, readDHT); // UPDATING DATA WITH INTERVAL ---
}
void loop(){
// READ HEATER STATUS ---
int heaterState = digitalRead(StatusPin);
if(heaterState == 1) { Blynk.virtualWrite(V3, "Active"); }
else { Blynk.virtualWrite(V3, "Inactive"); }
Blynk.run();
timer.run();
}