สวัสดีครับ วันนี้ผมจะมารีวิวหน้าจอแอลซีดีสัมผัส (LCD touch display) ของ Elecrow ครับ ซึ่งหน้าจอนี้ก็จัดเป็นกลุ่มของ HMI (human machine interface) ที่เป็นอุปกรณ์แสดงผลแบบสัมผัสที่ช่วยให้เราสื่อสารหรือโต้ตอบกับเครื่องจักรได้มีประสิทธิภาพมากขึ้น โดยทาง Elecrow ก็ผลิตหน้าจอแอลซีดีกลุ่มนี้ออกมาหลายขนาด ตั้งแต่ 2.4 นิ้วไปจนถึง 7.0 นิ้วครับ โดยการรีวิวนี้ Elecrow มอบมอดูลหน้าจอขนาด 3.5 นิ้วและ 7.0 นิ้ว มาให้ใช้รีวิว มอดูลทั้งสองตัวนี้มีองค์ประกอบที่สำคัญทั่วไปคล้ายกัน คือทั้งสองตัวใช้ ESP32 เป็นไมโครคอนโทรเลอร์หลักเหมือนกัน
สำหรับมอดูลหน้าจอขนาด 7.0 นิ้วนั้นใช้ ESP32-S3-WROOM-1-N4R8 ซึ่งเป็นไมโครโพเรเซสเซอร์ LX6 32 บิตแบบ dual-core, มี flash ขนาด 4 เมกะไบต์, มี ROM ขนาด 384 กิโลไบต์ และมี SRAM ขนาด 512 กิโลไบต์ รองรับการทำงานไร้สายทั้งแบบ WiFi และ Bluetooth ในส่วนของหน้าจอขนาด 7.0 นิ้วนั้นเป็นหน้าจอสัมผัสแบบ capacitive มีความละเอียด 800×480 พิกเซล และใช้ไดร์เวอร์ EK9716BD3/EK73002ACGB ควบคุมการทำงาน และรองรับการใช้งานร่วมกับ LVGL
ในส่วนของตัวหน้าจอขนาด 3.5 นิ้วนั้นมีจุดแตกต่างหลัก ๆ คือใช้ไมโครโพรเซสเซอร์ ESP32-WROOM-32-N4 ซึ่งเป็น LX6 แบบ dual-core และมี SRAM ขนาด 520 กิโลไบต์ (มากกว่าตัวหน้าจอ 7 นิ้วเล็กน้อย) ตัวหน้าจอเป็นจอแอลซีดีแบบ resistive ความละเอียด 320×480 พิกเซล และใช้ไดร์เวอร์ ILI9488
ตัวอุปกรณ์นั้นรองรับการพัฒนาโปรแกรมผ่าน IDE หลายตัว เช่น Arduino IDE, Espressif IDF, Platform IO และ MicroPython นอกจากนั้นอุปกรณ์ทั้งสองตัวยังมี connector แบบ I2C และขา GPIO ให้เราใช้งานได้อย่างละ 1 ชุด ส่วนจำนวนการเชื่อมต่อแบบ UART และรายละเอียดเพิ่มเติมอื่น ๆ ดูได้จากตารางสรุปของผู้ผลิตด้านล่างนี้ครับ
เปิดกล่องและทดสอบการใช้งาน
ตัวอย่างสินค้าที่ส่งมาให้ผมนั้นบรรจุมาในกล่องกระดาษลูกฟูก ส่งมาจากประเทศจีน เมื่อเปิดกล่องก็พบ bubble wrap กันกระแทกซึ่งเมื่อดูภายในก็พบว่าตัวหน้าจอแต่ละชุดนั้นถูกบรรจุแยกกันอยู่ในกล่องกระดาษลูกฟูกของตัวเองอีกชั้นหนึ่ง ขนาดของกล่องทั้งสองชั้นรวมทั้ง bubble wrap นั้นมีความพอดี อุปกรณ์ไม่เคลื่อนที่ไปมามากนัก เวลาจับแล้วรู้สึกว่าแข็งแรงดี เมื่อเปิดกล่องออกมาดูหน้าจอแต่ละตัวก็พบว่าตัว PCB ใช้ solder mask สีแดง และใช้ slikscreen สีขาว การประกอบอุปกรณ์ลง PCB นั้นทำได้สะอาดเรียบร้อย
สำหรับภายในกล่องของหน้าจอขนาด 7 นิ้วนั้นประกอบด้วยตัวหน้าจอหนึ่งชุด และสาย Crowtail/Grove to 4-pin DuPont กับสาย USB Type-C อย่างละหนึ่งเส้น นอกจากนั้นผู้ผลิตยังมีเคสหรือกล่องสำหรับใส่หน้าจอที่ทำจากแผ่นอคริลิคความหนา 6 มิลลิเมตรมาให้ด้วย ซึ่งในกรณีผมนั้นผู้ผลิตได้ประกอบมอดูลหน้าจอเข้ากับเคสอคริลิคและขันสกรูเรียบร้อยแล้ว
ส่วนภายในกล่องของมอดูลหน้าจอขนาด 3.5 นิ้วนั้นประกอบด้วยตัวหน้าจอหนึ่งชุด, ปากกาสำหรับใช้งานกับหน้าจอหนึ่งด้าม, และสาย Crowtail/Grove to 4-pin DuPont cable กับสาย USB Type-C อย่างละหนึ่งเส้น แต่สำหรับชุดนี้ผู้ผลิตก็มีเคสอคริลิคมาให้เพียงแต่ยังไม่ได้ประกอบ ซึ่งเมื่อประกอบเข้าด้วยกันแล้วก็ให้ความรู้สึกคล้ายกัน คือ รู้สึกแข็งแรงและมีความหนากำลังดี
ผมทดสอบใช้งานครั้งแรกด้วยการเชื่อมต่อกับคอมพิวเตอร์ด้วยการใช้สาย USB Type-C ที่ผู้ผลิตให้มาเสียบเข้าทางพอร์ต USB บนบอร์ด เมื่ออุปกรณ์เริ่มต้นทำงานก็พบกับหน้าจอหลักซึ่งเป็น factory demo code ชุดเดียวกันทั้งสองจอ เหมือนที่แสดงใน website และ Youtube ของผู้ผลิต จากนั้นผมจึงทดลองการสัมผัส UI elements ต่าง ๆ บนหน้าจอด้วยปลายนิ้วและปากกาที่ให้มา โดยรวมพบว่าทำงานได้ปกติ แต่อาจจะไม่ได้ลื่นหรือตอบสนองเร็วเหมือนตัวอย่างในวิดีโอ ส่วนเรื่องของความคมชัดและความสดใสของสีที่เห็นนั้นก็อยู่ในระดับปกติของหน้าจอประเภทนี้ สำหรับขอบเขตของมุมมองก็จำกัดตามคุณลักษณะของจอภาพแบบ TN ซึ่งอาจจะเทียบกับจอภาพแบบ IPS ไม่ได้ แต่ก็ยังคงมีความเหมาะสมกับการใช้งานได้หลายประเภท
ทดลองแฟลช Factory Demo Program ด้วย Arduino IDE
ตัวอุปกรณ์นั้นรองรับการพัฒนาโปรแกรมผ่าน IDE หลายตัว แต่ในการรีวิวนี้ผมจะทดสอบการทำงานด้วย Arduino IDE โดยผู้ผลิตมีตัวอย่างอธิบายขั้นตอนการติดตั้ง library ที่จำเป็นให้อยู่ในเว็บไซต์และมีวิดีโอแสดงตัวอย่างบน YouTube ด้วย เพียงแต่ในช่วงแรกนั้นผมค่อนข้างสับสนว่าจะหาโค๊ดตัวอย่างหรือรายละเอียดของ library ที่จำเป็นจากที่ไหน เนื่องจากข้อมูลที่แสดงในเว็บไซต์กับตัวอย่างวิดีโอที่มีใน YouTube นั้นมีหลายจุดที่แตกต่างกัน แต่หลังจากใช้เวลาสักครู่จึงพบว่าข้อมูลต่าง ๆ ที่จำเป็นสำหรับการแฟลชโปรแกรมนั้นดูจาก WiKi จะมีข้อมูลเยอะกว่าและทำตามได้ง่ายดี โดยหน้าจอขนาด 7.0 นิ้วนั้นดูจากได้ลิงค์นี้ ส่วนหน้าจอขนาด 3.5 นิ้วนั้นดูได้จากลิงค์นี้ หรืออาจจะใช้โค๊ดจาก GitHub ของผู้ผลิตจากลิงค์นี้ (7.0 นิ้ว, 3.5 นิ้ว) เลยก็ได้ครับ
ในคู่มือการติดตั้งไม่ได้กำหนดเวอร์ชันของ Arduino IDE เอาไว้ ส่วนในเว็บไซต์และในวิดีโอที่แสดงใน YouTube นั้นยกตัวอย่างด้วยการใช้ Arduino IDE เวอร์ชัน 1.8.19 แต่การรีวิวนี้ผมอยากจะทดลองว่าถ้าใช้ Arduino IDE เวอร์ชันใหม่จะมีปัญหาอะไรหรือไม่ ดังนั้นผมจึงเลือกที่จะใช้การติดตั้ง Arduino IDE เวอร์ชันล่าสุด โดยตอนเขียนรีวิวนี้จะเป็นเวอร์ชัน 2.2.1 ครับ
หลังจากเตรียม IDE แล้ว ผมจึงไปดาวน์โหลดโค๊ดที่จำเป็นตามคำแนะนำในเว็บไซต์ของผู้ผลิต ซึ่งโดยสรุปคือเราสามารถใช้ไฟล์ Arduino_35.zip
จากลิงค์นี้สำหรับหน้าจอ 3.5 นิ้ว และไฟล์ Arduino_7inch.zip
จากลิงค์นี้สำหรับหน้าจอ 7.0 นิ้ว
สำหรับการกำหนดค่าอื่น ๆ ใน Arduino IDE นั้น ผู้ผลิตแนะนำให้เรากำหนด URL ของ Additional Board Manage
r ให้เป็น https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
จากนั้นจึงติดตั้ง ESP32 Board โดยผู้ผลิตแนะนำให้เลือกบอร์ด ESP32 เวอร์ชัน 2.0.3 ส่วนการกำหนดค่าอื่น ๆ ที่จำเป็นของแต่ละบอร์ดก็ขอสรุปไว้ตามข้อมูลด้านล่างนี้ครับ
- มอดูลหน้าจอ 7 นิ้ว
- Board: ESP32S3 Dev MODULE
- Flash Mode: QIM 80MHz
- Flash Size: 4MB (32Mb)
- Partition Scheme: Huge APP (3MB No OTA/1MB SPIFFS)
- PSRAM: OPI PSRAM
- มอดูลหน้าจอ 3.5 นิ้ว
- Board: ESP32S3-WROOM-DA MODULE
- Flash Mode: QIM 80MHz
- Flash Size: 4MB (32Mb)
- Partition Scheme: Huge APP (3MB No OTA/1MB SPIFFS)
เตรียมโค๊ดโปรแกรมให้มอดูลหน้าจอ 7 นิ้ว
รายละเอียดของการแฟลชโปรแกรมให้มอดูลหน้าจอ 7 นิ้วด้วย Arduino IDE นั้นดูได้จากลิงค์นี้และวิดีโอนี้ ซึ่งโดยสรุปคือหลังจากดาวน์โหลดไฟล์ Arduino_7inch.zip
เรียบร้อยแล้ว เราจะต้องติดตั้ง library ที่จำเป็นด้วยตนเองด้วยการคัดลอกไฟล์ทั้งหมดในโฟล์เดอร์ libraries ภายใน Arduino_7inch
ไปไว้ในพาธ libraries ของ Arduino IDE เอง ถ้าหากเรากังวลว่า libraries เหล่านี้จะซ้ำซ้อนหรือมีปัญหากับ libraries เดิมที่มีอยู่แล้ว เราก็อาจจะไปกำหนดพาธของ libraries นี้ที่อื่นก็ได้ครับ โดยให้เราเปิดเมนู File
/Preferences
แล้วตั้งค่า Sketchbook location
ให้เป็นพาธที่เราต้องการ โดยในการรีวิวครั้งนี้ผมกำหนดค่า libraries ของการทดสอบแฟลชโปรแกรมลงหน้าจอทั้งสองแบบเป็นคนละโฟล์เดอร์กันครับ
จากนั้นผมเปิดไฟล์ HMI-7.ino แล้วทดลองเพิ่มคำสั่ง Serial.println(“Yes!”);
ที่บรรทัดสุดท้ายของฟังก์ชัน setup()
เพื่อใช้ตรวจสอบว่ารันแล้วเป็นโค๊ดใหม่จริง ๆ จากนั้นจึงพยายามคอมไพล์ให้ผ่าน ปัญหาพื้นฐานที่พบอย่างแรกคือยังขาด Arduino GFX library
จึงติดตั้งเวอร์ชัน 1.3.1 เพิ่มแล้วลองใหม่ การ compile ใช้เวลาซักครู่ จากที่สังเกตุพบว่าอาจจะมี warning ปรากฏบ้าง แต่ก็สามารถ compile ได้โดยไม่พบปัญหาอะไรอีก
เตรียมโค๊ดโปรแกรมให้มอดูลหน้าจอ 3.5 นิ้ว
การแฟลชโปรแกรมตัวอย่าง Factory Demo Code ให้กับบอร์ดนี้คล้ายกับตัวอย่างข้างบน โดยเราต้องนำ library ของบอร์ดนี้ไปวางใน libraries ของ Arduino เอง รวมถึงเราจะต้องแทนที่ไฟล์ User_Setup.
h ของ TFT_eSPI
ด้วยไฟล์ใน firmware ที่ download มา เพื่อให้การตั้งค่าต่าง ๆ ของ TFT_eSPI
นั้นตรงกับอุปกรณ์ของเรา โดยดูรายละเอียดเพิ่มเติมได้จากลิงค์นี้และวิดีโอนี้ครับ
ในส่วนของโปรแกรมหลักนั้นจะใช้ไฟล์ LVGL_Arduino3.5RTP-Hor.ino จาก 3.5-Factory-Program.zip\3.5-Factory-Program\LVGL_Arduino3.5RTP-Hor\
ซึ่งสามารถ compile ผ่านโดยไม่พบปัญหาเพิ่มเติม
Upload
การจะ upload ไปยังบอร์ดได้นั้นเราต้องทำให้บอร์ดอยู่ในโหมด download ก่อนครับ ซึ่งทำได้ด้วยการกดปุ่ม BOOT
บนบอร์ดค้างไว้ ตามด้วยปุ่ม RESET
สั้น ๆ หนึ่งครั้งแล้วปล่อย เสร็จแล้วค่อยปล่อยปุ่ม BOOT
ครับ ถ้าทำสำเร็จบอร์ดจะเข้าสู่โหมด download และหน้าจอจอเปลี่ยนเป็นสีดำ ซึ่งเราอาจจะเปิดหน้าต่าง Serial Monitor เพื่อตรวจสอบการเข้าสู่โหมด download นี้ด้วยก็ได้ครับ โดยบอร์ดจะแสดงข้อความ “waiting for download”
ถ้าเข้าสู่โหมด download ได้สำเร็จ
เมื่ออยู่ในโหมด download แล้วก็กดปุ่ม Upload
บน Arduino IDE เพื่อแฟลชโปรแกรมไปที่บอร์ด หลังจาก upload ไปบอร์ดเรียบร้อย แล้วให้เรากดปุ่ม RESET
บนบอร์ดอีกครั้งเพื่อรีสตาร์ท เราก็จะได้ใช้งานโปรแกรมชุดใหม่ตามที่เราต้องการ และบอร์ดที่ผมได้รับมานั้นมีรายละเอียดเกี่ยวกับบอร์ดระหว่างการ upload แสดงตามรายละเอียดด้านล่างนี้ครับ
- มอดูลหน้าจอ 7.0 นิ้ว
- Sketch uses 1707637 bytes (54%) of program storage space. Maximum is 3145728 bytes.
- Global variables use 94316 bytes (28%) of dynamic memory, leaving 233364 bytes for local variables. Maximum is 327680 bytes.
- Chip is ESP32-S3
- Features: WiFi, BLE
- Crystal is 40MHz
- มอดูลหน้าจอ 3.5 นิ้ว
- Sketch uses 2375949 bytes (75%) of program storage space. Maximum is 3145728 bytes.
- Global variables use 74536 bytes (22%) of dynamic memory, leaving 253144 bytes for local variables. Maximum is 327680 bytes.
- Chip is ESP32-D0WDQ6 (revision 1)
- Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
- Crystal is 40MHz
จากการตรวจสอบ code ของมอดูลหน้าจอ 3.5 นิ้ว ผมพบว่าโปรแกรม demo ตัวนี้มีโหมดทดสอบการทำงานให้เราทดลองเล่นด้วยครับ โดยให้เราพิมพ์ b
ที่ Serial Monitor แล้วเลือกโหมดที่ต้องการทดสอบตามข้อมูลด้านล่างนี้ ซึ่งโดยสรุปก็มีการทดสอบองค์ประกอบต่าง ๆ ของบอร์ด เช่น พิมพ์ตัว R
เพื่อทดสอบแสดงหน้าจอเป็นสีแดง, ทดสอบส่งสัญญาณทางขา GPIO, ทดสอบการสัมผัสหน้าจอ และการเชื่อมต่อ WiFi เป็นต้น ซึ่งแต่ละโหมดจะมีข้อความเพิ่มเติมให้อ่านผ่านทาง Serial Monitor ได้ และเราสามารถออกจากแต่ละโหมดด้วยการพิมพ์อักขระ i
(ตัวไอตัวพิมพ์เล็ก) ไปให้บอร์ดผ่านทาง Serial Monitor ครับ
- R : แสดงหน้าจอเป็นสีแดง
- G : แสดงหน้าจอเป็นสีเขียว
- B : แสดงหน้าจอเป็นสีน้ำเงิน
- S : ทดสอบการอ่านข้อมูล SD card
- T : ทดสอบการสัมผัสหน้าจอ
- L : ทดสอบการใช้งาน GPIO
- i : ทดสอบการใช้งาน I2C
- W : ทดสอบการใช้งาน WiFi
- U : ทดสอบการใช้งาน UART1
- P : ทดสอบการใช้งานลำโพง
- V : ทดสอบการใช้งาน Bluetooth
- C : ออกจากการทดสอบย่อยแต่ละแบบ แล้วกลับไปรอรับคำสั่งข้างบนใหม่
- I : ออกจากโหมดทดสอบ กลับไปหน้าจอปกติ
ตัวอย่างการประยุกต์ใช้งาน
สำหรับการทดลองเขียนโปรแกรมเพื่อใช้งานองค์ประกอบอื่น ๆ เช่น GPIO-D
, I2C
, TF
และ UART-1
นั้น ผมทดลองกับโค๊ดตัวอย่างของแต่ละบอร์ดแล้วพบว่าสามารถทำงานได้ตามปกติ ดังนั้นการรีวิวส่วนที่เหลือนี้ผมจะทดสอบการใช้งานด้วยการทำ mini-project เล็ก ๆ 2 เรื่อง โดยจะใช้ตัวมอดูลหน้าจอ 7.0 นิ้วเพื่อเป็น dashboard สำหรับการแสดงข้อมูลการตรวจวัดคุณภาพอากาศ และใช้มอดูลหน้าจอ 3.5 นิ้วเพื่อแสดงค่าที่ตรวจวัดได้จากมอดูลมัลติสเปกโทรมิเตอร์ (multispectrometer) ผ่านทางพอร์ต I2C แบบง่าย ๆ ตามรายละเอียดต่อไปนี้ครับ
มอดูลหน้าจอ 7.0 นิ้ว : Dashboard แสดงข้อมูลคุณภาพอากาศ
สำหรับข้อมูลคุณภาพอากาศที่จะนำมาแสดงผลนั้น ผมจะใช้ข้อมูลจาก AirGradient ONE ที่ผมได้รับมอบมาใช้ในการรีวิวครั้งที่ผ่านมาครับ โดยผมได้ปรับโค๊ดฝั่ง server นิดหน่อยแบบง่าย ๆ เพื่อให้รองรับการ request แบบ HTTP GET
เพื่อค้นหาข้อมูลการตรวจวัดล่าสุดแล้ว response กลับให้เป็นรูปแบบ JSON
โดยในการรีวิวนี้ผมออกแบบให้มีค่าที่ต้องการนำมาแสดงผลทั้งหมด 11 ค่า ตามรูปแบบ JSON
ด้านล่างนี้ครับ
{"result":"OK","data":[{"id":"32403","date_time":"2023-12-31 09:36:04","tvoc":"67","nox":"2","co2":"422","pm25":"20","pm01":"12","pm10":"20","pm03pcount":"2229","temp":"29.6","hum":"62"}]}
หลังจากนั้นผมจึงออกแบบ UI สำหรับแสดงผล โดยใช้ SquareLine Studio เวอร์ชัน 1.3.2 ซึ่งโปรแกรมตัวอย่างนี้ผมจะแบ่งหน้าจอออกเป็นสามส่วน ส่วนแรกใช้แสดงวันที่และเวลา ส่วนที่สองแสดงข้อมูลอุณหภูมิและความชื้น ส่วนที่สามแสดงข้อมูลที่เหลือ โดยผมกำหนดค่าที่จำเป็นใน SquareLine Studio ดังนี้
- Create/Audiono with TFT_eSPI
- Resolution: 800×480
- Color depth: 16 bit
- Choose LVGL version based on device’s library version : 8.3.3
ในส่วนของการเขียนโปรแกรมนั้น ผมใช้ไฟล์ 7.0-inch_Squareline_Demo.ino ที่ได้จาก GitHub ของผู้ผลิตมาเป็นโค๊ดตั้งต้น เพิ่มโค๊ดส่วนที่เกี่ยวข้องกับการเชื่อมต่อ WiFi เข้าไป รวมถึงการใช้ Arduino JSON เวอร์ชัน 0.2.0 เพื่อจัดการกับข้อมูล JSON จาก server และนำค่าที่สกัดได้ปปรับปรุง UI elements ต่าง ๆ ตามตัวอย่างด้านล่างนี้ครับ
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 |
void request_data() { String url = API_ENDPOINT + "/get.php?m=latest"; Serial.println("Sending request: "); Serial.println(url); http.begin(url.c_str()); http_request_payload = "api_key=KEY&m=MODE"; http.addHeader("Content-Type", "application/x-www-form-urlencoded"); http_response_code = http.POST(http_request_payload); Serial.print("Response code: "); Serial.println(http_response_code); if(http_response_code > 0){ String response_text = http.getString(); Serial.print("Response text: "); Serial.println(response_text); JSONVar my_json_obj = JSON.parse(response_text); Serial.print("Result: "); Serial.println(my_json_obj["result"]); Serial.print("data: "); Serial.println(my_json_obj["data"]); // Show the latest data show_data(my_json_obj["data"][0]); } http.end(); } |
สำหรับการปรับปรุง UI elements ผมทำด้วยฟังก์ชัน update_arc
และ update_bar
ด้านล่างนี้ โดยผมได้กำหนดให้ Arc
และ Bar
มีช่วงการแสดงผลระหว่าง 0 – 100 เท่ากันทุกชิ้น และได้กำหนดให้ฟังก์ชันรับค่าข้อมูล (val
) และขอบเขตค่าสูงสุดต่ำสุด (min
, max
) รวมถึงค่าขีดแบ่ง (threshold: t0
, t1
, t2
) สำหรับใช้กำหนดว่าค่าช่วงไหนจะเป็นสีอะไร จากนั้นนำค่าที่ส่งมาไปคำนวณ min-max scaling
เพื่อให้ช่วงข้อมูลอยู่ระหว่าง 0 – 100 จากนั้นจึงนำข้อมูลที่ได้ไปปรับปรุงการแสดงผลครับ
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 |
void update_arc(lv_obj_t *arc, float val, float min, float max, float t0, float t1, float t2) { float y = 100.0 * ((val - min)/(max - min)); if(y <= 0.0) { y = 0.0; } if(y >= 100.0) { y = 100.0; } lv_arc_set_value(arc, int(y)); if((val >= min) && (val < t0)) { // Blue lv_obj_set_style_arc_color(arc, color_value_low, LV_PART_INDICATOR | LV_STATE_DEFAULT ); } else if((val >= t0) && (val < t1)) { // Green lv_obj_set_style_arc_color(arc, color_value_normal, LV_PART_INDICATOR | LV_STATE_DEFAULT ); } else if((val >= t1) && (val < t2)) { // Yellow lv_obj_set_style_arc_color(arc, color_value_high, LV_PART_INDICATOR | LV_STATE_DEFAULT ); } else if(val >= t2) { // Red lv_obj_set_style_arc_color(arc, color_value_very_high, LV_PART_INDICATOR | LV_STATE_DEFAULT ); } else { lv_obj_set_style_arc_color(arc, color_value_error, LV_PART_INDICATOR | LV_STATE_DEFAULT ); } } |
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 |
void update_bar(lv_obj_t *bar, float val, float min, float max, float t0, float t1, float t2) { float y = 100.0 * ((val - min)/(max - min)); if(y <= 0.0) { y = 0.0; } if(y >= 100.0) { y = 100.0; } lv_bar_set_value(bar, int(y), LV_ANIM_OFF); if((val >= min) && (val < t0)) { // Blue lv_obj_set_style_bg_color(bar, color_value_low, LV_PART_INDICATOR | LV_STATE_DEFAULT ); } else if((val >= t0) && (val < t1)) { // Green lv_obj_set_style_bg_color(bar, color_value_normal, LV_PART_INDICATOR | LV_STATE_DEFAULT ); } else if((val >= t1) && (val < t2)) { // Yellow lv_obj_set_style_bg_color(bar, color_value_high, LV_PART_INDICATOR | LV_STATE_DEFAULT ); } else if(val >= t2) { // Red lv_obj_set_style_bg_color(bar, color_value_very_high, LV_PART_INDICATOR | LV_STATE_DEFAULT ); } else { lv_obj_set_style_bg_color(bar, color_value_error, LV_PART_INDICATOR | LV_STATE_DEFAULT ); } } |
มอดูลหน้าจอ 3.5 นิ้ว : วัดค่าแสงด้วย Multispectral Sensor
โดยปกติสาขาวิชาผมจะมีรายวิชาที่มีการใช้งานเครื่องวัดค่าการสะท้อนแสงแบบหลายช่วงคลื่น (multi-spectrometer) เพื่อนำค่าการสะท้อนของพืชพรรณหรือวัตถุอื่นบนพื้นที่ที่วัดได้ไปเปรียบเทียบกับค่าที่วิเคราะห์ได้จากภาพถ่ายจากดาวเทียม ปัญหาคืออุปกรณ์พวกนั้นแม้จะวัดได้ละเอียดแต่ก็มักจะมีราคาสูงมาก (หลายแสนหรือบางรุ่นหลายล้านบาท) ทำให้นักศึกษาอาจจะได้ฝึกใช้งานและวิเคราะห์ข้อมูลได้ไม่ครบถ้วน
ดังนั้นตัวอย่างการรีวิวและทดสอบการใช้งานชุดสุดท้ายนี้ ผมจะทดลองใช้งานหน้าจอขนาด 3.5 นิ้วร่วมกับมอดูล Sparkfun AS7341
(น่าเสียดายที่มอดูลรุ่นนี้เลิกผลิตแล้ว) เพื่อทำเครื่องวัดค่าพกพาแบบราคาประหยัดครับ มอดูลนี้เป็นเซ็นเซอร์ราคาประหยัดสำหรับการตรวจวัดค่าแสงแบบหลายช่วงคลื่น (multispectral sensor) โดยมอดูลตัวนี้ใช้เซ็นเซอร์ AS7341 จาก AMS ซึ่งสามารถวัดแสงได้จำนวน 11 ช่วงคลื่น ครอบคลุมตั้งแต่ด้านปลาย ๆ ของแสงสีน้ำเงิน (415 นาโนเมตร) ไปถึงอินฟราเรดใกล้ (near-Infrared : NIR) (915 นาโนเมตร) รองรับการเชื่อมต่อแบบ Qwiic
และแบบ I2C
ซึ่งในการทดลองนี้ผมจะเชื่อมต่อกับมอดูลหน้าจอผ่าน I2C
โดยใช้สายที่ผู้ผลิตมีมาให้ครับ แต่เนื่องจากก่อนหน้านี้ผมเคยทดลองใช้งาน Sparkfun AS7341X Arduino Libray กับ ESP32 หลายตัวแล้วพบปัญหาเชื่อมต่อไม่ได้ แต่เมื่อลองกับ Adafruit AS7341 Arduino Library ซึ่งใช้ชิป AS7341 เหมือนกัน แต่รายละเอียดของมอดูลและฟังก์ชันใน library ทั้งสองตัวนี้ค่อนข้างต่างกัน แต่เมื่อทดสอบแล้วสามารถเรียกฟังก์ชันเพื่อทดสอบการสแกนได้ปกติ (ค่าที่ตรวจวัดได้ค่อนข้างถูกต้อง เพียงแต่ไม่สามารถควบคุมการทำงาน LED ต่าง ๆ บนบอร์ดได้) ดังนั้นการทดลองนี้ผมจึงจะใช้ Adafruit AS7341 Arduino Library
เพื่อแสดงตัวอย่างการประยุกต์ใช้งานครับ
ปัญหาเล็กน้อยอีกประการคือขา I2C ของมอดูลหน้าจอที่ได้รับมานั้นกำหนดขา SDA = 22
และ SCL = 21
ซึ่งอาจจะสับสนกับการกำหนดขา I2C ของบอร์ด ESP32 อื่น ๆ ที่มักจะกำหนด SDA = 21
และ SCL = 22
ดังนั้นการทดลองนี้จึงแก้ปัญหานี้ด้วยวิธีง่าย ๆ คือการเพิ่มพารามิเตอร์หมายเลขขาที่ถูกต้องเข้าไปในการเรียก Wire.begin()
ในการทดลองนี้ผมจะอ่านแสงที่วัดได้จากมอดูลแล้วนำมาแสดงผลเลย โดยจะไม่ได้ทำการ calbirate ใด ๆ ทั้งสิ้น ซึ่งค่าที่อ่านมาได้จะเป็นค่าแบบ uint16_t
ที่ได้จากเมธอด readAllChannels
ที่ถูกนำไปเก็บใน array แล้วส่งต่อไปให้ฟังก์ชันเพื่อปรับปรุง UI ซึ่งผมออกแบบด้วยโปรแกรม SquareLine Studio เวอร์ชัน 1.3.2 โดยจะแสดงผลทั้งกราฟแท่งและข้อความ แต่เนื่องจากข้อมูลค่าการสะท้อนในแชนแนล C4 (clear) และ C5 (NIR) นั้นซ้ำกับแชลแนล C10 (clear) และ C11 (NIR) ดังนั้นโปรแกรมจะไม่แสดงค่าของ C4 และ C5 ในกราฟ แต่จะยังคงแสดงค่าใน label ดังตัวอย่างการออกแบบด้านล่างนี้ครับ
ส่วนสุดท้ายคือเพิ่มโค๊ดเพื่อให้โปรแกรมบันทึกผลการสแกนเก็บเป็นไฟล์ CSV เพื่อนำไปใช้งานต่อ ซึ่งใช้งานSD Card ก็ทำได้สะดวก ไม่พบปัญหาใด ๆ เพียงแต่เราต้องตรวจสอบให้ดีว่าได้หยุดการทำงานของ touch-device ในระหว่างการใช้งาน SD Card เมื่อเขียนไฟล์เสร็จแล้วจึงกลับมาใช้งาน touch-device ต่อได้ตามปกติ รวมถึงผมได้เพิ่มการใช้งานขา GPIO-25 ให้เปิด LED ระหว่างการสแกนอีกเล็กน้อย ได้ผลลัพธ์ดังตัวอย่างในภาพด้านล่างนี้
อื่น
Elecrow เป็นผู้ผลิตอุปกรณ์ฮารด์แวร์แบบ opensource ดังนั้นนอกจากจะมี source code ต่าง ๆ ตามที่เขียนมาด้านบนแล้ว ผู้ผลิตยังให้ไฟล์ PCB และ schematic diagram เพื่อให้เรานำไปศึกษาและพัฒนาต่อได้ด้วย ซึ่งใครที่สนใจศึกษารายละเอียดเกี่ยวกับวงจรก็สามารถเปิดดู PCB และ schematic diagram ของหน้าจอ 3.7 นิ้วได้จากลิงค์นี้ และหน้าจอ 7.0 นิ้วได้จากลิงค์นี้ ซึ่งผมสามารถเปิดดูได้ด้วย Autodesk EAGLE 9.6.2 Education License ได้ไม่มีปัญหาครับ
สรุป
โดยสรุปแล้วหน้าจอทั้งสองชุดทำงานได้ดี การพัฒนาโปรแกรมด้วย Arduino IDE ก็ทำได้สะดวกเนื่องจาก libraries ที่เตรียมมาให้ค่อนข้างครบและใช้งานทันทีไม่ต้องปรับเวอร์ชันอะไรเพิ่มเติม หน้าจอก็มีความสว่างและสีสันสวยงามตามปกติของหน้าจอประเภท TFT LCD โดยส่วนตัวอยากให้เพิ่มพอร์ต GPIO หรือ SPI อีกซักหนึ่งช่องเพื่อจะได้รองรับการทำงานได้มากขึ้น และการเข้าโหมด upload ด้วยการกดปุ่ม RESET
/BOOT
นั้นทำด้วยมือเดียวได้แต่อาจจะไม่ค่อยสะดวกนักเพราะช่องของเคสบริเวณทั้งสองปุ่มนั้นค่อนข้างแคบไปหน่อย (หรือนิ้วมือผมอ้วนไปก็ไม่แน่ใจครับ)
จริง ๆ แล้วรีวิวนี้ผมตั้งใจจะใช้หน้าจอทั้งสองร่วมกับบอร์ด SONY Spresense เพื่อแสดงข้อมูลต่าง ๆ จากระบบดาวเทียมนำทาง QZSS ของญี่ปุ่น ซึ่งเป็นระบบดาวเทียมนำทางบนโลก (global navigation satellite system : GNSS) เหมือนกับ GPS (Global Positing System) ซึ่งเป็นของสหัฐอเมริกา รวมทั้งตั้งใจจะนำข้อมูลการแจ้งเตือนภัยพิบัติต่าง ๆ ที่ฝังมาในสัญญาณของดาวเทียม QZSS มาแสดงผลบนหน้าจอด้วย แต่เนื่องจากเวลามีจำกัดผมเลยจะนำการใช้งานร่วมกับ SONY Spresense ไปแยกเขียนเป็นอีกบทความนึง
ขอขอบคุณ Elecrow ที่ส่ง ESP32 3.5” HMI Display กับ ESP32 7.0” HMI Display มาให้ผมได้ทดสอบการใช้งานครับ ถ้าใครสนใจก็สั่งซื้อได้จากผู้ผลิตโดยตรงก็ได้ โดยตอนนี้ตัวหน้าจอ 3.5 นิ้วขายที่ราคา 20.63 USD (ประมาณ 720 บาท) ส่วนตัวหน้าจอ 7.0 นิ้วขายราคา 34.23 USD (ประมาณ 1200 บาท)
I am an assistant professor in surveying engineering and geographic information systems at Rambhai Barni Rajabhat University. My primary research areas include digital image/audio processing, digital photogrammetry, AI, IoT, and UAV. I am open to other subjects as well.