ESP32 Programming with M5Stack Core
แนะนำการอุปกรณ์สมองกลฝังตัวที่เรียกว่า M5Stack M5 Core ซึ่งใช้ตัวประมวลผลเป็นชิป ESP32 และเขียนโปรแกรมได้โดยใช้ภาษา MicroPython และใช้เฟิร์มแวร์ของ M5Stack UIFlow
Last updated
แนะนำการอุปกรณ์สมองกลฝังตัวที่เรียกว่า M5Stack M5 Core ซึ่งใช้ตัวประมวลผลเป็นชิป ESP32 และเขียนโปรแกรมได้โดยใช้ภาษา MicroPython และใช้เฟิร์มแวร์ของ M5Stack UIFlow
Last updated
M5Stack.com (Shenzhen, China) ได้พัฒนาและจำหน่ายโมดูลหรืออุปกรณ์อิเล็กทรอนิกส์ที่ใช้ Espressif ESP32 เป็นตัวประมวลผลหลัก แบ่งออกได้เป็นหลายรุ่น เช่น M5 Core (BASIC / GRAY / FIRE), M5Stick-C และ M5 ATOM รองรับการเขียนโปรแกรมด้วย Arduino และ MicroPython
อุปกรณ์ที่ได้นำมาใช้งานสำหรับการลองเขียนโค้ดไมโครไพธอน คือ M5 Core ซึ่งมีให้เลือก เช่น M5 BASIC / GRAY (ไม่มี PSRAM มีแต่ SPI Flash ขนาด 4MB) และ M5 FIRE (มี PSRAM ขนาด 4MB เพิ่มมาให้) เป็นต้น
ข้อมูลเชิงเทคนิคเกี่ยวกับ M5 BASIC
ESP32 with WiFi / Bluetooth capability (2.4 GHz)
4MB of SPI Flash
Micro-SD Card Slot (up to 16GB Storage)
Type-C USB Port / USB-to-Serial Converter
320x240 2.0" TFT Color Display (ILI9342C driver)
3 User Buttons (A, B, C) + 1 Reset Button
Small 1W speaker
150 mAh LiPo Battery
Grove Port / I2C Connector
ข้อมูลเชิงเทคนิคเกี่ยวกับ M5 GRAY
An upgrade version of M5 BASIC
I2C IMU Sensor: MPU9250 or MPU6886 + BMM150
Analog MEMS Microphone BSE3729
ข้อมูลเชิงเทคนิคเกี่ยวกับ M5 FIRE
An upgrade version of M5 GRAY (with 16MB SPI Flash + 4MB PSRAM)
Type-C USB port / USB-to-Serial converter
Grove Ports (I2C + I/O + UART)
2-inch, 320x240 TFT LCD (ILI9342C driver)
Speaker 1W-0928
MEMS Analog BSE3729 Microphone
3 Custom Buttons
SK6812 3535 RGB LED x 10
IMU Sensor: MPU9250 or BMM150 + MPU6886
550 mAh @ 3.7V LiPo Battery + IP5306 (I2C)
โมดูล M5 Basic และ M5 Gray จะมีบอร์ดฐานปิดด้านล่าง เรียกว่า Base CORE Bottom ซึ่งมีแบตเตอรี LiPo (110 mAh @ 3.7V) อยู่ภายใน และมีคอนเนกเตอร์ที่เรียกว่า M-Bus และทั้งสี่ด้านมี Pin Headers เอาไว้สำหรับต่อสายเชื่อมต่อกับอุปกรณ์หรือวงจรภายนอกได้
บอร์ดฐานยังมีอีกหลายแบบ จำแนกตามกลุ่มได้แก่ โมดูลสื่อสาร (Communication Modules) เช่น LoRa/LoRaWAN, SIM800L, GPS Receiver, W5500 (Ethernet) เป็นต้น โมดูลแบตเตอรีที่มีความจุมากกว่า 100 mAh หรือโมดูลขยายพอร์ตสำหรับต่อวงจร (Expansion Modules) และโมดูลสำหรับขับมอเตอร์ไฟฟ้ากระแสตรง (Drive Modules) เป็นต้น
ข้อสังเกต: M5 FIRE มีราคาสูงกว่ารุ่นก่อนหน้า และมีหน่วยความจำ SPI Flash เพิ่มจาก 4MB เป็น 16MB และที่สำคัญคือ มีการเพิ่มไอซีหน่วยความจำ SPI RAM / PSRAM ที่มีความจุ 4MB ดังนั้นเหมาะกับการเขียนโค้ดด้วยไมโครไพธอน
ในปัจจุบันทางบริษัท M5Stack ได้ออกแบบและพัฒนาอุปกรณ์ที่ใช้ตัวประมวลผล ESP32 ออกมาอีกหลายรูปแบบ แต่สำหรับเนื้อหาในเอกสารนี้ เราจะกล่าวถึงและใช้งานเฉพาะ M5Stack Core
เพื่อสนับสนุนการเขียนโปรแกรม บริษัท M5Stack ได้พัฒนาซอฟต์แวร์ UIFlow (http://flow.m5stack.com) ซึ่งเป็น Web-based IDE และใช้งานแบบออนไลน์ (มีเวอร์ชัน UIFlow Desktop IDE ให้ดาวน์โหลดและติดตั้งใช้งานแบบ Offline ได้เช่นกัน)
UIFlow = “A Web IoT programming platform using Blockly+MicroPython”
ซอฟต์แวร์ดังกล่าวใช้สำหรับการเขียนโปรแกรมด้วยวิธีการต่อบล็อกตามรูปแบบของ Google Blockly และสามารถใช้ในการออกแบบกราฟิกโดยใช้ UI Designer หรือจะเปลี่ยนโหมดไปใช้ภาษาไมโครไพธอนในการเขียนโค้ดก็ได้
สำหรับผู้เริ่มต้น การใช้บล็อกคำสั่งของ UIFlow แล้วแปลงให้เป็นโค้ด อาจเป็นวิธีหนึ่งที่ช่วยในการศึกษา และทำให้เห็นตัวอย่างการใช้คำสั่งได้ง่ายขึ้น นอกเหนือจากการศึกษาจากเอกสารเกี่ยวกับ API ของ UIFlow และไลบรารีที่เกี่ยวข้อง
การติดตั้งไฟล์เฟิร์มแวร์ไปยัง M5 Core สามารถใช้โปรแกรม M5 Burner หรือ UI Flow Desktop IDE (มีให้ดาวน์โหลดสำหรับ Windows 64-bit, Linux และ Mac OS X) ในบทความนี้จะสาธิตวิธีการใช้โปรแกรมชื่อ esptool
ที่ทำงานโดยใช้ Python 3 เป็นอีกหนึ่งวิธี
เราจะไม่ใช้ไฟล์สำหรับติดตั้งเฟิร์มแวร์ MicroPython (ESP32 Port) แต่จะใช้ M5-UIFlow Firmware (ลองใช้เวอร์ชัน 1.5.4 — 2020.06.05) ที่บริษัท M5Stack ได้พัฒนาเอาไว้ เนื่องจากได้รวมไลบรารีอย่างเช่น UIFlow-Code ไว้แล้ว
ดาวนโหลดไฟล์ M5Burner.zip
(ในกรณีนี้ ใช้สำหรับ Windows 64-bit) จากนั้นทำคำสั่ง Unzip จะได้ไดเรกทอรีใหม่ชื่อ M5Burner
ให้ดับเบิลคลิกที่ไฟล์ M5Burner.exe
เพื่อเรียกใช้งาน
ข้อสังเกต: ถ้าลองใช้เวอร์ชัน เช่น v1.5.4 สำหรับ M5 Core Basic / Gray ให้เลือกไฟล์ UIFlow-v1.5.4-en.bin
แต่ถ้าใช้สำหรับ M5 Core Fire ให้เลือกไฟล์ UIFlow-v1.5.4-fire.bin
เมื่อได้ดาวน์โหลดไฟล์ .bin
มาแล้ว จะมีปุ่ม “Burn” ปรากฏ จากนั้นให้เสียบสาย USB เชื่อมต่อกับอุปกรณ์ M5 Core และทำขั้นตอนอัปโหลดไฟล์เฟิร์มแวร์
จากขั้นตอนที่แล้ว จะสังเกตได้ว่า M5Burner ได้ใช้คำสั่ง esptool
สำหรับทำขั้นตอน Burn Firmware และอ่านไฟล์ .bin
จากไดเรกทอรี M5Burner\packages\fw\core
ดังนั้นถ้าจะลองใช้คำสั่ง esptool
ดูบ้าง ให้แน่ใจว่า ในเครื่องคอมพิวเตอร์มี Python 3 ไว้พร้อมใช้งานแล้ว (ถ้าไม่มีให้ติดตั้งก่อน) จากนั้นให้ติดตั้ง esptool
โดยใช้คำสั่ง pip
เสียบสาย USB เชื่อมต่อกับอุปกรณ์ แล้วลองทำคำสั่ง (ลองอ่านหมายเลข MAC Address ของอุปกรณ์)
ถ้าทำได้สำเร็จ แสดงว่า สามารถเชื่อมต่อกับอุปกรณ์ได้ จากนั้นให้ทำคำสั่งเพื่อลบข้อมูลในหน่วยความจำ Flash ของ ESP32 ดังนี้
จากนั้นทำคำสั่งต่อไปนี้ เพื่อเขียนไฟล์เฟิร์มแวร์ไปยังอุปกรณ์ M5 BASIC / GRAY:
ในกรณีที่ต้องการลองใช้ UIFlow แบบออนไลน์ จะต้องตั้งค่า Wi-Fi (SSID และ Password) ให้กับอุปกรณ์ก่อน เพื่อให้สามารถเชื่อมต่อไปยังอินเทอร์เน็ตได้
การตั้งค่า Wi-Fi ให้อุปกรณ์ ทำได้โดยเปิดใช้งานโหมด Wi-Fi AP โดยไปที่เมนู Setup > “Wi-Fi via AP” (สามารถใช้ปุ่มกดที่มีอยู่สามปุ่มของอุปกรณ์เลือกเมนูได้) ซึ่งจะเห็น SSID ของอุปกรณ์ที่ปรากฏชื่อเป็น M5-XXXX
(X
=แทนตัวเลขฐานสิบหก) เป็นแบบ Open ไม่มีรหัสผ่าน
เมื่ออุปกรณ์อยู่ในโหมด Wi-Fi AP แล้ว ให้คอมพิวเตอร์ของผู้ใช้เชื่อมต่อกับระบบ Wi-Fi ดังกล่าว จากนั้นเปิด Web browser ไปที่ 192.168.4.1
จะมีหน้าเว็บให้ผู้ใช้เลือก WiFi SSID และรหัสผ่านที่ต้องการเลือกใช้งาน เมื่อเชื่อมต่อได้แล้ว อุปกรณ์จะรีเซตตัวเอง
ขั้นตอนถัดไปคือ ทำให้อุปกรณ์ทำงานในโหมด Internet โดยเลือกเมนู Switch Mode > Internet Mode จากนั้นกดปุ่มรีเซตของอุปกรณ์อีกครั้ง เมื่อระบบเริ่มทำงานใหม่ จะพยายามเชื่อมต่อ Wi-Fi จากนั้นจะเชื่อมต่อไปยัง M5 UIFlow Server (flow.m5stack.com) ตามลำดับ
การใช้ซอฟต์แวร์ UIFlow IDE จะต้องมีการระบุ API Key ซึ่งเป็นเลขฐานสิบหกที่มีจำนวน 8 หลัก (8-Digit Hex String) และมีค่าแตกต่างกันไปสำหรับแต่ละอุปกรณ์ เราจะทราบได้ก็เมื่อได้ติดตั้ง M5 Firmware ลงในอุปกรณ์ M5 Core แล้ว
เมื่อระบบเริ่มทำงานเข้าสู่ Internet Mode หรือ USB Mode จะมีการแสดงค่าดังกล่าวบนจอ LCD ของอุปกรณ์ ค่า API KEY นี้จะต้องนำไปใช้กับ UIFlow IDE จึงจะรันโค้ดกับอุปกรณ์ที่เชื่อมต่อได้
จากนั้นเราก็สามารถลงเขียนโค้ด และทดสอบการทำงานกับอุปกรณ์ที่เชื่อมต่ออยู่ในขณะนั้นได้
ข้อคิดเห็นของผู้เขียน: จากการทดลองใช้ UIFlow IDE (แบบออนไลน์) การเขียนโค้ดและทดสอบการทำงานร่วมกับอุปกรณ์จริง ก็ทำได้สะดวก แต่มีข้อจำกัดอยู่บ้าง เช่น การตรวจสอบ Syntax ของโค้ด และการดีบักหรือแสดงเอาต์พุตการทำงานของโค้ด เช่น ด้วยวิธีการใช้คำสั่ง print()
ไม่สามารถทำได้โดยตรง ยกเว้นว่า จะใช้คำสั่ง lcd.print()
มาเป็นตัวช่วย
อีกประเด็นหนึ่งคือ เมื่อเกิดความผิดพลาดระหว่างที่รันโค้ด เช่น เกิด Runtime Error ก็จะมีข้อความแจ้งปัญหา (Error Message) สั้น ๆ แสดงบนหน้าจอ LCD ของอุปกรณ์ และจะไม่เหมือนกรณีที่ใช้ MicroPython REPL
ถ้าจะเขียนโค้ดแบบ Offline เช่น ใช้ UIFlow Desktop IDE (ดาวน์โหลดไฟล์ติดตั้งได้จาก https://m5stack.com/pages/download) หรือโปรแกรมอื่นเช่น Thonny IDE หรือ Mu Editor จะต้องทำให้อุปกรณ์อยู่ในโหมด USB
เมื่อกดปุ่มรีเซตที่ตัวอุปกรณ์ จะปรากฏเมนูบนหน้าจอ LCD จากนั้นให้เลือกโหมด Setup เลือกไปที่ Switch Mode แล้วเปลี่ยนจาก APP Mode เป็น USB Mode
ถ้าเราตั้งค่าดังกล่าวแล้ว เมื่อกดปุ่มรีเซตของตัวอุปกรณ์อีกครั้ง ระบบจะเริ่มทำงานโดยเข้าสู่โหมด USB
ถัดไปเป็นการลองใช้โปรแกรม Thonny IDE สำหรับระบบปฏิบัติการ Windows (ถ้ายังไม่มี ให้ดาวน์โหลดไฟล์และติดตั้งใช้งานก่อน)
เสียบสาย USB เชื่อมต่อกับอุปกรณ์ M5 Core จากนั้นเลือกเมนูคำสั่ง Run > Select Interpreter ให้เป็น MicroPython (generic) และระบุพอร์ตของอุปกรณ์ M5 Core ที่กำลังเชื่อมต่ออยู่
เมื่อเราเชื่อมต่อกับอุปกรณ์ได้แล้ว ให้กดปุ่ม “Stop” (Stop/Restart) ของโปรแกรม Thonny IDE เพื่อหยุดการทำงานของโปรแกรมของอุปกรณ์ที่กำลังทำงานอยู่ในขณะนั้น เราจะเข้าโหมด REPL และปรากฎสัญลักษณ์ >>>
สำหรับรับคำสั่งถัดไป
ปัญหาที่อาจพบ: บ่อยครั้งที่เมื่อเชื่อมต่อครั้งแรกจาก Thonny IDE ผ่านทาง USB-to-Serial อาจไม่มีการตอบสนองจากบอร์ด และจะต้องลองหลายครั้งจึงจะสำเร็จ
ในมุมมอง “Files” เราจะเห็นรายการไฟล์และไดเรกทอรีย่อยภายใน Flash Storage ของอุปกรณ์ เช่น ไดเรกทอรี flash
ที่มีไฟล์ boot.py
และ main.py
เป็นต้น
เมื่อเปิดระบบ เช่น หลังจากการกดปุ่มรีเซต และระบบเริ่มทำงาน ก็จะเรียกไฟล์ boot.py
เพื่อทำคำสั่งที่อยู่ภายในเป็นลำดับแรก ถัดจากนั้นจะตรวจสอบดูว่า มีไฟล์ main.py
หรือไม่ ถ้ามี ก็ให้เรียกไฟล์ดังกล่าวให้ทำงานเป็นลำดับถัดไป แต่ถ้า M5 Core อยู่ในโหมด USB จะไม่มีการรันคำสั่งในไฟล์ main.py
ตัวอย่างโค้ดแรก แสดงข้อความบนกลางจอ LCD มีพื้นหลัง (Background Color) เป็นสีดำ แล้วเปลี่ยนสีของข้อความตามค่าสี (ค่าคงที่สำหรับการเลือกใช้สีแบบ RGB) ที่ใส่ไว้ในอาร์เรย์
ให้บันทึกโค้ดลงในไฟล์ /flash/temp.py
ใน Flash Storage ของอุปกรณ์ สามารถทำได้โดยใช้ Thonny IDE ในมุมมอง View > Files แล้วกดปุ่ม “Run” (Run Current Script)
โค้ดตัวอย่างนี้ แสดงข้อความบนกลางจอ LCD แล้วเปลี่ยนฟอนต์ (Font) ของระบบที่ใช้ในการแสดงข้อความตามรายการที่กำหนดไว้ในอาร์เรย์
โค้ดตัวอย่างถัดไป สาธิตการตรวจสอบว่า มีการกดปุ่ม A, B หรือ C หรือไม่ โดยเราสามารถใช้ btnA
, btnB
และ btnC
จากไลบรารี m5stack
สำหรับปุ่มกดทั้งสาม และมีคำสั่งให้ใช้ เช่น wasPressed()
และ wasReleased()
โดยจะต้องระบุฟังก์ชันที่ทำหน้าที่เป็น Callback Function เมื่อเกิดเหตุการณ์ดังกล่าว (มีเกิดการกดปุ่มหรือปล่อยปุ่มในแต่ละครั้ง)
โค้ดตัวอย่างถัดไป สาธิตการใช้คำสั่งเกี่ยวกับปุ่มกดทั้งสาม เช่น การตรวจสอบว่ามีการกดปุ่ม (เช่น ปุ่ม btnA
) มีระยะเวลาอย่างน้อยในการกดค้างไว้ การกดปุ่มแบบดับเบิลคลิก (เช่น ปุ่ม btnB
) หรือมีการกดปุ่มแล้วปล่อยแล้วหรือไม่ (เช่น ปุ่ม btnC
) เป็นต้น
ตัวอย่างถัดไปเป็นการสร้างเสียง โดยใช้สัญญาณ PWM เป็นเอาต์พุต และสร้างอ็อบเจกต์จากคลาส machine.PWM
และเลือกใช้ขา GPIO25 (ต่อกับวงจรลำโพงเสียงภายในของ M5 Core Basic) กำหนดค่าความถี่ได้ (หน่วยเป็น Hz) และค่า Duty Cycle ในช่วง 0 ถึง 100 (เลือกค่าให้น้อยลง เพื่อลดระดับความดังของสัญญาณเสียง)
ในตัวอย่างนี้ เราสร้างอ็อบเจกต์จากคลาส machine.Timer
(เลือกใช้หมายเลข 0..4 สำหรับ Hardware Timer ของ ESP32) มาใช้ในโหมด Oneshot เพื่อกำหนดระยะเวลาในการสร้างสัญญาณเสียงแล้วปิดเสียงหลังจากนั้น
หรือเราจะใช้คำสั่ง speaker
แทนก็ได้ เช่น
ในกรณีที่เราต้องการหยุดการทำงานของอุปกรณ์เพื่อประหยัดพลังงาน เราสามารถใช้คำสั่งเพื่อทำให้ ESP32 เข้าสู่โหมด Deep Sleep เช่น เมื่อกดปุ่ม C ของอุปกรณ์ ก็สามารถใช้คำสั่งดังนี้
สร้างรูปกราฟิกที่เป็นวงกลม (Circle) แบบสุ่มพิกัด (x,y) ขนาดรัศมี (r) โดยใช้หน่วยเป็นพิกเซล และสี RGB ของเส้นวงกลม (ไม่ระบายสีภายใน) สร้างทั้งหมด 100 วงกลม คำสั่งที่ใช้วาดวงกลมคือ lcd.circle()
โดยที่ lcd
เป็นส่วนหนึ่งของโมดูล m5stack
เราสามารถเปลี่ยนมาใช้ M5Circle()
ซึ่งอยู่ในโมดุล m5ui
เพื่อสร้างอ็อปเจกต์ (Object) เป็นรูปวงกลมแทนการใช้คำสั่ง lcd.circle()
ลองเปลี่ยนเป็นรูปกราฟิกทรงสี่เหลี่ยม (Rectangle) แบบสุ่มพิกัดเริ่มต้น และสุ่มขนาดของสี่เหลี่ยม (ความกว้างและความยาว) โดยใช้วิธีการสร้างอ็อปเจกต์จาก M5Rect
ตัวอย่างถัดไปสาธิตการสุ่มเลขจำนวนเต็มในช่วง 0..200 จำนวน N=50 แล้วนำข้อมูลที่ได้มาแสดงเป็นกราฟแท่งตามลำดับของข้อมูลในอาร์เรย์
ตัวอย่างที่ได้เลือกมาสาธิตการใช้งานคือ การเชื่อมต่อกับ MQTT Broker ที่ได้จากการติดตั้งโปรแกรม Mosquitto สำหรับบอร์ด Raspberry Pi และทำงานร่วมกับโปรแกรม Zigbee2mqtt ที่ทำหน้าที่เป็นตัวเชื่อมต่อ (Bridge) ระหว่างเครือข่ายไร้สาย ZigBee กับ MQTT Broker
ขั้นตอนการติดตั้งใช้งาน Zigbee2mqtt สำหรับบอร์ด Raspberry Pi ทางผู้พัฒนาได้เขียนอธิบายอย่างละเอียดแล้ว ดังนั้นศึกษาได้จาก https://www.zigbee2mqtt.io/getting_started/running_zigbee2mqtt.html
ในกรณีสาธิตนี้ เราจะใช้ M5 Core เชื่อมต่อไปยัง MQTT Broker พอร์ต 1883
ตามหมายเลข IP Address ของบอร์ด Rasbperry Pi ที่ได้นำมาใช้งาน และจะต้องมีการระบุชื่อผู้ใช้และรหัสผ่านสำหรับ MQTT User Authentication ด้วย (ในโค้ดตัวอย่างได้ตั้งค่าไว้เป็น zigbee2mqtt
: zigbee2mqtt
)
เมื่อเริ่มต้นการทำงาน อุปกรณ์ M5 Core จะเชื่อมต่อกับ Wi-Fi เข้าสู่ระบบเครือข่ายโดยอัตโนมัติ (ถ้าเคยได้ตั้งค่าใช้งานอย่างถูกต้องไว้แล้ว) และเชื่อมต่อกับ MQTT Broker ได้แล้ว จะทำหน้าที่คอยรับข้อความในหัวข้อ (Topic) ตามที่ระบุได้
เมื่อมีข้อความซึ่งอยู่ในรูปแบบของ JSON String ถูกส่งมาจาก MQTT Broker ด้วยรูปแบบการสื่อสาร (Protocol) ที่เรียกว่า MQTT ข้อมูลในข้อความที่ได้รับ จะถูกนำมาแสดงผลบนจอ LCD
ในกรณีตัวอย่างนี้เป็นข้อมูลของโมดูลเซ็นเซอร์ Xiaomi Mijia Temperature and Humidity Sensor ได้แก่ ค่าอุณหภูมิ ค่าความชื้นสัมพัทธ์ ระดับของแบตเตอรี่ที่เหลืออยู่ และแรงดันของแบตเตอรี่
โดยสรุป การใช้งานซอฟต์แวร์ UIFlow / UIFlow-Desktop IDE และเฟิร์มแวร์ที่เกี่ยวข้องร่วมกับอุปกรณ์ M5 Core (ESP32) เพื่อเขียนโปรแกรมด้วยภาษาไมโครไพธอน ก็ถือว่าทำได้สะดวก และสามารถใช้ชุดคำสั่งหรือไลบรรีที่ทาง M5Stack ได้จัดทำไว้แล้ว แต่ก็มีข้อจำกัดอยู่บ้างในการใช้งาน จุดเด่นน่าจะเป็นตัวช่วยในการออกแบบ UI แบบกราฟิกที่แสดงผลบนจอ TFT-LCD ขนาด 320x240 พิกเซล เราสามารถนำไปประยุกต์ใช้งาน เช่น การสร้างอุปกรณ์ IoT ควบคุมและแสดงผลที่มีขนาดเล็กสำหรับผู้ใช้และเชื่อมต่อ Wi-Fi ได้
เผยแพร่ภายใต้ลิขสิทธิ์ Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)