دانشجوی مهندسی برق و علاقه مند به رباتیک و اینترنت اشیاء
راه اندازی یک وب سرور ساده با ESP8266
سلاااام
در قسمت ششم ESP رو به وای فای متصل کردیم و در این قسمت و احتمالا چند قسمت بعدی روی وب سرور کار خواهیم کرد.
چی هست اصن؟
خب وقتی یک سایت رو باز می کنید این اطلاعات از کجا میاد؟ از وب سرور
پس وب سرور به تعریف ساده یک کامپیوتر متصل به شبکه است که یک سری فایل و احتمالا دیتابیس رو در خودش نگه داری میکنه مثلا فایل های HTML, JS, CSS یا عکس، فیلم و... و زمانی که کاربر این اطلاعات رو درخواست میکنه، فایل ها رو برای کاربر ارسال می کنه.
ما قراره به ESP بگیم که وقتی کاربر یک آدرس رو وارد کرد بیا و مثلا یک صفحه HTML برایش بفرست!
از اینجا به بعد ممکنه یکم مباحث وب و شبکه هم قاطی بحثمون بشه !!
راه اندازی وب سرور با ESP
از اونجایی که آردوینو مثال درست و درمونی نداشت این کد زیر رو آماده کردم و طبق اون جلو میریم:
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#ifndef STASSID
#define STASSID "SSID" // YOUR WIFI SSID
#define STAPSK "PASSWORD" // YOUR WIFI PASSWORD
#endif
const char* ssid = STASSID;
const char* password = STAPSK;
ESP8266WebServer server(80);
خب اول کتابخونه های لازم که ESP8266WiFi برای اتصال به شبکه و ESP8266WebServer برای اجرای وب سرور رو import کردیم.
بعد دوتا define داریم که اسم و پسورد وای فایتون رو وارد می کنید که ESP به اون شبکه متصل بشه.
و بعد هم یک Object به اسم سرور تعریف کردیم که آرگومان ورودی اون شماره پورتی هست که سرور قراره اجرا بشه.
چندتا نکته:
- پورت پیشفرض همون 80 هست و اگر اون رو انتخاب کنید لازم نیست بعد از IP یا Host Name پورت رو وارد کنید.
- پورت 443 برای HTTPS هست. پس این پورت هم نیازی به وارد کرد بعد از آدرس نداره فقط باید Redirect ها رو مدیریت کنید.
- بعضی پورت ها رو نمیشه استفاده کرد چون برای یک کار دیگه ای در نظر گرفته شده اند. پس اگه می خواهید عوضش کنید لیست پورت های قابل استفاده رو در اینجا ببینید.
- اگر پورتی جز 80 یا 443 انتخاب کردید باید به صورت IP_or_Domain:Port در مرورگر وارد کنید.
- اگر بازم باز نشد یک / (اسلش) آخرش قرار بدین یا اول آدرس http or https بزنید تا مرورگر متوجه بشه یک هاست هست.
void setup(void) {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.println("");
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());
server.on("/", []() {
server.send(200, "text/plain", "Hello My Little Server");
});
server.begin();
Serial.println("HTTP server started");
}
و اما بخش مهم کار! اول که سریال مانیتور استارت شده، بعد اتصال به وای فای و چاپ کردن آی پی ESP. تا اینجا رو قبلا داشتیم!
دستور بعدی ()server.on یک تابع هست که عموما دوتا پارامتر ورودی دارد یکی path و یک کاری که باید پس از ریکوئست دادن به اون path انجام بده.
در اینجا پارامتر اول "/" هست یعنی همون آدرس خالی (HomePage). نگران نباشید در ادامه مثال های بیشتری خواهیم داشت!
پارامتر دوم یک خودش یک تابع هست! میتونید قبل از setup یک تابع تعریف کنید یا همین جا اون تابع رو معرفی کنید. این ()[] یعنی یک تابع و اگر توی پرانتز اسم یک متغیر رو بنویسید به عنوان آرگومان اون تابع درنظر گرفته میشه و بعدش هم که { روتین تابع } رو مینویسید. توی روتین تابع یک دستور send داریم. آرگومان اول کد هست که عدد 200 به معنی ok هست. ارگومان بعدی نوع دیتایی هست که میخواهیم بفرستیم که در اینجا یک متن معمولی هست پس text/plain رو در نظر میگیریم. و نهایتا آرگومان سوم دیتای ما هست یعنی همون متن معمولی که متنی که دوست داریم در اون صفحه وب نمایش داده بشه رو می نویسیم.
در آخر با دستور ()server.begin سرور را اجرا میکنیم. پس بعد از اون برای این که مطمئن بشیم این دستور اجرا شده و سرور اصطلاحا بالا اومده توی سریال متنی رو چاپ میکنیم.
برخی از ارور کد ها:
- 200 که یعنی همه چی رو به راهه.
- 404 رو هم میدونید دیگه یعنی Not Found یا چنین صفحه ای وجود ندارد.
- 403 به معنی عدم دسترسی هست! احتمالا توی گوگل این ارور کد رو زیاد دیدین و یعنی از ایران اجازه دسترسی نداریم به این صفحه.
- سری 500 خطاهای سمت سرور هست یعنی توی سرور یه مشکلی هست یا سرور در دسترس نیست.
هنوز تموم نشده بریم سراغ لوپ
void loop(void) {
server.handleClient();
}
توی لوپ برنامه باید بگیم که درخواست های کاربر رو رسیدگی! (هندل) کن.
خب همه چی آماده است. کد رو آپلود میکنیم. و منتظر می مونیم تا ESP به شبکه وصل بشه و آی پی رو بهمون بده و همچنین سرور رو run کنه!
الان کافیه از یک دیوایسی که روی همون شبکه هست آی پی ESP رو در مرورگر سرچ کنیم و یک صفحه خیلی ساده با متن Hello My Little Server نمایش داده میشه. تا اینجا یعنی یک وب سرور کوچیک رو راه اندازی کردیم ^_^
دوباره یک سری نکته!
- برای دسترسی به یک پورت اولا باید اون پورت به چیزی اختصاص داشته باشه (که ما پورت 80 رو به وب سرور اختصاص دادیم).
- دوما باید توسط دیوایسی که اون پورت رو ایجاد کرده و همچنین فایروال ها اجازه دسترسی داشته باشیم.
- سوما باید توی یک شبکه باشیم (بیشتر مربوط میشه به آی پی البته!) مثلا سیستمی که وب سرور را ایجاد کرده و سیستمی که اون رو مشاهده می کنه به یک مودم وای فای وصل باشند. حتی این شبکه میتونه توسط خود ESP ایجاد بشه و شما به ESP متصل بشید! احتمالا در مباحث آینده داریم!
- اگر بخواهیم از طریق اینترنت (دیوایسی که به شبکه فعلی ESP متصل نیست ولی دسترسی به اینترنت دارد) به ESP که آن هم به یک مودم متصل است و خود مودم هم به اینترنت متصله، صفحه وب رو ببینیم میشه؟ معلومه که میشه چون هم سرور و کلاینت در یک شبکه (اینترنت) هستند فقط باید اجازه دسترسی به پورت 80 مربوط به آی پی ESP رو در مودم/روتر آزاد کنید. و با یک Port Forwarding در روتر ترافیک مثلا پورت 5000 آی پی گلوبالتون در نت رو به پورت 80 آی پی ESP اتنقال بدین! کار خاصی نداره البته. فقط اینکه آی پی گلوبال تو نت با هر بار قطع و وصل شدن عوض میشه و باید مشکلات امنیتیش رو به جون بخرید!
بیخیال اینا! بریم سر کار خودمون
Handle Not Found
بیاین یک صفحه دیگه رو سرچ کنیم! مثلا YourIP:Port/lamp یعنی مثلا چنین چیزی: http://192.168.1.10/lamp خب با یه صفحه زشت 404 مواجه میشیم که یعنی این صفحه وجود ندارد.
می خواهیم ببنیم چطوری Not Found ها رو Handle کنیم.
اول توی همون کد قبل از setup کد تابع به اسم onNotFound تعریف میکنیم
void onNotFound() {
String message = "File Not Found\n\n"
message += "URI: "
message += server.uri();
server.send(404, "text/plain", message);
}
این تابع زمانی که اجرا بشه یک String درست میکنه که شامل یک پیغام و آدرس اون صفحه است. و یک 404 ارسال میکند که متن آن همین String است.
و حالا باید در Setup برنامه بگوییم زمانی که صفحه ای که وجود نداشت درخواست شد این تابع را اجرا کن! به این منظور کد زیر را بعد از sever.on قبلی و قبل از اجرا سرور در تابع setup درج میکنیم.
server.onNotFound(onNotFound);
و حالا با درخواست کردن یک صفحه ای که موجود نیست میتوانیم به صفحه 404 خودمان برسیم :)
خیلی طولانی شد ولی برای اینکه یک خروجی درست حسابی داشته باشیم بیاین با وب یک LED رو خاموش و روشن کنیم.
اجرا دستورات آردوینو در متن سرور
دوتا تابع داریم به اسم های led_on , led_off و قبل از setup تعریف میکنیم:
void led_on(){
digitalWrite(LED_BUILTIN, LOW);
server.send(200, "text/plain", "LED is ON!");
}
void led_off(){
digitalWrite(LED_BUILTIN, HIGH);
server.send(200, "text/plain", "LED is OFF!");
}
این دوتا تابع زمانی که اجرا بشن led روی برد ESP روشن و خاموش می کنند. شاید بپرسین چرا اسم تابع با HIGH LOW بودن پایه برعکس؟ چون پایه رو که صفر کنید مدار روشن شدن تکمیل میشه! عکس زیر
و در setup برنامه پایه led را خروجی میکنیم:
pinMode(LED_BUILTIN, OUTPUT);
server.on("/on", led_on);
server.on("/off", led_off);
یادتون هست که آرگومان دوم server.on تابع بود؟ الان هم اسم تابع هایی که از قبل نوشتیم را بدون پرانتز وارد می کنیم! و تمام
حالا با وارد کردن on/ یا off/ بعد از آی پی ESP ضمن خاموش و روشن کردن LED در صفحه وب هم اطلاع می دهد که LED خاموش یا روشن شد. مثلا http://192.168.1.10/on
کلا در تابع هندل کردن صفحات وب میتونید تمام دستورات آردوینو رو استفاده کنید به شرطی که خیلی زمان بر نباشند.
اگر شما هم به فکر این افتادین که به جای LED یک رله وصل کنید و لامپ اتاقتون رو با وب خاموش و روشن کنید، صبر کنید!!
مشکل این کتابخانه
حلقه loop رو ببنید. لازمه که همیشه server.handleClient اجرا بشه و اگر نشه چی؟ سرور بالا نمیاد. مثلا فرض کنید یک دستور زمان بر یا مثلا delay در این حلقه داریم؛ تا زمانی که این دستورات اجرا نشه و به handleClient نرسه شما باید منتظر بارگزاری صفحه مورد نظرتون باشید! این یعنی فاجعه! به همین دلیل خیلی از این مثال و کتابخونه خوشم نمیاد :(
کد های این قسمت را می توانید از اینجا دانلود کنید.
شما هم مثل من از این کتابخونه خوشتون نیومد؟ یا دوست دارین وب پنل کاربر پسندتری داشته باشین؟
منتظر قسمت هشتم باشید تا در حل این موضوع با هم همراه باشیم.
مطلبی دیگر از این انتشارات
بهانهای برای ورود به دنیای امبدد سیستمها (V)
مطلبی دیگر از این انتشارات
دستورات مقدماتی وای فای ESP8266
مطلبی دیگر از این انتشارات
رزبری پای پیکو (Pico) ; ورود رزبری پای به کلاس میکروکنترلر ها