آیا تا به حال آرزو کرده اید که ای کاش می توانستید از موبایل، تبلت یا رایانه شخصی خود برای نظارت بر دما و رطوبت خانه، سردخانه یا انبار شراب در هر زمانی استفاده کنید؟ سپس این پروژه اینترنت اشیا می تواند مکانی عالی برای شروع باشد!
این پروژه از ESP32 به عنوان دستگاه کنترل استفاده می کند که به یک شبکه WiFi موجود متصل می شود و یک وب سرور ایجاد می کند. هنگامی که دستگاهی به این وب سرور متصل می شود، ESP32 دما و رطوبت نسبی را از سنسور DHT11/DHT22 می خواند و با رابط کاربری زیبا به مرورگر وب دستگاه ارسال می کند. برانگیخته؟ بیا شروع کنیم!
چند مفهوم وجود دارد که باید قبل از ادامه این آموزش با آنها آشنا شوید. اگر هر یک از آموزش های زیر برای شما ناآشنا است، ابتدا آنها را مطالعه کنید:
ESP32 دارای سنسور دمای داخلی است، پس چرا از آن استفاده نکنید؟
ESP32 در واقع دارای یک سنسور دما با محدوده دمایی -40 تا 125 درجه سانتیگراد است. این سنسور دما ولتاژی متناسب با دما تولید می کند که سپس توسط مبدل داخلی آنالوگ به دیجیتال به شکل دیجیتال تبدیل می شود.
با توجه به برگه اطلاعات ESP32، مشکل این سنسور دما این است که به دلیل تغییرات فرآیند، افست از تراشه ای به تراشه دیگر متفاوت است. اندازه گیری دما نیز تحت تأثیر گرمای تولید شده توسط مدار Wi-Fi قرار می گیرد. در نتیجه، سنسور دمای داخلی فقط برای برنامه هایی مناسب است که تغییرات دما را به جای دمای مطلق تشخیص می دهند.
سیم کشی سنسور DHT11/DHT22 به ESP32
اتصال سنسور DHT11/DHT22 به ESP32 بسیار آسان است. با قرار دادن ESP32 روی تخته نان خود شروع کنید و مطمئن شوید که هر طرف تخته در سمت دیگری از تخته نان قرار دارد.
سنسور را روی تخته نان خود در کنار ESP32 قرار دهید. پایه VCC سنسور را به پایه 3.3 ولتی ESP32 وصل کنید و زمین را به زمین متصل کنید. پین Data سنسور را به پایه D4 ESP32 وصل کنید. در نهایت، یک مقاومت کششی 10KΩ بین VCC و خط داده اضافه کنید تا برای برقراری ارتباط مناسب بین سنسور و ESP32، آن را بالا نگه دارید.
تصویر زیر سیم کشی را نشان می دهد.
نصب کتابخانه سنسور DHT
برای شروع خواندن دادههای حسگر، باید کتابخانه حسگر DHT را نصب کنید . از مدیر کتابخانه آردوینو در دسترس است.
برای نصب کتابخانه، به Sketch > Include Library > Manage Libraries بروید… منتظر بمانید تا مدیر کتابخانه فهرست کتابخانه ها را دانلود کند و لیست کتابخانه های نصب شده را به روز کند.
جستجوی خود را با وارد کردن «سنسور DHT» فیلتر کنید . به دنبال کتابخانه حسگر DHT توسط Adafruit باشید . روی آن ورودی کلیک کنید و سپس Install را انتخاب کنید.
کتابخانه حسگر DHT از پشتیبانی سنسور Adafruit استفاده می کند . بنابراین، Adafruit Unified Sensor را در مدیریت کتابخانه جستجو کنید و آن را نیز نصب کنید.
ایجاد یک وب سرور ESP32 با استفاده از حالت WiFi Station (STA).
حالا بیایید سراغ چیزهای جالب برویم!
همانطور که از عنوان پیداست، ما یک وب سرور ESP32 را در حالت Station (STA) پیکربندی می کنیم تا صفحات وب را به هر مشتری متصل در شبکه موجود ارائه دهد.
قبل از شروع آپلود طرح، باید دو متغیر زیر را با اعتبار شبکه خود جایگزین کنید تا ESP32 بتواند به یک شبکه موجود متصل شود.
const char* ssid = "YourNetworkName"; // Enter SSID here
const char* password = "YourPassword"; //Enter Password here
وقتی کارتان تمام شد، طرح را امتحان کنید و سپس به تفصیل آن را بررسی خواهیم کرد.
#include <WiFi.h>
#include <WebServer.h>
#include "DHT.h"
// Uncomment one of the lines below for whatever DHT sensor type you're using!
//#define DHTTYPE DHT11 // DHT 11
//#define DHTTYPE DHT21 // DHT 21 (AM2301)
#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321
/*Put your SSID & Password*/
const char* ssid = "YourNetworkName"; // Enter SSID here
const char* password = "YourPassword"; //Enter Password here
WebServer server(80);
// DHT Sensor
uint8_t DHTPin = 4;
// Initialize DHT sensor.
DHT dht(DHTPin, DHTTYPE);
float Temperature;
float Humidity;
void setup() {
Serial.begin(115200);
delay(100);
pinMode(DHTPin, INPUT);
dht.begin();
Serial.println("Connecting to ");
Serial.println(ssid);
//connect to your local wi-fi network
WiFi.begin(ssid, password);
//check wi-fi is connected to wi-fi network
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected..!");
Serial.print("Got IP: "); Serial.println(WiFi.localIP());
server.on("/", handle_OnConnect);
server.onNotFound(handle_NotFound);
server.begin();
Serial.println("HTTP server started");
}
void loop() {
server.handleClient();
}
void handle_OnConnect() {
Temperature = dht.readTemperature(); // Gets the values of the temperature
Humidity = dht.readHumidity(); // Gets the values of the humidity
server.send(200, "text/html", SendHTML(Temperature,Humidity));
}
void handle_NotFound(){
server.send(404, "text/plain", "Not found");
}
String SendHTML(float Temperaturestat,float Humiditystat){
String ptr = "<!DOCTYPE html> <html>\n";
ptr +="<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
ptr +="<title>ESP32 Weather Report</title>\n";
ptr +="<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n";
ptr +="body{margin-top: 50px;} h1 {color: #444444;margin: 50px auto 30px;}\n";
ptr +="p {font-size: 24px;color: #444444;margin-bottom: 10px;}\n";
ptr +="</style>\n";
ptr +="</head>\n";
ptr +="<body>\n";
ptr +="<div id=\"webpage\">\n";
ptr +="<h1>ESP32 Weather Report</h1>\n";
ptr +="<p>Temperature: ";
ptr +=(int)Temperaturestat;
ptr +="°C</p>";
ptr +="<p>Humidity: ";
ptr +=(int)Humiditystat;
ptr +="%</p>";
ptr +="</div>\n";
ptr +="</body>\n";
ptr +="</html>\n";
return ptr;
}
دسترسی به وب سرور
پس از آپلود طرح، Serial Monitor را با 115200 baud باز کنید و دکمه RESET را در ESP32 فشار دهید. اگر همه چیز خوب باشد، آدرس IP پویا به دست آمده از روتر شما و همچنین پیام «سرور HTTP شروع شده» را نمایش می دهد.
بعد، یک مرورگر را راه اندازی کنید و به آدرس IP نمایش داده شده در مانیتور سریال بروید. ESP32 باید یک صفحه وب با دمای فعلی و رطوبت نسبی ارائه دهد.
توضیح دقیق کد
طرح با گنجاندن کتابخانه WiFi.h آغاز می شود. این کتابخانه شامل متدهای مخصوص ESP32 است که برای اتصال به شبکه از آنها استفاده می کنیم. پس از آن، ما کتابخانه WebServer.h را شامل میکنیم که حاوی روشهایی است که به ما در پیکربندی سرور و رسیدگی به درخواستهای HTTP ورودی بدون نگرانی در مورد جزئیات پیادهسازی سطح پایین کمک میکنند. در نهایت، ما کتابخانه DHT.h را شامل میشویم.
#include <WiFi.h>
#include <WebServer.h>
#include "DHT.h"
در مرحله بعد، نوع سنسور DHT مورد استفاده خود را مشخص می کنیم. خط مناسب زیر را لغو نظر کنید!
//#define DHTTYPE DHT11 // DHT 11
//#define DHTTYPE DHT21 // DHT 21 (AM2301)
#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321
از آنجایی که ما در حال پیکربندی وب سرور ESP32 در حالت Station (STA) هستیم، به شبکه WiFi موجود می پیوندد. بنابراین، ما باید SSID و رمز عبور را مشخص کنیم.
/*Put your SSID & Password*/
const char* ssid = "YourNetworkName"; // Enter SSID here
const char* password = "YourPassword"; //Enter Password here
به دنبال آن، یک شی از کتابخانه WebServer ایجاد می کنیم تا بتوانیم به توابع آن دسترسی داشته باشیم. سازنده این شیء، پورتی را که سرور به آن گوش می دهد، به عنوان پارامتر می پذیرد. از آنجایی که HTTP به طور پیش فرض از پورت 80 استفاده می کند، ما از این مقدار استفاده خواهیم کرد. این به ما امکان می دهد بدون تعیین پورت در URL به سرور متصل شویم.
// declare an object of WebServer library
WebServer server(80);
در مرحله بعد، شماره پین GPIO را در ESP32 که پین Data سنسور ما به آن متصل است، تعریف می کنیم و یک شی DHT ایجاد می کنیم. بنابراین، ما می توانیم به توابع خاص کتابخانه DHT دسترسی داشته باشیم.
// DHT Sensor
uint8_t DHTPin = 4;
// Initialize DHT sensor.
DHT dht(DHTPin, DHTTYPE);
دو متغیر شناور تنظیم شده است: دما و رطوبت.
float Temperature;
float Humidity;
تابع Inside Setup()
در تابع راه اندازی، ما وب سرور خود را پیکربندی می کنیم. ابتدا یک اتصال سریال برای اهداف اشکال زدایی ایجاد می کنیم و پین GPIO را طوری پیکربندی می کنیم که به عنوان یک ورودی رفتار کند. ما همچنین شی DHT را مقداردهی اولیه می کنیم.
Serial.begin(115200);
delay(100);
pinMode(DHTPin, INPUT);
dht.begin();
سپس از WiFi.begin()
تابع برای اتصال به شبکه وای فای استفاده می کنیم. تابع SSID (نام شبکه) و رمز عبور را به عنوان پارامتر می پذیرد.
Serial.println("Connecting to ");
Serial.println(ssid);
//connect to your local wi-fi network
WiFi.begin(ssid, password);
در حالی که ESP32 تلاش می کند به شبکه متصل شود، می توانیم از این WiFi.status()
تابع برای بررسی وضعیت اتصال استفاده کنیم.
//check wi-fi is connected to wi-fi network
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
پس از اتصال به شبکه، این WiFi.localIP()
تابع برای چاپ آدرس IP اختصاص داده شده به ESP32 استفاده می شود.
Serial.println("");
Serial.println("WiFi connected..!");
Serial.print("Got IP: "); Serial.println(WiFi.localIP());
برای رسیدگی به درخواستهای HTTP ورودی، باید مشخص کنیم که هنگام دسترسی به یک URL خاص، کدام کد باید اجرا شود. برای این کار از .on()
روش استفاده می کنیم. این روش دو پارامتر را می پذیرد: یک مسیر URL نسبی و نام تابعی که باید هنگام بازدید از آن URL اجرا شود.
کد زیر نشان می دهد که وقتی یک سرور درخواست HTTP را در مسیر ریشه (/) دریافت می کند، handle_OnConnect()
تابع را فراخوانی می کند. توجه به این نکته ضروری است که URL مشخص شده یک مسیر نسبی است.
server.on("/", handle_OnConnect);
ما مشخص نکردهایم که اگر سرویس گیرنده نشانی اینترنتی را درخواست کند که با آن مشخص نشده است، چه سرویسی باید ارائه کند server.on()
. باید خطای ۴۰۴ (صفحه یافت نشد) را به عنوان پاسخ بدهد. برای انجام این کار از server.onNotFound()
روش استفاده می کنیم.
server.onNotFound(handle_NotFound);
حال برای راه اندازی سرور، متد شی سرور را begin()
فراخوانی می کنیم.
server.begin();
Serial.println("HTTP server started");
تابع درون حلقه ()
درخواستهای واقعی HTTP ورودی در تابع حلقه بررسی میشوند. برای این کار از متد شی سرور استفاده می handleClient()
کنیم.
server.handleClient();
اکنون باید handle_OnConnect()
تابعی را بنویسیم که قبلاً به URL ریشه (/) وصل کرده بودیم server.on
. ما این عملکرد را با خواندن مقادیر دما و رطوبت از سنسور شروع می کنیم.
ما از روش ارسال برای پاسخ به درخواست HTTP استفاده می کنیم. اگرچه روش را می توان با تعدادی آرگومان مختلف فراخوانی کرد، اما ساده ترین شکل به کد پاسخ HTTP، نوع محتوا و محتوا نیاز دارد.
اولین پارامتری که به روش ارسال میدهیم، کد ۲۰۰ (یکی از کدهای وضعیت HTTP ) است که با پاسخ OK مطابقت دارد. سپس نوع محتوا را به عنوان “text/html” مشخص می کنیم و در نهایت SendHTML()
تابع سفارشی را پاس می کنیم که یک صفحه HTML پویا با خوانش دما و رطوبت ایجاد می کند.
void handle_OnConnect()
{
Temperature = dht.readTemperature(); // Gets the values of the temperature
Humidity = dht.readHumidity(); // Gets the values of the humidity
server.send(200, "text/html", SendHTML(Temperature,Humidity));
}
به طور مشابه، ما یک تابع برای مدیریت صفحه خطای ۴۰۴ می نویسیم.
void handle_NotFound(){
server.send(404, "text/plain", "Not found");
}
نمایش صفحه وب HTML
هر زمان که وب سرور ESP32 درخواستی از یک سرویس گیرنده وب دریافت می کند، این sendHTML()
تابع یک صفحه وب ایجاد می کند. این به سادگی کدهای HTML را در یک رشته طولانی ادغام می کند و به server.send()
تابعی که قبلاً در مورد آن صحبت کردیم برمی گردد. این تابع از خوانش دما و رطوبت به عنوان پارامتر برای تولید محتوای HTML به صورت پویا استفاده می کند.
اولین متنی که همیشه باید ارسال کنید، <!DOCTYPE>
اعلان است که نشان می دهد ما کد HTML را ارسال می کنیم.
String SendHTML(float Temperaturestat,float Humiditystat){
String ptr = "<!DOCTYPE html> <html>\n";
عنصر <meta>
viewport باعث می شود صفحه وب پاسخگو باشد و اطمینان حاصل کند که در همه دستگاه ها خوب به نظر می رسد. تگ عنوان عنوان صفحه را تعیین می کند.
ptr +="<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
ptr +="<title>ESP32 Weather Report</title>\n";
سبک دادن به صفحه وب
به دنبال آن، ما مقداری CSS برای استایل دادن به ظاهر کلی صفحه وب داریم. فونت Helvetica را انتخاب می کنیم و محتوایی را که قرار است به صورت یک بلوک درون خطی، تراز وسط نمایش داده شود، تعریف می کنیم.
ptr +="<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n";
کد زیر رنگ، فونت و حاشیه را در اطراف تگ های بدنه، H1 و p تنظیم می کند.
ptr +="body{margin-top: 50px;} h1 {color: #444444;margin: 50px auto 30px;}\n";
ptr +="p {font-size: 24px;color: #444444;margin-bottom: 10px;}\n";
ptr +="</style>\n";
ptr +="</head>\n";
ptr +="<body>\n";
تنظیم عنوان صفحه وب
بعد، عنوان صفحه وب تنظیم می شود. می توانید این متن را به هر چیزی که برای برنامه شما مناسب است تغییر دهید.
ptr +="<div id=\"webpage\">\n";
ptr +="<h1>ESP32 Weather Report</h1>\n";
نمایش دما و رطوبت در صفحه وب
ما از تگ پاراگراف برای نمایش مقادیر دما و رطوبت استفاده کردیم. توجه داشته باشید که این مقادیر با استفاده از نوع ریخته گری به اعداد صحیح تبدیل می شوند.
ptr +="<p>Temperature: ";
ptr +=(int)Temperaturestat;
ptr +="°C</p>";
ptr +="<p>Humidity: ";
ptr +=(int)Humiditystat;
ptr +="%</p>";
ptr +="</div>\n";
ptr +="</body>\n";
ptr +="</html>\n";
return ptr;
}
صفحه وب را برای حرفه ای تر به نظر رسیدن یک ظاهر طراحی کنید
برنامه نویسان تمایل دارند که زیبایی شناسی را نادیده بگیرند، اما با کمی تلاش، صفحه وب ما می تواند جذاب تر به نظر برسد. اسکرین شات زیر به شما ایده ای از کاری که قرار است انجام دهیم ارائه می دهد.
باورنکردنی نیست؟ بیایید اکنون کمی سبک به صفحه HTML قبلی خود اضافه کنیم. SendHTML()
برای شروع، تابع موجود در طرح بالا را با کد زیر جایگزین کنید. طرح جدید را امتحان کنید و سپس با جزئیات به آن خواهیم پرداخت.
String SendHTML(float TempCstat,float TempFstat,float Humiditystat){
String ptr = "<!DOCTYPE html> <html>\n";
ptr +="<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
ptr +="<link href=\"https://fonts.googleapis.com/css?family=Open+Sans:300,400,600\" rel=\"stylesheet\">\n";
ptr +="<title>ESP32 Weather Report</title>\n";
ptr +="<style>html { font-family: 'Open Sans', sans-serif; display: block; margin: 0px auto; text-align: center;color: #333333;}\n";
ptr +="body{margin-top: 50px;}\n";
ptr +="h1 {margin: 50px auto 30px;}\n";
ptr +=".side-by-side{display: inline-block;vertical-align: middle;position: relative;}\n";
ptr +=".humidity-icon{background-color: #3498db;width: 30px;height: 30px;border-radius: 50%;line-height: 36px;}\n";
ptr +=".humidity-text{font-weight: 600;padding-left: 15px;font-size: 19px;width: 160px;text-align: left;}\n";
ptr +=".humidity{font-weight: 300;font-size: 60px;color: #3498db;}\n";
ptr +=".temperature-icon{background-color: #f39c12;width: 30px;height: 30px;border-radius: 50%;line-height: 40px;}\n";
ptr +=".temperature-text{font-weight: 600;padding-left: 15px;font-size: 19px;width: 160px;text-align: left;}\n";
ptr +=".temperature{font-weight: 300;font-size: 60px;color: #f39c12;}\n";
ptr +=".superscript{font-size: 17px;font-weight: 600;position: absolute;right: -20px;top: 15px;}\n";
ptr +=".data{padding: 10px;}\n";
ptr +="</style>\n";
ptr +="</head>\n";
ptr +="<body>\n";
ptr +="<div id=\"webpage\">\n";
ptr +="<h1>ESP32 Weather Report</h1>\n";
ptr +="<div class=\"data\">\n";
ptr +="<div class=\"side-by-side temperature-icon\">\n";
ptr +="<svg version=\"1.1\" id=\"Layer_1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"\n";
ptr +="width=\"9.915px\" height=\"22px\" viewBox=\"0 0 9.915 22\" enable-background=\"new 0 0 9.915 22\" xml:space=\"preserve\">\n";
ptr +="<path fill=\"#FFFFFF\" d=\"M3.498,0.53c0.377-0.331,0.877-0.501,1.374-0.527C5.697-0.04,6.522,0.421,6.924,1.142\n";
ptr +="c0.237,0.399,0.315,0.871,0.311,1.33C7.229,5.856,7.245,9.24,7.227,12.625c1.019,0.539,1.855,1.424,2.301,2.491\n";
ptr +="c0.491,1.163,0.518,2.514,0.062,3.693c-0.414,1.102-1.24,2.038-2.276,2.594c-1.056,0.583-2.331,0.743-3.501,0.463\n";
ptr +="c-1.417-0.323-2.659-1.314-3.3-2.617C0.014,18.26-0.115,17.104,0.1,16.022c0.296-1.443,1.274-2.717,2.58-3.394\n";
ptr +="c0.013-3.44,0-6.881,0.007-10.322C2.674,1.634,2.974,0.955,3.498,0.53z\"/>\n";
ptr +="</svg>\n";
ptr +="</div>\n";
ptr +="<div class=\"side-by-side temperature-text\">Temperature</div>\n";
ptr +="<div class=\"side-by-side temperature\">";
ptr +=(int)TempCstat;
ptr +="<span class=\"superscript\">°C</span></div>\n";
ptr +="</div>\n";
ptr +="<div class=\"data\">\n";
ptr +="<div class=\"side-by-side humidity-icon\">\n";
ptr +="<svg version=\"1.1\" id=\"Layer_2\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"\n\"; width=\"12px\" height=\"17.955px\" viewBox=\"0 0 13 17.955\" enable-background=\"new 0 0 13 17.955\" xml:space=\"preserve\">\n";
ptr +="<path fill=\"#FFFFFF\" d=\"M1.819,6.217C3.139,4.064,6.5,0,6.5,0s3.363,4.064,4.681,6.217c1.793,2.926,2.133,5.05,1.571,7.057\n";
ptr +="c-0.438,1.574-2.264,4.681-6.252,4.681c-3.988,0-5.813-3.107-6.252-4.681C-0.313,11.267,0.026,9.143,1.819,6.217\"></path>\n";
ptr +="</svg>\n";
ptr +="</div>\n";
ptr +="<div class=\"side-by-side humidity-text\">Humidity</div>\n";
ptr +="<div class=\"side-by-side humidity\">";
ptr +=(int)Humiditystat;
ptr +="<span class=\"superscript\">%</span></div>\n";
ptr +="</div>\n";
ptr +="</div>\n";
ptr +="</body>\n";
ptr +="</html>\n";
return ptr;
}
توضیح کد
ما قبلاً می دانیم که <!DOCTYPE>
اعلان به مرورگر اطلاع می دهد که ما در حال ارسال کد HTML هستیم و <meta>
عنصر viewport صفحه وب را پاسخگو می کند. تنها تفاوت اینجا این است که ما از فونت های گوگل استفاده خواهیم کرد. گوگل صدها فونت وب رایگان را برای استفاده تجاری و شخصی ارائه می دهد.
برای وبسایت خود، از فونت وب Open Sans به سفارش Google استفاده میکنیم . فونت گوگل با استفاده از <link>
تگ در سر سند HTML شما تعبیه شده است.
برای صفحه خود، وزن فونت های ۳۰۰ (سبک)، ۴۰۰ (عادی) و ۶۰۰ (پررنگ) را انتخاب کرده ایم. شما می توانید هر تعداد که می خواهید انتخاب کنید، اما به خاطر داشته باشید که وزن بیش از حد فونت زمان بارگذاری صفحه را کاهش می دهد.
همچنین میتوانید به سادگی با اضافه کردن یک کاراکتر i به انتهای وزن فونت، استایل ایتالیک اضافه کنید، به عنوان مثال، 400i فونت معمولی-ایتالیک-سبک را جاسازی میکند.
مهم است که توجه داشته باشید که فونت های گوگل به صورت پویا بارگذاری می شوند. شما نمی توانید فونت Google را ببینید مگر اینکه در دستگاهی که از آن به این صفحه دسترسی دارید اتصال اینترنتی فعال داشته باشید.
String SendHTML(float TempCstat,float TempFstat,float Humiditystat){
String ptr = "<!DOCTYPE html> <html>\n";
ptr +="<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
ptr +="<link href=\"https://fonts.googleapis.com/css?family=Open+Sans:300,400,600\" rel=\"stylesheet\">\n";
سپس فونت Open Sans را در کل سند HTML اعمال می کنیم. همچنین باید sans-serif را به عنوان فونت بازگشتی خود مشخص کنیم. اگر اولین فونت مشخص شده بارگیری نشود، مرورگر سعی می کند فونت بازگشتی را بارگیری کند.
ptr +="<title>ESP32 Weather Report</title>\n";
ptr +="<style>html { font-family: 'Open Sans', sans-serif; display: block; margin: 0px auto; text-align: center;color: #333333;}\n";
ptr +="body{margin-top: 50px;}\n";
ptr +="h1 {margin: 50px auto 30px;}\n";
در مرحله بعد، ما CSS را برای رطوبت و دما – نمادها، عناوین و مقادیر اعمال می کنیم. هر سه این عناصر به صورت خطی و به صورت عمودی تراز هستند. پس زمینه آیکون با استفاده از شعاع حاشیه 50 درصد و ارتفاع و عرض 30 پیکسل دایره ای ساخته شده است.
ptr +=".side-by-side{display: inline-block;vertical-align: middle;position: relative;}\n";
ptr +=".humidity-icon{background-color: #3498db;width: 30px;height: 30px;border-radius: 50%;line-height: 36px;}\n";
ptr +=".humidity-text{font-weight: 600;padding-left: 15px;font-size: 19px;width: 160px;text-align: left;}\n";
ptr +=".humidity{font-weight: 300;font-size: 60px;color: #3498db;}\n";
ptr +=".temperature-icon{background-color: #f39c12;width: 30px;height: 30px;border-radius: 50%;line-height: 40px;}\n";
ptr +=".temperature-text{font-weight: 600;padding-left: 15px;font-size: 19px;width: 160px;text-align: left;}\n";
ptr +=".temperature{font-weight: 300;font-size: 60px;color: #f39c12;}\n";
ptr +=".superscript{font-size: 17px;font-weight: 600;position: absolute;right: -20px;top: 15px;}\n";
ptr +=".data{padding: 10px;}\n";
ptr +="</style>\n";
ptr +="</head>\n";
ptr +="<body>\n";
پس از آن، ما قرائت دما را با این نمایش می دهیمنماد کوچک زیبا
نماد دما یک تصویر گرافیک برداری مقیاس پذیر (SVG) است که در <svg>
تگ تعریف شده است. ایجاد یک SVG به مهارت های برنامه نویسی خاصی نیاز ندارد. می توانید با استفاده از ویرایشگر SVG Google برای صفحه خود گرافیک ایجاد کنید . به دنبال نماد، ما قرائت دمای واقعی را از سنسور نمایش می دهیم.
ptr +="<div id=\"webpage\">\n";
ptr +="<h1>ESP32 Weather Report</h1>\n";
ptr +="<div class=\"data\">\n";
ptr +="<div class=\"side-by-side temperature-icon\">\n";
ptr +="<svg version=\"1.1\" id=\"Layer_1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"\n";
ptr +="width=\"9.915px\" height=\"22px\" viewBox=\"0 0 9.915 22\" enable-background=\"new 0 0 9.915 22\" xml:space=\"preserve\">\n";
ptr +="<path fill=\"#FFFFFF\" d=\"M3.498,0.53c0.377-0.331,0.877-0.501,1.374-0.527C5.697-0.04,6.522,0.421,6.924,1.142\n";
ptr +="c0.237,0.399,0.315,0.871,0.311,1.33C7.229,5.856,7.245,9.24,7.227,12.625c1.019,0.539,1.855,1.424,2.301,2.491\n";
ptr +="c0.491,1.163,0.518,2.514,0.062,3.693c-0.414,1.102-1.24,2.038-2.276,2.594c-1.056,0.583-2.331,0.743-3.501,0.463\n";
ptr +="c-1.417-0.323-2.659-1.314-3.3-2.617C0.014,18.26-0.115,17.104,0.1,16.022c0.296-1.443,1.274-2.717,2.58-3.394\n";
ptr +="c0.013-3.44,0-6.881,0.007-10.322C2.674,1.634,2.974,0.955,3.498,0.53z\"/>\n";
ptr +="</svg>\n";
ptr +="</div>\n";
ptr +="<div class=\"side-by-side temperature-text\">Temperature</div>\n";
ptr +="<div class=\"side-by-side temperature\">";
ptr +=(int)TempCstat;
ptr +="<span class=\"superscript\">°C</span></div>\n";
ptr +="</div>\n";
با ایننماد، ما قرائت رطوبت را نمایش می دهیم.
این یک SVG دیگر است. پس از چاپ مقادیر رطوبت، تمام تگ های باز مانند body
و را می بندیم html
.
ptr +="<div class=\"data\">\n";
ptr +="<div class=\"side-by-side humidity-icon\">\n";
ptr +="<svg version=\"1.1\" id=\"Layer_2\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"\n\"; width=\"12px\" height=\"17.955px\" viewBox=\"0 0 13 17.955\" enable-background=\"new 0 0 13 17.955\" xml:space=\"preserve\">\n";
ptr +="<path fill=\"#FFFFFF\" d=\"M1.819,6.217C3.139,4.064,6.5,0,6.5,0s3.363,4.064,4.681,6.217c1.793,2.926,2.133,5.05,1.571,7.057\n";
ptr +="c-0.438,1.574-2.264,4.681-6.252,4.681c-3.988,0-5.813-3.107-6.252-4.681C-0.313,11.267,0.026,9.143,1.819,6.217\"></path>\n";
ptr +="</svg>\n";
ptr +="</div>\n";
ptr +="<div class=\"side-by-side humidity-text\">Humidity</div>\n";
ptr +="<div class=\"side-by-side humidity\">";
ptr +=(int)Humiditystat;
ptr +="<span class=\"superscript\">%</span></div>\n";
ptr +="</div>\n";
ptr +="</div>\n";
ptr +="</body>\n";
ptr +="</html>\n";
return ptr;
}
بهبود ۱ – به روز رسانی خودکار صفحه
یکی از پیشرفت هایی که می توانید انجام دهید این است که صفحه را به طور خودکار به روز کنید تا مقدار سنسور را به روز کنید.
میتوانید با قرار دادن یک متا تگ در سند HTML خود، به مرورگر دستور دهید که صفحه را در یک بازه زمانی مشخص مجدداً بارگیری کند.
<meta http-equiv="refresh" content="2" >
<head>
این کد را در تگ سند خود وارد کنید . این متا تگ به مرورگر دستور می دهد که هر دو ثانیه یکبار به روز شود.
بهبود 2 – بارگذاری دینامیک داده های سنسور با AJAX
اگر صفحه وب بزرگ باشد، تازه کردن یک صفحه وب غیر عملی است. جاوا اسکریپت ناهمزمان و Xml (AJAX) روش بهتری است زیرا به ما امکان میدهد بدون رفرش کردن صفحه، دادهها را به صورت ناهمزمان (در پسزمینه) از سرور درخواست کنیم.
شی XMLHttpRequest در جاوا اسکریپت معمولاً برای اجرای AJAX در صفحات وب استفاده می شود. یک درخواست GET بی صدا به سرور ارسال می کند و عنصر صفحه را به روز می کند. AJAX یک فناوری جدید نیست و نه یک زبان برنامه نویسی متفاوت. بلکه صرفاً یک فناوری موجود است که به روشی متفاوت استفاده می شود. به شما اجازه می دهد:
- پس از بارگیری صفحه، داده ها را از سرور درخواست کنید
- پس از بارگیری صفحه، داده ها را از سرور دریافت کنید
- داده ها را به سروری در پس زمینه ارسال کنید
این اسکریپت AJAX است که ما از آن استفاده خواهیم کرد. این اسکریپت را قبل از بستن <head>
تگ قرار دهید.
ptr +="<script>\n";
ptr +="setInterval(loadDoc,200);\n";
ptr +="function loadDoc() {\n";
ptr +="var xhttp = new XMLHttpRequest();\n";
ptr +="xhttp.onreadystatechange = function() {\n";
ptr +="if (this.readyState == 4 && this.status == 200) {\n";
ptr +="document.getElementById(\"webpage\").innerHTML =this.responseText}\n";
ptr +="};\n";
ptr +="xhttp.open(\"GET\", \"/\", true);\n";
ptr +="xhttp.send();\n";
ptr +="}\n";
ptr +="</script>\n";
توضیح کد
از آنجایی که اسکریپت AJAX فقط جاوا اسکریپت است، باید در <script>
تگ محصور شود. ما از setInterval()
تابع جاوا اسکریپت برای فراخوانی مکرر این تابع استفاده خواهیم کرد. به دو پارامتر نیاز دارد: تابعی که باید اجرا شود و فاصله زمانی (بر حسب میلی ثانیه).
ptr +="<script>\n";
ptr +="setInterval(loadDoc,200);\n";
یک loadDoc()
تابع مهمترین بخش این اسکریپت است. در این تابع یک شی از XMLHttpRequest()
ایجاد می شود. این شیء برای پرس و جو از سرور وب برای داده استفاده می شود.
ptr +="function loadDoc() {\n";
ptr +="var xhttp = new XMLHttpRequest();\n";
هر زمان xhttp.onreadystatechange()
که تغییر کند متد فراخوانی می شود readyState
. ویژگی readyState
نشان دهنده وضعیت XMLHttpRequest است. یکی از مقادیر ذکر شده در زیر را دارد.
- ۰: درخواست اولیه نشده است
- ۱: اتصال سرور برقرار شد
- ۲: درخواست دریافت شد
- ۳: پردازش درخواست
- ۴: درخواست به پایان رسید و پاسخ آماده است
این status
ویژگی وضعیت شی XMLHttpRequest را نگه می دارد. یکی از مقادیر ذکر شده در زیر را دارد.
- ۲۰۰: “خوب”
- ۴۰۳: «ممنوع»
- ۴۰۴: “صفحه یافت نشد”
وقتی readyState
۴ status
باشد و 200 باشد، پاسخ کامل میشود و محتوای عنصر با شناسه «صفحه وب» (div حاوی مقادیر دما و رطوبت) بهروزرسانی میشود.
ptr +="xhttp.onreadystatechange = function() {\n";
ptr +="if (this.readyState == 4 && this.status == 200) {\n";
ptr +="document.getElementById(\"webpage\").innerHTML =this.responseText}\n";
ptr +="};\n";
سپس از توابع open()
و send()
برای شروع درخواست HTTP استفاده می شود.
ptr +="xhttp.open(\"GET\", \"/\", true);\n";
ptr +="xhttp.send();\n";
ptr +="}\n";
منبع
https://lastminuteengineers.com/esp32-dht11-dht22-web-server-tutorial/
آخرین دیدگاهها