معرفی:
در ادامهی سری جلسات آموزش آردوینو وارد مبحث جذاب راه اندازی ماژول وای فای ESP8266 و نحوه کدنویسی برای آن با کامپایلر آردوینو شدیم. در جلسه ششم با نحوه معرفی ماژول ESP8266-01 به کامپایلر Arduino آشنا شدیم و یک برنامه چشمکزن ساده نوشتیم و داخل ماژول بارگزاری نمودیم. در این جلسه قصد داریم توسط ماژول ESP8266 به مودم وای فای و در نهایت به سایت iot.avr64.com که یک سرویس آنلاین و رایگان شِبه Cloud اینترنت اشیا است متصل شویم. در این آموزش پروژه محور یک ریموت کنترل تحت وب اینترنتی طراحی میکنیم که روی سخت افزار ریموت یک کانال نوین کیت قابل پیاده سازی است و براحتی میتوان یک رله را از هر کجای دنیا روشن و خاموش نمود. این پروژه در واقع نسخه تکمیل شدهی پروژه راه اندازی ماژول WiFi وای فای ESP8266 میباشد که در سال 1394 با Bascom نوشته شده بود.
مدهای ماژول ESP8266
ماژول ESP8266 را میتوان در دو مد AP یا Access Point و STA یا Station و یا هر دو باهم پیکرهبندی نمود. مد AP حالتی است که ESP8266 به یک اکسس پوینت تبدیل میشود و میتوانیم همانند یک مودم از بخش Wi-Fi گوشی یا کامپیوتر آن را سرچ کنیم و به آن متصل شویم. در این حالت میتوان فقط یک Web Server یا Telnet Server و چیزی شبیه به این در داخل ماژول پیاده سازی کرد.
مد دوم حالت Station میباشد. در این مد که به ایستگاه کاری معروف است ماژول شبیه گوشی موبایل میتواند به یک مودم وای فای متصل شود. پس از اتصال به مودم، هم میتوان داخل ماژول یک وب سرور پیادهسازی کرد و هم میتوان بعنوان یک کلاینت به یک وب سرور متصل شد. در حالتی که در این مد در داخل ماژول یک وب سرور پیاده سازی کنیم تمام صفحات وب داخل ماژول پیاده سازی میشود و برای اتصال به ماژول از داخل شبکه میتوان به IP محلی که ماژول دریافت میکند متصل شد و برای اتصال از خارج شبکه هم حتما باید تنظیمات Port Forwarding یا DMZ بر روی مودم انجام شده و نیاز به دریافت IP Static یا آی پی ثابت از سرویس دهنده اینترنت میباشد.
اما در حالتی که در مد دوم از قابلیت Client یا مشتری استفاده کنیم میتوانیم به اینترنت دسترسی داشته باشیم. یعنی براحتی میتوانیم با پروتکل http به سایتهای مختلف متصل شویم و یا با برنامه نویسی سوکت و با داشتن IP:PORT ماژول را به یک سرور مجازی VPS وصل کنیم. ما در این آموزش از این قابلیت استفاده میکنیم. در واقع ماژول را روی مد استیشن تنظیم میکنیم و از حالت کلاینت بهره میبریم و به سایت iot.avr64.com متصل میشویم.
نحوه عملکرد
قبل از توضیح برنامه آردوینو اجازه دهید کمی در مورد نحوه کار این پروژه توضیح دهیم. ما در این برنامه به سایت iot.avr64.com متصل میشویم و هر 10 ثانیه (یا کمتر) یک URL را میخوانیم که محتوای آن یکی از دو مقدار ##DATA-IS:(on)## یا ##DATA-IS:(off)## میباشد. کاربر از هر نقطهی دنیا میتواند با هر وسیلهای وارد این سایت و اکانت خود شده و این دو مقدار را تغییر دهد. در صورتی که کاربر کلید روشن را کلیک کنید مقدار ##DATA-IS:(on)## در دیتابیس سایت ذخیره میشود و از طریق آدرس http://iot.avr64.com/read.php?u=test@avr64.com&p=123456&r=field_1 بوسیله آردوینو قایل خواندن میباشد. دقت داشته باشید که در این URL عبارت نوشته شده در جلوی u همان یوزرنیم ثبتنامی در سایت iot.avr64.com بوده و عبارت نوشته شده در جلوی p نیز پسورد میباشد. یعد از پردازش و کنترل رله، فیدبک توسط URL دیگری به سایت ارسال میشود. به این نوع ریموت کنترلها مدل P2P نیز گفته میشود، چرا که نیازی به IP ثابت نداشته و دستگاهها توسط سرور واسط به یکدیگر متصل میشوند.
سخت افزار
برای این پروژه میتوانید از سخت افزار آماده رله تک کانال تحت وب نوین کیت استفاده کنید که از طریق این لینک قابل خریداری است. البته نیاز به فلش کردن ماژول و یا استفاده از یک ماژول دیگر ESP8266-01S میباشد.
برنامه آردوینو
در این قسمت برنامه کامل آردوینو آورده شده است. اولین کد با حداقل دستورات print دیباگ نوشته شده و مخصوص اجرای نهایی روی سخت افزار است. کد بعدی دستورات دیباگ بیشتری دارد و فقط برای تست اولیه و آشنا شدن با نحوه اجرا یا عدم اجرای دستورات است. در این برنامه در ابتدا چهار کتابخانه مختلف اضافه شدهاند:
- کتابخانه Arduino.h که یک کتابخانه عمومی بوده و حاوی کدها و توابع داخل آردوینو میباشد.
- کتابخانه ESP8266WiFi.h برای اتصال ESP8266 به مودم وای فای کاربرد دارد.
- کتابخانه ESP8266HTTPClient.h به ما امکان استفاده از پروتکل http و پردازش راحتتر URL ها را میدهد.
- و در نهایت کتابخانه WiFiClient.h برای ایجاد یک کلاینت یا مشتری بکار میرود و می توان گفت که http بر روی این کتابخانه سوار میشود.
در خطوط بعدی باید نام SSID و پسورد مودم وای فای خود را بنویسید. این دو رشته بصورت اشارهگر از نوع Char در آردوینو تعریف شدهاند. بعنوان یک نکته توجه داشته باشید که تعریف رشتهها بصورت اشارهگر و یا حداکثر بصورت آرایه برای آردوینو بسیار سبکتر و بهتر از String میباشد. رشتههای String و دستورات کار بر روی آنها SRAM و Heap بیشتری از میکرو اشغال میکند و امکان بهم ریختن برنامه بیشتر میشود.
در تابع setup ابتدا پایههای 0 و 2 خروجی تعریف شده و مقدار پیشفرض آنها تنظیم شده است. با توجه به اینکه در این پروژه از ماژول وای فای ESP8266-01S و سخت افزار رله تک کانال نوین کیت استفاده کردهایم، پایه 2 که مربوط به LED روی ماژول است را در ابتدای کار با دستور HIGH خاموش و پایه 0 که به رله متصل شده را نیز با دستور LOW بصورت off تنظیم کردهایم.
در خط بعدی با دستور Serial.begin و آرگومان 115200 پروت سریال را که معمولا برای دیباگ کردن (اشکال زدایی) بکار میرود باز کردهایم. برای مشاهده خروجی دیباگ میتوانید پس از آپلود برنامه روی ماژول از منوی Tools>Serial Monitor در محیط آردوینو ترمینال را باز کنید و سرعت آن را روی 115200 قرار دهید.
در بخش بعدی با دستور WiFi.begin و آرگومانهای آن که نام و رمز مودم میباشد میتوانیم به مودم وای فای ADSL متصل شویم. با توجه به این که فراید متصل شدن به شبکه وای فای معمولا اندکی به طول میانجامد در یک حلقه while وضعیت متصل شده به شبکه با دستور WiFi.status چک میشود و تا زمانی که به مودم متصل نشده است یک نقطه در خروجی ترمینال ارسال میشود.
برنامه اصلی در حلقه loop نوشته شده است که به طور دائم تکرار میگردد. در این قیسمت ابتدا با دستور WiFiClient client یک شی به نام client از کلاس WiFiClient ایجاد میشود. برنامه نویسی در آردوینو به زبان سی پلاس پلاس بوده و از قابلیت شی گرایی پشتیبانی میکند. اگر در این زمینه اطلاعاتی ندارید حتما در خصوص شی گرایی در سی پلاس پلاس آموزش های زیادی که در اینترنت وجود دارد را مطالعه نمایید.
در خط بعدی نیز با دستور HTTPClient http یک شی به نام http از کلاس والد HTTPClient ایجاد شده است. ما در برنامه نویسی شی گرایی برای کار با کلاس ها حتما باید از آنها شی ایجاد کنیم. نکته جالب در این روش اینست که به تعداد زیادی میتوان از یک کلاس شی ایجاد کرد و این اشیا که باید دارای نام های متفاوت باشند هر کدام از یکدیگر مستقل بوده میتوانند بدون اختلال روی یکدیگر و بصورت مستقل کار کنند. درست بر خلاف استفاده از توابع. بعنوان یک مزیت برنامه نویسی شی گرایی فرض کنید برای نوشتن یک بازی فوتبال براحتی میتوان 12 شی از کلاس بازیکن ایجاد کرد و برای هر یک نام و کد مشخص لباس تنظیم کرد و هر یک را در موقعیت خاصی از زمین قرار داد.
در قسمت بعدی از دستور http.begin استفاده کردهایم. تابع begin یک تابع عضو از کلاس HTTPClient است که دو آرگومان مختلف میگیرد. آرگومان اول کلاینتی است که باید روی آن عمل کند و آرگومان دوم نیز آدرس کامل URL با http (در این کد حتما از ULR ساده غیر SSL و بدون S استفاده شود. برای کار با https باید تغییراتی در کد اعمال نمود). این تابع برای آغاز پردازش URL میباشد.
دستور بعدی یعنی http.GET تابع GET را از کلاس HTTPClient اجرا میکند. این تابع URL تنظیم شده در دستور قبل را با متد GET فراخوانی میکند. در مورد متدهای GET و POST نیز مطالب بیشماری در اینترنت وجود دارد که در این مختصر نمیگنجد. فقط همینقدر بدانید که متد POST در فرمهای ثبت نام بکار میرود و معمولا برای آپلود اطلاعات مثل عکس و… به سرور میتوان از آن استفاده کرد.
در بخش بعدی کد برگشتی از تابع چک می شود و اگر صفحه با موفقیت پردازش شده باشد با دستور http.getString محتوای صفحه خوانده میشود. محتوای برگشتی API ما یکی از دو مقدار ##DATA-IS:(on)## یا ##DATA-IS:(on)## است.
در بخش بعدی با دستور payload.indexOf مقدار رشته دریافتی بررسی میشود و متناسب با رشته دریافتی رله و LED روشن یا خاموش میشوند. همچنین مجددا URL دیگری پردازش میشود. اگر دستور خاموش را دریافت کرده باشیم URL اول و اگر دستور روشن را گرفته باشیم URL دوم را پردازش میکنیم. این URL ها فیدبک را در سرور ثبت میکنند و در سایت وضعیت واقعی رله را نشان میدهند.
- http://iot.avr64.com/write.php?u=test@avr64.com&p=123456&f=state_1&v=off
- http://iot.avr64.com/write.php?u=test@avr64.com&p=123456&f=state_1&v=on
در انتهای حلقه نیز دستور delay روی 10 ثانیه تنظیم شده است. این مقدار را روی یک مقدار معقول قرار دهید. اگر خیلی کم باشد سرور و برد دچار اختلال میشوند و ترافیک اینترنت سرور و ترافیک شما نیز بیهوده تلف میشود. اگر هم خیلی زیاد باشد سرعت دستگاه کم میشود و دیر پاسخ میدهد. مقدار 10 ثانیه الی 30 ثانیه قابل قبول است. ضمنا دستور delay اعداد خیلی بالا را قبول نمیکند و باید از چند دستور پشت سرهم استفاده کنید.
کد اصلی بدون دستورات دیباگ برای آپلود در سخت افزار:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
#include <Arduino.h> #include <ESP8266WiFi.h> #include <ESP8266HTTPClient.h> #include <WiFiClient.h> #ifndef STASSID #define STASSID "your-modem-ssid" #define STAPSK "your-modem-pass" #endif const char* ssid = STASSID; const char* password = STAPSK; void setup() { pinMode(0,OUTPUT); pinMode(2,OUTPUT); digitalWrite(0,LOW); digitalWrite(2,HIGH); Serial.begin(115200); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } delay(500); } void loop() { WiFiClient client; HTTPClient http; if (http.begin(client, "http://iot.avr64.com/read.php?u=test@avr64.com&p=123456&r=field_1")) { int httpCode = http.GET(); if (httpCode > 0) { if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) { String payload = http.getString(); Serial.println(payload); if(payload.indexOf("##DATA-IS:(off)##")>0){ digitalWrite(0,LOW); digitalWrite(2,HIGH); http.begin(client, "http://iot.avr64.com/write.php?u=test@avr64.com&p=123456&f=state_1&v=off"); http.GET(); } if(payload.indexOf("##DATA-IS:(on)##")>0){ digitalWrite(0,HIGH); digitalWrite(2,LOW); http.begin(client, "http://iot.avr64.com/write.php?u=test@avr64.com&p=123456&f=state_1&v=on"); http.GET(); } } } http.end(); } delay(10000); } |
کد دوم فقط برای شروع کار آورده شده و رله و LED را روشن و خاموش نمیکند و ارسال فیدبک نیز ندارد اما دستورات Debug فراوانی دارد و تمام مراحل پردازش URL ها و اتصال به مودم و سایت را روی سریال مانیتور نمایش میدهد. ترجیحا ابتدا با این کد کار کنید و بعد از آشنایی با روند برنامه کد اصلی را روی ماژول آپلود کنید. ضمناً از ماژول های آماده Wemos هم میتوانید استفاده کنید فقط در بخش Tools>Board ماژول مناسب را انتخاب نمایید.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
#include <Arduino.h> #include <ESP8266WiFi.h> #include <ESP8266HTTPClient.h> #include <WiFiClient.h> #ifndef STASSID #define STASSID "your-modem-ssid" #define STAPSK "your-modem-pass" #endif const char* ssid = STASSID; const char* password = STAPSK; int h=0; void setup() { Serial.begin(115200); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); Serial.println(); Serial.print("Wait for WiFi... "); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); delay(500); } void loop() { WiFiClient client; HTTPClient http; Serial.print("[HTTP] begin...\n"); if (http.begin(client, "http://iot.avr64.com/read.php?u=test@avr64.com&p=123456&r=field_1")) { Serial.print("[HTTP] GET...\n"); // start connection and send HTTP header int httpCode = http.GET(); // httpCode will be negative on error if (httpCode > 0) { // HTTP header has been send and Server response header has been handled Serial.printf("[HTTP] GET... code: %d\n", httpCode); // file found at server if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) { String payload = http.getString(); Serial.println(payload); } } else { Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str()); } http.end(); } else { Serial.printf("[HTTP} Unable to connect\n"); } delay(10000); } |
فیلم عملکرد
در این قسمت یک ویدیوی کوتاه از عملکرد این رله تحت وب اینترنتی آورده شده است:
خلاصه
در این مقاله به آموزش ساخت یک ریموت p2p اینترنتی پرداختیم. استفاده از دستور GET به طور مداوم یک روش ابداعی میباشد ولی ترافیک زیادی را ایجاد میکند. مزیت این روش استفاده از هاست های ارزان قیمت برای ساخت ریموت اینترنتی شبه Cloud و عدم نیاز به VPS و یا IP Static میباشد. برای سرعت بالاتر و Real Time باید از یک سرور مجازی یا حقیقی (اصطلاحا سرور ابری یا کلود (Cloud)) بجای هاست استفاده کرد و با دستورات سوکت و مفسر NodeJs یا محیط Node RED کار کرد.
بازدیدها: 453