كورس:أنظمة المنازل الذكية المعتمدة على ESP8266 (الدرس الثاني)

Greeting

تعرفنا في الدرس السابق على الأنواع المختلفة للمديول ESP8266 و على كيفية اعداد ال Arduino IDE ليكون قادر على برمجة المتحكم الداخلي للمديول ESP8266 و
في هذا الدرس سنتعرف على كيفية التحكم بالاجهزة و الأحمال عن طريق الإنترنت .


 NodeMCU V1.0

سأعتمد في هذا السلسلة على بورد التطوير NodeMCU V1.0 لما تتميز به عن باقي بوردات التطوير :
  • 11 قطب دخل / خرج قابلة للاستخدام .
  • منفذ USB لرفع البرنامج على المديول .
  • احتوائها على منظم جهد 3.3V لتأمين التغذية اللازمة للمديول .
ملاحظة : استخدامي ل NodeMCU 1.0 لا يعني على الإطلاق انك لو امتلكت ESP-01 فلن تستطيع تطبيق ما ستتعلمه في هذه السلسلة لكن انصح بإقتنائها لما ذكرته من ميزات .
الفيديو التالي يظهر التجربة الخاصة بهذا الدرس :



الكود البرمجي :

// Required libraries
#include <ESP8266WiFi.h>

// WiFi parameters
const char* ssid = "SSID";
const char* password = "PASSWORD";

// Create an instance of the server
WiFiServer server(80);

// Pin
int output_pin = 2;

void setup() {
 
  // Start Serial
  Serial.begin(115200);
  delay(10);

  pinMode(output_pin, OUTPUT);
  digitalWrite(output_pin, LOW);
 
  // Connect to WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
 
  WiFi.begin(ssid, password);
 
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
 
  // Start the server
  server.begin();
  Serial.println("Server started");
 
  // Print the IP address
  Serial.println(WiFi.localIP());
}

void loop() {
 
  // Check if a client has connected
  WiFiClient client = server.available();
  if (!client) {
    return;
  }
 
  // Wait until the client sends some data
  Serial.println("new client");
  while(!client.available()){
    delay(1);
  }
 
  // Read the first line of the request
  String req = client.readStringUntil('\r');
  Serial.println(req);
  client.flush();
 
  // Match the request
  if (req.indexOf("/on") != -1){
    digitalWrite(output_pin, HIGH);
    Serial.println("on led");
  }
  else if (req.indexOf("/off") != -1) {
    digitalWrite(output_pin, LOW);
    Serial.println("off led");
  }
   
  client.flush();

  // Prepare the response
  String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n";
  s += "<head>";
  s += "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">";
  s += "<script src=\"https://code.jquery.com/jquery-2.1.3.min.js\"></script>";
  s += "<link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css\">";
  s += "</head>";
  s += "<div class=\"container\">";
  s += "<h1>Relay Control</h1>";
  s += "<div class=\"row\">";
  s += "<div class=\"col-md-2\"><input class=\"btn btn-block btn-lg btn-primary\" type=\"button\" value=\"On\" onclick=\"on()\"></div>";
  s += "<div class=\"col-md-2\"><input class=\"btn btn-block btn-lg btn-danger\" type=\"button\" value=\"Off\" onclick=\"off()\"></div>";
  s += "</div></div>";
  s += "<script>function on() {$.get(\"/on\");}</script>";
  s += "<script>function off() {$.get(\"/off\");}</script>";
  
  // Send the response to the client
  client.print(s);
  delay(1);
  Serial.println("Client disconnected");
}


شرح الكود :

في بداية الكود قمنا بإدراج المكتبة الخاصة بالمديول :
// Required libraries
#include <ESP8266WiFi.h>

كلنا يعلم ان الاتصال بالشبكة عن طريق ال WIFI يحتاج إلى مُعرف الشبكة SSID و ال Password ولذالك يتوجب عليك اسنادهم للمتحولين التاليين  ssid و password حتى يتمكن المديول من الاتصال بشبكتك اللاسلكية .
// WiFi parameters
const char* ssid = "SSID";
const char* password = "PASSWORD";

لاحظ انني استخدم الدبوس رقم 2 لإظهار النتائج على الليد المدمج على البورد NodeMCU 
// Pin
int output_pin = 2;

حتى تستطيع عرض اي صفحة ويب عن طريق المديول ستحتاج إلى خادم server و كل ما عليك لإنشائه تعريف نسخة من WiFiServer و تهيئة رقم المنفذ Port (و القيمة الافتراضية 80) وهذا ما قمت بعمله .
// Create an instance of the server
WiFiServer server(80);

الأن نأتي لعملية تهيئة المنفذ التسلسلي و قطب الخرج :
// Start Serial
  Serial.begin(115200);
  delay(10);

  pinMode(output_pin, OUTPUT);
  digitalWrite(output_pin, LOW);

للإتصال بالشبكة نستدعي الدالة WiFi.begin و نسند لها معرف الشبكة و الرقم السري و من ثم ندخل المديول بحلقة while ولن يخرج منها حتى يتم الاتصال بالشبكة:
// Connect to WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  
  WiFi.begin(ssid, password);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");

  Serial.println("WiFi connected");


الان نقوم بتشغيل الخادم Server :
// Start the server
  server.begin();
  Serial.println("Server started");

عند الاتصال بالشبكة يقوم الراوتر باعطاء المديول IP address خاص به و ليتثنى لنا الولوج إليه عن طريق المتصفح سنحتاج لمعرفة ال IP address لذالك قمت بطباعته على المنفذ التسلسلي :
  // Print the IP address
  Serial.println(WiFi.localIP());

التحقق من ولوج اي عميل لعنوان ال IP الخاص بالمديول :
// Check if a client has connected
  WiFiClient client = server.available();
  if (!client) {
    return;
  }
هل قام العميل بالضغط على زر التشغيل او الاطفاء ؟
// Wait until the client sends some data
  Serial.println("new client");
  while(!client.available()){
    delay(1);
  }
  
  // Read the first line of the request
  String req = client.readStringUntil('\r');
  Serial.println(req);
  client.flush();
  
  // Match the request
  if (req.indexOf("/on") != -1){
    digitalWrite(output_pin, HIGH);
    Serial.println("on led");
  }
  else if (req.indexOf("/off") != -1) {
    digitalWrite(output_pin, LOW);
    Serial.println("off led");
  }
    
  client.flush();

كود انشاء صفحة ويب وعرضها للعميل :

معلومة : تتم كتابة صفحات الويب بلغة HTML  و يتم تنسيق الصفحات و الالوان باستخدام لغة CSS  أما لغة الجافاسكريبت JavaScript فتقوم بإنشاء دوال تفاعلية بحيث يكون لكل فعل رد فعل وفي مثالنا قمنا بانشاء الدالتين on و off والتان يتم استدعائهما عند الضغط على الازرار المقابلة لهم , و اخيرا ال jQuery هي مكتبة خاصة بالجافا سكريبت، تقوم باختصار العديد من النصوص البرمجية المكررة والمهام المعروفة، وذلك لتسهيل عملية البرمجة.

// Prepare the response
  String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n";
  s += "<head>";
  s += "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">";
  s += "<script src=\"https://code.jquery.com/jquery-2.1.3.min.js\"></script>";
  s += "<link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css\">";
  s += "</head>";
  s += "<div class=\"container\">";
  s += "<h1>Relay Control</h1>";
  s += "<div class=\"row\">";
  s += "<div class=\"col-md-2\"><input class=\"btn btn-block btn-lg btn-primary\" type=\"button\" value=\"On\" onclick=\"on()\"></div>";
  s += "<div class=\"col-md-2\"><input class=\"btn btn-block btn-lg btn-danger\" type=\"button\" value=\"Off\" onclick=\"off()\"></div>";
  s += "</div></div>";
  s += "<script>function on() {$.get(\"/on\");}</script>";
  s += "<script>function off() {$.get(\"/off\");}</script>";
   
  // Send the response to the client
  client.print(s);
  delay(1);
  Serial.println("Client disconnected");

مشاكل و حلول :

  1. من غير المعقول ان تقوم باسناد معرف الشبكة SSID و ال Password ضمن البرنامج لكل عميل على حدى ولحل هذه المشكلة يتوجب عليك انشاء WiFi Access Point و عمل بحث عن جميع الشبكات الموجودة وعرضها على المستخدم ليختار شبكته ويدخل كلمة السر ليتم الاتصال بشبكته وعند نجاح الاتصال يقوم المديول بتخزين معرف الشبكة وكلمة السر في الذاكرة EEPROM ليتثى له الاتصال بها بعد اعادة تشغيل النظام بدون ان يعاود الطلب مرة اخرى , و سنحاول في الدرس القادم حل هذه المشكلة .
  2. عندما يقوم المديول بالاتصال بالراوتر يقوم الاخير باعطائه IP address لكن هذا العنوان من الممكن ان يتغير عند كل اتصال بالراوتر و لحل هذه المشكلة سنقوم باستبدال ال IP address باسم ذو معنى DNS لتسهيل الوصول إليه.
  3. في مثالنا يتم التواصل  مع المديول عن طريق الشبكة المحلية واذا حاولت التواصل مع المديول من شبكة اخرى فلن تستطيع الوصول إليه ولحل هذه المشكلة نقوم بفتح منفذ من الراوتر ولكن هذا الحل مؤقت ولا انصح به للإستخدامات التجارية و سنحاول شرح بروتوكول MQTT في الدروس القادمة لحل هذه المشكلة.


share

8 التعليقات

إضغط هنا لـ التعليقات
Ahmad Al-Shalabi
المدير
4 ديسمبر 2016 8:48 م ×

الله يعطيك العافية :)

رد
avatar
Tarek Al Gamal
المدير
6 ديسمبر 2016 4:29 م ×

بارك الله لك،،،
أرجو أن لا تتأخر علينا في الدرس القادم لحل المشاكل التي ذكرتها

رد
avatar
Tarek Al Gamal
المدير
22 يناير 2017 4:46 م ×

is there a way to use tx and rx for outputs in "esp8266-01" ?
so i can have 4 channels?

رد
avatar
Horizon 4 electronics
المدير
23 يناير 2017 12:56 م ×

watch the video in the link below, it should help you with your problem
http://hackaday.com/2015/05/31/more-gpios-for-the-esp8266/

رد
avatar
Hatem Mahdy
المدير
13 فبراير 2017 10:59 م ×

منذ فتره وانا مهجب بهذه البوردة الصغيرة
ولكن هل التحكم عن طريق الوايفاي يوفر نظاما مستقرا؟
وخصوصا اذا زادت عناصر النظام وزادت مساحة التغطية؟
أقصد ان من عيوب الوايفاي عدم الاستقرار مع التداخل الموجي للاجهزة المحيطة
ومساحة التغطية المحدودة مع الجدران والاسقف.
أرجو عمل مقارنة بينه وبين طرق الاتصال اللاسلكية الاخرى
وجزاكم الله خيرا

رد
avatar
mohamed shams
المدير
4 أبريل 2017 4:41 ص ×

بارك الله فيك

رد
avatar
ali reda
المدير
30 يونيو 2017 7:37 م ×

الله ينور مستنيين الدرس التالت

رد
avatar
Unknown
المدير
2 سبتمبر 2017 5:55 ص ×

بسم الله ما شاء الله... شرح ممتاز جداً... وتوضيح لمعظم الأسئلة التي كانت لدي... وفي انتظار باقي السلسلة.. وربنا يجعله في ميزان حسناتك

رد
avatar
شكرا لك ولمرورك