ESP32-S3 เป็นชิพไมโครคอนโทรลเลอร์ (microcontroller) รองรับการเชื่อมต่อ WiFi และบลูทูธ พัฒนาโดย Espressif Systems เป็นรุ่นที่อัพเกรดจาก ESP32 เพิ่มความสามารถทางด้านการประมวลผล (CPU) เพิ่มหน่วยประมวลผล AI การจัดการหน่วยความจำดีขึ้น อัพเกรดเวอร์ชั่นของบลูทูธจาก 4.2 เป็น 5 และเพิ่มขาต่อใช้งานจาก 38 เป็น 42 ขา
ATD1.47-S3 ออกแบบและพัฒนาโดย ArtronShop เป็นบอร์ดที่รวมเอา ESP32-S3, จอแสดงผล TFT ขนาด 1.47 นิ้ว, สวิตช์, วงจรชาร์จแบตเตอรี่ และวงจรอัพโหลดโปรแกรม ไว้ในบอร์ดเดียว รองรับการต่ออุปกรณ์ I2C ผ่าน Grove อัพโหลดโปรแกรมลงบอร์ดผ่าน USB-C เขียนโปรแกรมด้วย Arduino IDE, PlatformIO และ Espressif-IDE
ด้วยพลังของ ESP32-S3 ทำให้ ATD1.47-S3 เชื่อมต่อ WiFi และบลูทูธได้ สร้างโปรเจค IoT ที่แสดงสถานะบนหน้าจอได้อย่างง่ายดาย เช่น เครื่องวัดค่าอุณหภูมิและความชื้น IoT แบบมีจอแสดงผลค่าที่วัดได้, เครื่องบอกมูลค่าเหรียญบิทคอยน์, เครื่องบอกอารมณ์ของต้นไม้, เครื่องนับก้าวเดิน, นาฬิกาจับเวลา, GPS เป็นต้น
ด้านบนประกอบด้วย หน้าจอแสดงผล และสวิตช์กดติด-ปล่อยดับ เขียนโปรแกรมสั่งงานได้อิสระ
รูปที่ 1 ส่วนประกอบของ ATD1.47-S3 ด้านบน
ด้านล่างประกอบด้วย โมดูล ESP32-S3-WROOM-1U-N8R8 ต่อเสาอากาศ WiFi และบลูทูธภายนอกผ่าน IPEX (ในชุดมีเสาอากาศให้), วงจรชาร์จและสลับไฟแบตเตอรี่ (เมื่อไม่มีไฟเลี้ยง จะใช้ไฟจากแบตเตอรี่อัตโนมัติ), วงจรอัพโหลดโปรแกรมผ่าน USB-C, จุดต่ออุปกรณ์ I2C ผ่านคอนเนคเตอร์ Grove, จุดต่อแบตเตอรี่ และไฟสถานะได้รับไฟเลี้ยง (ไฟ Power)
รูปที่ 2 ส่วนประกอบของ ATD1.47-S3 ด้านล่าง
วงจรภายในของ ATD1.47-S3 มีการเชื่อมต่อกันดังนี้
รูปที่ 3 แผนภาพการเชื่อมต่อภายใน (internal wiring) ของ ATD1.47-S3
หากใช้ไลบรารี่ ATD1.47-S3 ของบอร์ด ไม่จำเป็นต้องทราบวงจรภายในก็ได้
Pinout ของ ATD1.47-S3 แสดงดังรูปที่ 4
รูปที่ 4 Pinout ของ ATD1.47-S3
มีรายละเอียดขาต่อใช้งานดังนี้
ติดตั้งโปรแกรม Arduino IDE แล้วติดตั้งบอร์ด ESP32 เพิ่ม ตามบทความ การติดตั้ง และใช้งาน Arduino IDE V2
เปิดโปรแกรม Arduino IDE ขึ้นมา เปิดโปรแกรมตัวอย่างอ่านค่าสวิตช์โดยกดที่ File > Examples > 01.Basics เลือก DigitalReadSerial
แก้ไขโค้ดโปรแกรมบรรทัดที่ 12 ให้เป็นขาที่ต่ออยู่กับสวิตช์ หากดูจาก โครงสร้างภายใน ATD1.47-S3 จะเห็นว่าสวิตช์ A ต่ออยู่กับขา IO4 สวิตช์ B ต่ออยู่ขา IO5 และสวิตช์ C ต่ออยู่ขา IO45 ตัวอย่างเลือกอ่านค่าจากสวิตช์ A จึงแก้ไขเลข 2 เป็นเลข 4 แทน
เสียบบอร์ด ATD1.47-S3 เข้ากับเครื่องคอมพิวเตอร์ ด้วยสาย USB-C จากนั้นเลือกบอร์ดเป็น ATD1.47-S3 และเลือกพอร์ต
หมายเหตุ. หากไม่มีบอร์ด ATD1.47-S3 ให้เลือก ให้เลือกเป็น ESP32-S3 Dev Module แทน
กดอัพโหลดโปรแกรม แล้วรอจนกว่าจะมีข้อความ Done uploading ขึ้น
เปิด Serial Monitor ขึ้นมา ปรับเป็น 9600 baud จะเห็นเลข 1 แสดงขึ้นมารัว ๆ
เมื่อกดสวิตช์ A ค้างไว้ จะมีเลข 0 ขึ้นมาแทน
หมายเหตุ. สวิตช์ A, B, C ต่อแบบ Pull-up / Active Low หมายถึงตอนกดสวิตช์อ่านได้ลอจิก 0 ตอนไม่กดอ่านได้ 1
ATD1.47-S3 Lib เป็นไลบรารี่ที่ ArtronShop พัฒนาขึ้นเพื่อให้เขียนโปรแกรมสั่งงานบอร์ด ATD1.47-S3 ได้สะดวกมากยิ่งขึ้น โดยมีคำสั่งใช้งานจอเบื้องต้น เช่น วาดเส้น วาดสี่เหลี่ยม วาดสามเหลี่ยม วงกลม เชื่อมกับ LVGL และสวิตช์ให้
ติดตั้งไลบรารี่ ATD1.47-S3 Lib ตามขั้นตอนดังนี้
1) กดไอคอนรูปหนังสือที่มุมซ้าย แล้วพิมพ์ชื่อไลบรารี่ ATD1.47-S3 Lib ลงในช่องค้นหา จากนั้นกดปุ่ม INSTALL แล้วรอจนกว่าจะติดตั้งเสร็จ
2) เมื่อติดตั้งไลบรารี่เสร็จ จะมีข้อความ Successfully installed library (ดังรูป)
การเขียนโปรแกรมสังงานจอ LCD เริ่มต้นด้วยการ include ไลบรารี่ ATD1.47-S3 Lib เข้ามา
#include <ATD1.47-S3.h>
แล้วใช้คำสั่ง Display.begin(); ใน void setup() เพื่อสั่งให้หน้าจอเริ่มทำงาน
Display.begin();
เท่านี้ก็พร้อมเขียนโปรแกรมสั่งงานจอแล้ว
ระบบสีที่ใช้บนเครื่องคอมพิวเตอร์เป็นแบบ 24 บิต RGB888 แต่ที่ใช้บนจอ TFT และไลบรารี่ ATD1.47-S3 Lib ใช้ระบบสี RGB565 ... การแปลงสี RGB888 เป็น RGB565 สามารถทำได้โดยใช้คำสั่ง Display.color565() หรือ Display.color24to16() มีรูปแบบคำสั่งดังนี้
ตัวอย่าง 1 วาดเส้นที่ตำแหน่งเริ่มต้น (10, 10) ไปที่ตำแหน่ง (40, 40) กำหนดเส้นสีแดง (0xFF0000) เขียนโปรแกรมได้ดังนี้
Display.drawLine(10, 10, 40, 40, Display.color24to16(0xFF0000)); // int32_t xs, int32_t ys, int32_t xe, int32_t ye, uint32_t color
ตัวอย่าง 2 วาดเส้นที่ตำแหน่งเริ่มต้น (50, 20) ไปที่ตำแหน่ง (100, 180) กำหนดเส้นสีเขียว (0x00FF00) เขียนโปรแกรมได้ดังนี้
Display.drawLine(50, 20, 100, 180, Display.color24to16(0x00FF00)); // int32_t xs, int32_t ys, int32_t xe, int32_t ye, uint32_t color
ใช้คำสั่ง tft.fillScreen() มีรูปแบบคำสั่งดังนี้
void Display.fillScreen(uint32_t color);
ตัวอย่าง เทสีทั้งหน้าจอด้วยสีดำ
tft.fillScreen(tft.color24to16(0x000000));
การวาดเส้นตรงมีคำสั่งให้ใช้งานดังนี้
void Display.drawLine(int32_t xs, int32_t ys, int32_t xe, int32_t ye, uint32_t color); // ใช้วาดเส้นตรงแนวตั้ง แนวนอน และแบบเอียง
ตัวอย่าง วาดเส้นตรงที่ตำแหน่งเริ่มต้น (0, 0) ไปตำแหน่ง (140, 20) กำหนดเส้นสีขาว (0xFFFFFF) เขียนโปรแกรมได้ดังนี้
tft.drawLine(0, 0, 140, 20, tft.color24to16(0xFFFFFF));
การวาดสี่เหลี่ยมมีคำสั่งให้ใช้งานดังนี้
ตัวอย่างที่ 1 วาดกรอบสี่เหลี่ยมที่จุดเริ่มต้น (30, 30) ขนาด 40 x 60 พิกเซล สีน้ำเงิน เขียนโปรแกรมได้ดังนี้
Display.drawRect(30, 30, 40, 60, Display.color24to16(0x0000FF));
ตัวอย่างที่ 2 วาดกล่องสี่เหลี่ยมทึบแสงที่จุดเริ่มต้น (20, 60) ขนาด 100 x 100 พิกเซล สีขาว เขียนโปรแกรมได้ดังนี้
Display.fillRect(30, 30, 40, 60, Display.color24to16(0xFFFFFF));
ตัวอย่างที่ 3 วาดกรอบสี่เหลี่ยมขอบโค้งที่จุดเริ่มต้น (30, 30) ขนาด 40 x 60 พิกเซล ขอบโค้ง 20 พิกเซล สีน้ำเงิน เขียนโปรแกรมได้ดังนี้
Display.drawRoundRect(30, 30, 40, 60, 20, Display.color24to16(0x0000FF));
การวาดวงกลมมีคำสั่งให้ใช้งานดังนี้
ตัวอย่างที่ 1 วาดวงกลมโปร่งแสงจุดศูนย์กลางอยู่ที่ตำแหน่ง (150, 150) รัศมี 80 สีขาว เขียนโปรแกรมได้ดังนี้
Display.drawCircle(150, 150, 80, Display.color24to16(0xFFFFFF));
ตัวอย่างที่ 2 วาดวงกลมทึบแสงจุดศูนย์กลางอยู่ที่ตำแหน่ง (160, 100) รัศมี 40 สีขาว เขียนโปรแกรมได้ดังนี้
Display.fillCircle(160, 100, 40, Display.color24to16(0xFFFFFF));
ตัวอย่างโค้ดโปรแกรมวาดรูปบนหน้าจอฉบับเต็ม
ผลที่ได้เป็นดังนี้
LVGL (Light and Versatile Graphics Library) เป็นโครงการ Open Source สำหรับการพัฒนาแอปพลิเคชันและอินเตอร์เฟซผู้ใช้ (UI) บนไมโครคอนโทรลเลอร์ ถูกออกแบบมาเพื่อให้มีขนาดเล็กและประสิทธิภาพสูง ทำให้เหมาะสำหรับการใช้งานในอุปกรณ์ที่มีทรัพยากรที่จำกัด ใช้สร้างโปรเจคได้หลากหลาย เช่น นาฬิกาอัจฉริยะ, หน้าจอ HMI ควบคุมเครื่องจักร, หน้าจอควบคุมระบบภายในบ้าน, รีโมทควบคุมระบบ Smart Home, หน้าจอเครื่องวัดพลังงานไฟฟ้า, หน้าจอเครื่องพิมพ์ 3 มิติ เป็นต้น
LVGL ออกแบบให้การเขียนโค้ดสร้าง UI ใช้แนวคิดคล้าย HTML + CSS ทำให้สามารถสร้าง UI ได้ง่ายและแสดงผลได้อย่างสวยงาม รองรับการแสดงผลหน้าจอในรูปแบบที่หลากหลาย ทั้งหน้าจอแบบสีเดียว (จอขาว-ดำ) เช่น OLED, LCD และจอสี เช่น TFT LCD, RGB LED Panel สามารถใช้งานได้กับหลายแพลตฟอร์มไมโครคอนโทรลเลอร์ เป็นที่นิยมในวงการพัฒนาซอฟต์แวร์ฝังตัว โดยปัจจุบันถือเป็นโครงการที่มียอด Star ใน GitHub อันดับต้น ๆ ในหมวดซอฟต์แวร์ฝังตัว
ไลบรารี่ ATD1.47-S3 Lib อำนวยความสะดวกในการใช้งาน ATD1.47-S3 ร่วมกับ LVGL โดยมีคำสั่งที่ใช้ตั้งค่าให้ LVGL พร้อมใช้งานเพียงเรียกคำสั่งเดียว ช่วยให้โค้ดสะอาดตามากขึ้น ลดขั้นตอนและระยะเวลาที่ใช้ในการพัฒนาลง
ตัวอย่างการใช้งานร่วมกับ LVGL มีขั้นตอนดังนี้
1) ติดตั้งไลบรารี่ LVGL กดไอคอนรูปหนังสือที่มุมซ้าย แล้วพิมพ์ชื่อไลบรารี่ lvgl ลงในช่องค้นหา จากนั้นกดปุ่ม INSTALL แล้วรอจนกว่าจะติดตั้งเสร็จ
2) เมื่อติดตั้งไลบรารี่เสร็จ จะมีข้อความ Successfully installed library (ดังรูป)
3) เข้าไปในโฟลเดอร์ไลบรารี่ ATD1.47-S3 Lib ซึ่งโดยปกติจะอยู่ที่ My Documents\Arduino\libraries\ATD1.47-S3-Lib แล้วเข้าไปที่โฟลเดอร์ extras จากนั้นคัดลอกไฟล์ lv_conf.h ไปวางไว้ที่ My Documents\Arduino\libraries
4) ที่โปรแกรม Arduino IDE เปิดโค้ดโปรแกรมตัวอย่าง with-LVGL
5) เลือกบอร์ด เลือกพอร์ต แล้วกดอัพโหลดโปรแกรม
6) เมื่ออัพโหลดโปรแกรมเสร็จ หน้าจอของ ATD1.47-S3 จะแสดงข้อความ Hello, LVGL work ! (ดังรูป)
โค้ดโปรแกรมตัวอย่าง มีหลักการทำงานดังนี้
ศึกษาการใช้งาน LVGL เพิ่มเติมได้ที่ lvgl.io
ไลบรารี่ ATD1.47-S3 Lib ออกแบบให้เขียนโปรแกรมใช้งานสวิตช์แบบ Event-driven คือเมื่อเกิดเหตุการณ์ที่กำหนดขึ้น ก็จะให้โปรแกรมส่วนที่กำหนดทำงาน เช่น เมื่อกดสวิตช์ ให้นับเลข เป็นต้น โดยไลบรารี่รองรับเหตุการณ์ กดปุ่ม (on pressed) และปล่อยปุ่ม (on release) ของปุ่ม A, B และ C โดยมีรายละเอียดคำสั่งดังนี้
เริ่มต้นใช้งานสวิตช์ คำสั่งต้องอยู่ใน void setup() มีรูปแบบดังนี้
void Switch.begin();
เรียกใช้คำสั่งเบื้องหลังของไลบรารี่ เพื่อให้การอ่านค่ากดสวิตช์ ปล่อยสวิตช์ เป็นไปอย่างปกติ คำสั่งต้องอยู่ใน void loop() มีรูปแบบดังนี้
void Switch.loop();
ใช้กำหนดโค้ดที่จะถูกเรียกเมื่อกดปุ่มที่กำหนด มีรูปแบบดังนี้
void Switch.onPressed(SwitchNum sw, callback);
มีพารามิเตอร์ดังนี้
ตัวอย่าง 1 เมื่อกดปุ่ม A ให้แสดงข้อความ Hello ! ที่ Serial Monitor
Switch.onPressed(A, []() { // เมื่อกดปุ่ม A
Serial.println("Hello !"); // แสดงข้อความ Hello ! ที่ Serial Monitor
});
ตัวอย่าง 2 เมื่อกดปุ่ม B ให้แสดงข้อความ Hello ! ที่ Serial Monitor
Switch.onPressed(B, []() { // เมื่อกดปุ่ม B
Serial.println("Hello !"); // แสดงข้อความ Hello ! ที่ Serial Monitor
});
ตัวอย่าง 3 เมื่อกดปุ่ม C ให้แสดงข้อความ Hello ! ที่ Serial Monitor
Switch.onPressed(C, []() { // เมื่อกดปุ่ม C
Serial.println("Hello !"); // แสดงข้อความ Hello ! ที่ Serial Monitor
});
ใช้กำหนดโค้ดที่จะถูกเรียกเมื่อปล่อยปุ่มที่กำหนด มีรูปแบบดังนี้
void Switch.onRelease(SwitchNum sw, callback);
มีพารามิเตอร์ดังนี้
ตัวอย่าง เมื่อปล่อยปุ่ม A ให้แสดงข้อความ Release A ! ที่ Serial Monitor
Switch.onRelease(A, []() { // เมื่อปล่อยปุ่ม A
Serial.println("Release A !"); // แสดงข้อความ Release A ! ที่ Serial Monitor
});
ใช้กำหนดโค้ดที่จะถูกเรียกเมื่อปล่อยปุ่มที่กำหนด มีรูปแบบดังนี้
bool Switch.isPressed(SwitchNum sw);
มีพารามิเตอร์ดังนี้
ใช้กำหนดโค้ดที่จะถูกเรียกเมื่อปล่อยปุ่มที่กำหนด มีรูปแบบดังนี้
bool Switch.isRelease(SwitchNum sw);
มีพารามิเตอร์ดังนี้
ตัวอย่างที่ 1 กดปุ่ม A วาดวงกลมสีแดง ที่ตำแหน่งกลางจอ กดปุ่ม B วาดวงกลมสีเขียว กดปุ่ม C ล้างหน้าจอด้วยการเทสีดำ
ผลที่ได้ เมื่อกดปุ่ม A หน้าจอแสดงกลมสีแดง กดปุ่ม B หน้าจอแสดงวงกลมสีเขียว กดปุ่ม C ล้างหน้าจอ
ตัวอย่างที่ 2 ใช้งานร่วมกับ LVGL นับจำนวนครั้งการกดสวิตช์ A และรีเซ็ตค่าเมื่อกดสวิตช์ B
ผลที่ได้ เมื่อกด A ค่า count บนหน้าจอขึ้นเลขตามการกดสวิตช์ เมื่อกดสวิตช์ B ค่า count กลับเป็น 0