تحكم في مصباح من هاتفك عبر الواي فاي 📱💡 | ESP32 من الصفر #7
في هذا المشروع من سلسلة ESP32 من الصفر سنتعلم كيفية التحكم في مصباح LED مباشرة من الهاتف باستخدام شبكة WiFi، وبدون الحاجة إلى تثبيت أي تطبيق. سنقوم بربط لوحة ESP32 بالشبكة وتحويلها إلى خادم ويب (Web Server) يحتوي على صفحة بسيطة تسمح لنا بتشغيل المصباح وإطفائه من متصفح الهاتف.
هذا المشروع سيساعدنا على فهم واحدة من أهم مميزات ESP32، وهي إمكانية ربط المشاريع الإلكترونية بالشبكة والتحكم فيها عن بعد.
فيديو المشروع
ضع فيديو YouTube للحلقة 7 هنا.
فكرة المشروع
تعتمد فكرة المشروع على توصيل الهاتف ولوحة ESP32 بنفس شبكة WiFi. تقوم لوحة ESP32 بإنشاء خادم ويب صغير يحتوي على صفحة تحكم يمكن فتحها مباشرة من متصفح الهاتف.
عند الضغط على زر تشغيل يرسل المتصفح طلبًا إلى ESP32، فتقوم اللوحة بتغيير حالة المنفذ GPIO23 إلى HIGH، وبالتالي يشتغل المصباح.
وعند الضغط على زر إيقاف يتم إرسال طلب آخر يجعل GPIO23 في الحالة LOW، فينطفئ المصباح.
الهاتف ← WiFi → الشبكة ← WiFi → ESP32 → GPIO23 → LED
المكونات المطلوبة
| المكون | العدد |
|---|---|
| لوحة ESP32 | 1 |
| مصباح LED | 1 |
| مقاومة مناسبة للمصباح | 1 |
| Breadboard | 1 |
| Jumper Wires | حسب الحاجة |
مخطط التوصيل
الدائرة الإلكترونية المستخدمة في هذا المشروع بسيطة جدًا. نقوم بتوصيل المنفذ GPIO23 بالمقاومة، ثم بالطرف الموجب للمصباح LED، بينما يتم توصيل الطرف السالب بالأرضي GND.
| ESP32 | التوصيل |
|---|---|
| GPIO23 | المقاومة ← الطرف الموجب LED |
| GND | الطرف السالب LED |
تعمل المقاومة على تحديد التيار المار عبر المصباح وحمايته من التيار الزائد.
ضع صورة مخطط التوصيل هنا.
كيف يعمل المشروع؟
بعد تشغيل ESP32 تتصل اللوحة بشبكة WiFi باستخدام اسم الشبكة وكلمة المرور الموجودين داخل البرنامج.
بعد نجاح الاتصال تحصل ESP32 على عنوان IP داخل الشبكة المحلية. نقوم بكتابة هذا العنوان في متصفح الهاتف للوصول إلى صفحة التحكم.
يستخدم البرنامج ثلاثة مسارات رئيسية:
/لعرض صفحة التحكم الرئيسية./onلتشغيل المصباح./offلإطفاء المصباح.
عندما نضغط على أحد الأزرار في صفحة التحكم يرسل المتصفح طلب HTTP إلى المسار المناسب، ثم تقوم ESP32 بتنفيذ الأمر المرتبط به.
الكود الكامل للمشروع
مهم: قبل رفع البرنامج إلى ESP32، قم باستبدال WIFI_NAME و WIFI_PASSWORD باسم شبكة WiFi وكلمة المرور الخاصة بك.
#include <WiFi.h>
#include <WebServer.h>
// Wi-Fi
const char* ssid = "WIFI_NAME";
const char* password = "WIFI_PASSWORD";
// LED
#define LED_PIN 23
// Serveur Web
WebServer server(80);
bool ledState = false;
// Page principale
void handleRoot() {
String html = "<!DOCTYPE html><html lang='ar' dir='rtl'>";
html += "<head>";
html += "<meta charset='UTF-8'>";
html += "<meta name='viewport' content='width=device-width, initial-scale=1.0'>";
html += "<title>التحكم في المصباح</title>";
html += "<style>";
html += "body {font-family: Arial; text-align: center; margin-top: 50px;}";
html += "h1 {color: #444;}";
html += "p {font-size: 20px; color: #666;}";
html += ".button {display: block; width: 150px; color: white;";
html += "padding: 15px; margin: 20px auto; text-decoration: none;";
html += "font-size: 22px; border-radius: 8px;}";
html += ".on {background-color: #2ecc71;}";
html += ".off {background-color: #e74c3c;}";
html += "</style></head>";
html += "<body>";
html += "<h1>التحكم في المصباح بواسطة ESP32</h1>";
if (ledState) {
html += "<p>حالة المصباح: <strong>مشتغل 💡</strong></p>";
html += "<a class='button off' href='/off'>إيقاف</a>";
} else {
html += "<p>حالة المصباح: <strong>متوقف</strong></p>";
html += "<a class='button on' href='/on'>تشغيل</a>";
}
html += "</body></html>";
server.send(200, "text/html; charset=UTF-8", html);
}
// تشغيل المصباح
void handleOn() {
ledState = true;
digitalWrite(LED_PIN, HIGH);
server.sendHeader("Location", "/");
server.send(303);
}
// إيقاف المصباح
void handleOff() {
ledState = false;
digitalWrite(LED_PIN, LOW);
server.sendHeader("Location", "/");
server.send(303);
}
void setup() {
Serial.begin(115200);
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
// الاتصال بشبكة Wi-Fi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.println("Wi-Fi connected");
Serial.print("IP: ");
Serial.println(WiFi.localIP());
// مسارات خادم الويب
server.on("/", handleRoot);
server.on("/on", handleOn);
server.on("/off", handleOff);
// تشغيل الخادم
server.begin();
}
void loop() {
server.handleClient();
}شرح الكود
استدعاء مكتبات WiFi و WebServer
نبدأ باستدعاء المكتبتين WiFi.h و WebServer.h. تسمح المكتبة الأولى للوحة ESP32 بالاتصال بشبكة WiFi، بينما تسمح لنا الثانية بإنشاء خادم ويب داخل ESP32 واستقبال الطلبات القادمة من المتصفح.
إعداد معلومات شبكة WiFi
يتم تخزين اسم الشبكة في المتغير ssid وكلمة المرور في password. يجب استبدال WIFI_NAME و WIFI_PASSWORD بمعلومات الشبكة الخاصة بك.
تحديد GPIO23
باستخدام #define LED_PIN 23 نحدد أن المصباح متصل بالمنفذ GPIO23. استخدام الاسم LED_PIN يجعل البرنامج أسهل في القراءة والتعديل.
إنشاء خادم الويب
التعليمة WebServer server(80); تنشئ خادم ويب يعمل على المنفذ 80، وهو المنفذ القياسي المستخدم عادة للاتصال بصفحات الويب عبر بروتوكول HTTP.
أما المتغير ledState فيستخدم للاحتفاظ بحالة المصباح. وضعنا قيمته في البداية على false لأن المصباح سيكون متوقفًا عند تشغيل ESP32.
إنشاء صفحة التحكم
الدالة handleRoot() مسؤولة عن إنشاء صفحة HTML التي ستظهر على الهاتف. استخدمنا lang='ar' لتحديد اللغة العربية و dir='rtl' لجعل اتجاه الكتابة من اليمين إلى اليسار.
كما استخدمنا ترميز UTF-8 لعرض الحروف العربية بشكل صحيح، وأضفنا إعداد viewport حتى تتكيف الصفحة مع حجم شاشة الهاتف.
تغيير الصفحة حسب حالة المصباح
يختبر الشرط if (ledState) حالة المصباح. إذا كان مشتغلًا تعرض الصفحة زر إيقاف، وإذا كان متوقفًا تعرض زر تشغيل.
يرسل زر التشغيل المتصفح إلى المسار /on، بينما يرسل زر الإيقاف الطلب إلى المسار /off.
تشغيل المصباح
عند تنفيذ handleOn() تصبح قيمة ledState مساوية لـ true، ثم تقوم digitalWrite(LED_PIN, HIGH) بوضع GPIO23 في الحالة المرتفعة وتشغيل المصباح.
بعد ذلك يتم توجيه المتصفح إلى الصفحة الرئيسية من جديد حتى تظهر حالة المصباح الجديدة.
إيقاف المصباح
تعمل الدالة handleOff() بالعكس. تصبح حالة المصباح false وتقوم digitalWrite(LED_PIN, LOW) بإطفائه، ثم يعود المتصفح إلى الصفحة الرئيسية.
الاتصال بشبكة WiFi
تبدأ عملية الاتصال بواسطة WiFi.begin(ssid, password). وطالما أن WiFi.status() لا تساوي WL_CONNECTED ينتظر البرنامج ويعرض نقاطًا في Serial Monitor.
معرفة عنوان IP الخاص بـ ESP32
بعد نجاح الاتصال تعرض WiFi.localIP() عنوان IP الخاص بلوحة ESP32 داخل الشبكة. سنكتب هذا العنوان في متصفح الهاتف للوصول إلى صفحة التحكم.
إنشاء مسارات خادم الويب
نستخدم server.on() لربط كل مسار بالدالة المناسبة: المسار / يعرض الصفحة الرئيسية، والمسار /on يشغل المصباح، والمسار /off يطفئه.
تشغيل خادم الويب
تقوم server.begin() بتشغيل الخادم، وبعدها تصبح لوحة ESP32 جاهزة لاستقبال الطلبات القادمة من الهاتف.
استقبال طلبات المتصفح
داخل الدالة loop() تعمل server.handleClient() باستمرار وتتحقق من وجود طلب جديد. عندما نضغط على زر في الهاتف تستقبل ESP32 الطلب وتوجهه إلى الدالة المناسبة.
رفع البرنامج وتجربة المشروع
- قم بتوصيل ESP32 بالحاسوب.
- افتح البرنامج في Arduino IDE.
- غيّر
WIFI_NAMEإلى اسم شبكة WiFi الخاصة بك. - غيّر
WIFI_PASSWORDإلى كلمة مرور الشبكة. - ارفع البرنامج إلى لوحة ESP32.
- افتح Serial Monitor بسرعة 115200.
- انتظر حتى تتصل ESP32 بشبكة WiFi.
- انسخ عنوان IP الذي سيظهر في Serial Monitor.
- تأكد من أن الهاتف متصل بنفس شبكة WiFi.
- اكتب عنوان IP في متصفح الهاتف.
ستظهر صفحة التحكم التي أنشأناها داخل ESP32. اضغط على تشغيل لإضاءة LED وعلى إيقاف لإطفائه.
مشاكل شائعة وحلولها
ESP32 لا تتصل بشبكة WiFi
تأكد من كتابة اسم الشبكة وكلمة المرور بشكل صحيح داخل البرنامج، وتأكد من توفر شبكة WiFi في المكان الذي توجد فيه لوحة ESP32.
صفحة التحكم لا تظهر على الهاتف
تأكد من أن الهاتف ولوحة ESP32 متصلان بنفس شبكة WiFi، ثم تحقق من كتابة عنوان IP الظاهر في Serial Monitor بشكل صحيح داخل المتصفح.
عنوان IP لا يظهر في Serial Monitor
تأكد من ضبط سرعة Serial Monitor على 115200 baud، وهي نفس السرعة المستخدمة في Serial.begin(115200).
صفحة التحكم تظهر ولكن LED لا يعمل
تحقق من توصيل المصباح بالمنفذ GPIO23، وتأكد من اتجاه LED الصحيح ومن توصيل المقاومة و GND.
ماذا تعلمنا؟
تعلمنا في هذا المشروع كيفية:
- ربط ESP32 بشبكة WiFi.
- إنشاء Web Server داخل ESP32.
- إنشاء صفحة HTML داخل البرنامج.
- استخدام HTTP Routes.
- معرفة عنوان IP الخاص بـ ESP32.
- التحكم في GPIO23 من متصفح الهاتف.
- تشغيل وإطفاء LED عن بعد بدون تثبيت أي تطبيق.
استخدمنا في هذا المشروع مصباح LED بسيطًا، لكن نفس المبدأ يمكن استخدامه لاحقًا للتحكم في أجهزة أخرى وإنشاء مشاريع IoT أكثر تطورًا.
ESP32 من الصفر
← الحلقة السابقة | الحلقة التالية →