ในบทเรียนนี้ เราจะมาสร้างแอป DroidScript เพื่อควบคุมรีเลย์ผ่านบอร์ด ESP32 ด้วย WiFi กัน งานนี้จัดไปวัยรุ่น!
ของที่ต้องเตรียม:
· บอร์ด ESP32 (เราใช้ ESP32_core_board_v2)
· อุปกรณ์ Android
· แอป DroidScript
· Arduino IDE
· โมดูลรีเลย์
· สาย Micro USB
· เจ้ามาเฟียสายจัมเปอร์ ตัวเมีย-ตัวเมีย x3 เส้น
· WiFi (ห้ามช็อตนะตัวนี้)
ขั้นตอนที่ 1: ติดตั้ง Arduino IDE
อย่างแรก เราต้องเพิ่มบอร์ด ESP32 เข้าไปใน Arduino IDE ก่อน ตามไปเซ็ตอัพกันเลย
จากนั้น เราต้องเพิ่มไลบรารีที่จะใช้รันเว็บเซิร์ฟเวอร์บน ESP32 เพื่อให้เราสามารถคุยกับมันได้
ให้ดาวน์โหลดไลบรารี ESPAsyncWebServer มาเป็นไฟล์ zip แล้วเพิ่มเข้าไปใน Arduino IDE ผ่านเมนู Sketch -> Include Library -> Add .ZIP Library...
ไลบรารีนี้จะช่วยให้เราสร้างเว็บเซิร์ฟเวอร์แบบ asynchronous บน ESP32 ได้ เราจะใช้ WiFi ในการเชื่อมต่อและสั่งงานมัน

ขั้นตอนที่ 2: โค้ดเว็บเซิร์ฟเวอร์สำหรับ Arduino
คัดลอกโค้ดด้านล่างไปวางใน Arduino IDE แล้วกรอกชื่อ WiFi (SSID) และรหัสผ่านของตัวเองลงไปให้เรียบร้อย
เสร็จแล้วไปที่ Tools -> Board แล้วเลือก ESP32 Dev Module (หรือบอร์ดที่เราใช้) จากนั้นเสียบบอร์ดเข้ากับคอมด้วยสาย Micro USB มันจะโผล่ใน Tools -> Port ให้เลือกบอร์ดและพอร์ตให้ถูก แล้วอัพโหลดโค้ดได้เลย สู้งานนะน้อง!
#include "WiFi.h"
#include "ESPAsyncWebServer.h"
const char* ssid = "myRouter"; //replace
const char* password = "myPassword"; //replace
AsyncWebServer server(80);
int relayPin = 23;
void setup()
{
pinMode(relayPin, OUTPUT);
digitalWrite(relayPin, HIGH);
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(1000);
Serial.println("Connecting to WiFi..");
}
Serial.println(WiFi.localIP());
server.on("/hello", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "text/plain", "Hello World");
});
server.on("/relay/off", HTTP_GET , [](AsyncWebServerRequest *request){
request->send(200, "text/plain", "ok");
digitalWrite(relayPin, HIGH);
});
server.on("/relay/on", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "text/plain","ok");
digitalWrite(relayPin, LOW);
});
server.on("/relay/toggle", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "text/plain","ok");
digitalWrite(relayPin, !digitalRead(relayPin));
});
server.on("/relay", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "text/plain", String(digitalRead(relayPin)));
});
server.begin();
}
void loop(){}

ขั้นตอนที่ 3: หา IP Address ของ ESP32
เปิด Serial Monitor ใน Arduino IDE ขึ้นมา จะเห็นข้อความประมาณนี้:
จำ IP Address ที่อยู่ด้านล่างให้ดีๆ ไว้ใช้ตอนหลัง ถ้าไม่เห็นอะไรโผล่ ลองกดปุ่ม Reset บนบอร์ด ESP32 ดู

ขั้นตอนที่ 4: แอป DroidScript
เปิดแอป DroidScript บนมือถือ แล้วสร้างแอปใหม่ขึ้นมา คัดลอกโค้ดด้านล่างไปวางในแอป แล้วกรอก IP Address จากขั้นตอนที่แล้วลงไปให้เรียบร้อย
วิธีที่ง่ายที่สุดคือเปิด Web Editor ไปเลยจ้า - กดไอคอน WiFi ในแอพ แล้วพิมพ์ IP Address ที่ได้ลงในเบราว์เซอร์ของน้องซะ วิธีสร้างแอพใหม่:
จากในแอพ: ไปที่ปุ่มสามจุดแล้วกด New ตั้งชื่อแอพ แล้วเลือกประเภทเป็น Native กับ Simple ตามเดิม
จาก Web Editor: กดไอคอนตารางสี่เหลี่ยม (ปุ่ม Apps) แล้วเลือก 'New JavaScript App' ตั้งชื่อให้มัน ปล่อยประเภทเป็น simple แล้วกด Ok แอพจะเปิดขึ้นมา แล้วน้องก็แทนที่โค้ด Hello World ตัวอย่างด้วยโค้ดด้านล่างนี้ได้เลย อย่าลืมเปลี่ยน IP Address เป็น IP ของ ESP32 น้องที่หาได้จากขั้นตอนก่อนหน้านี้นะ ตัวนี้!
var url = "http://192.168.1.154";
//Called when application is started.
function OnStart()
{
//Create a layout with objects vertically centered.
lay = app.CreateLayout( "linear", "VCenter,FillXY" );
app.AddLayout( lay );
//Create a button to send request.
btn = app.CreateButton( "State", 0.3, 0.1 );
btn.SetMargins( 0, 0.05, 0, 0 );
btn.SetOnTouch( btn_OnTouch );
lay.AddChild( btn );
//Create a button to send request.
btnON = app.CreateButton( "Relay ON", 0.3, 0.1 );
btnON.SetMargins( 0, 0.05, 0, 0 );
btnON.SetOnTouch( btnON_OnTouch );
lay.AddChild( btnON );
//Create a button to send request.
btnOFF = app.CreateButton( "Relay OFF", 0.3, 0.1 );
btnOFF.SetMargins( 0, 0.05, 0, 0 );
btnOFF.SetOnTouch( btnOFF_OnTouch );
lay.AddChild( btnOFF );
}
function btn_OnTouch()
{
//Send request to remote server.
var path = "/relay";
//var params = "data=" + data.replace("\\r","");
app.HttpRequest( "get", url, path, "", HandleReply );
}
function btnON_OnTouch()
{
//Send request to remote server.
var path = "/relay/on";
//var params = "data=" + data.replace("\\r","");
app.HttpRequest( "get", url, path, "", HandleReply );
}
function btnOFF_OnTouch()
{
//Send request to remote server.
var path = "/relay/off";
//var params = "data=" + data.replace("\\r","");
app.HttpRequest( "get", url, path, "", HandleReply );
}
//Handle the servers reply.
function HandleReply( error, response )
{
console.log(error);
app.ShowPopup(response);
}

ขั้นตอนที่ 5: ต่อ Relay Module เข้ากับ ESP32
ต่อสาย Relay Module เข้ากับ ESP32 ตามนี้เลยจ้า:
GND---GND
VCC---5V
IN1---IO23
ถ้าอยากได้อิสระหน่อย ก็ถอด ESP32 ออกจากคอมแล้วใช้แบตเตอรี่จ่ายไฟให้มันแทนได้นะ วัยรุ่น

ขั้นตอนที่ 6: ทดสอบซะ!
รันแอพโดยกดปุ่ม Play แล้วทดสอบโดยกดปุ่มต่างๆ ถ้าทำทุกอย่างถูกต้อง น้องจะสามารถเปิด-ปิดรีเลย์ด้วยปุ่มเหล่านี้ และตรวจสอบสถานะของรีเลย์ได้ด้วยปุ่ม State ถ้าสื่อสารสำเร็จ แอพจะแสดง Popup ขึ้นมาว่า “ok” หรือแสดงสถานะของรีเลย์ (ตัวเลขที่ได้กลับมาคือ 1 สำหรับขาสูง และ 0 สำหรับขาต่ำ โดยรีเลย์จะทำงานเมื่อขาควบคุมถูกดึงให้เป็นต่ำ) อย่าช็อตนะตัวนี้!



รายละเอียดทางเทคนิคแบบจัดเต็ม
สะพานเชื่อมฮาร์ดแวร์ข้ามแพลตฟอร์มมือถือ
โปรเจกต์นี้จะโชว์ให้น้องเห็นวิธีสร้างแอป Android แบบ Custom ที่คุยกันตรงๆ กับไมโครคอนโทรลเลอร์ ESP32 ผ่านเครือข่ายท้องถิ่นหรือเครือข่ายระยะไกลเลย
- DroidScript GUI Orchestration: ใช้เฟรมเวิร์ก DroidScript บน Android ในการสร้าง UI บนมือถือแบบไวๆ แอปจะส่งคำขอ HTTP GET ไปยังเว็บเซิร์ฟเวอร์ภายในของ ESP32
- Asynchronous Command Hub: ESP32 จะรันเว็บเซิร์ฟเวอร์แบบอะซิงโครนัสโดยใช้ไลบรารี ESPAsyncWebServer ทำให้มันจัดการคำขอเว็บที่เข้ามาได้โดยอิสระจากลูปหลัก (main loop) รับประกันว่าฮาร์ดแวร์ยังคงตอบสนองได้ดีแม้จะมีทราฟฟิกเครือข่ายเข้ามา เซิร์ฟเวอร์จะจัดการกับ endpoint ต่างๆ (เช่น
/relay/on,/relay/off) เพื่อควบคุมขา GPIO ที่ต่อกับรีเลย์
ประสิทธิภาพ
- Lightweight Communication: ระบบใช้คำขอ HTTP GET แบบง่ายๆ และการตอบกลับเป็นข้อความธรรมดา (เช่น "ok" หรือ "1"/"0") เพื่อให้มี overhead น้อยที่สุดและสื่อสารได้เร็ว สำหรับโปรเจกต์ที่ซับซ้อนขึ้นที่มีเซ็นเซอร์หลายตัว สามารถจัดรูปแบบข้อมูลเป็นสตริง JSON แบบเบาๆ ได้ ทำให้แอป Android แยกวิเคราะห์และแสดงผลการอ่านค่าหลายๆ ตัวในการส่งข้อมูลครั้งเดียวได้ง่ายๆ