# ESP32 Programming with M5Stack Core

## แนะนำอุปกรณ์ **ESP32-M5Stack**  <a href="#dfad" id="dfad"></a>

[**M5Stack.com**](https://m5stack.com/) (**Shenzhen**, **China**) ได้พัฒนาและจำหน่ายโมดูลหรืออุปกรณ์อิเล็กทรอนิกส์ที่ใช้ [**Espressif ESP32**](https://www.espressif.com/en/products/socs/esp32/overview) เป็นตัวประมวลผลหลัก แบ่งออกได้เป็นหลายรุ่น เช่น **M5 Core (**[**BASIC**](https://docs.m5stack.com/#/en/core/basic) **/** [**GRAY**](https://docs.m5stack.com/#/en/core/gray) **/** [**FIRE**](https://docs.m5stack.com/#/en/core/fire)**),** [**M5Stick-C**](https://docs.m5stack.com/#/en/core/m5stickc) และ [**M5 ATOM**](https://docs.m5stack.com/#/en/core/atom_lite) รองรับการเขียนโปรแกรมด้วย **Arduino** และ **MicroPython**

อุปกรณ์ที่ได้นำมาใช้งานสำหรับการลองเขียนโค้ดไมโครไพธอน คือ **M5 Core** ซึ่งมีให้เลือก เช่น **M5 BASIC / GRAY** (ไม่มี **PSRAM** มีแต่ **SPI Flash** ขนาด **4MB**) และ **M5 FIRE** (มี **PSRAM** ขนาด **4MB** เพิ่มมาให้) เป็นต้น

![รูปภาพ: M5 Core / Kit Products (Source: M5Stack)](https://969412697-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MIHfYo9IV3uTFm2tkDn%2F-MKIsPchPaj6sH1x229e%2F-MKIspSwKqcfw_83uXAB%2Fm5stack_core_products.png?alt=media\&token=43330650-74c5-4f3f-8ba3-2345f0bcd20e)

**ข้อมูลเชิงเทคนิคเกี่ยวกับ 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**](https://docs.m5stack.com/#/en/base/core_bottom) ซึ่งมีแบตเตอรี **LiPo (110 mAh @ 3.7V)** อยู่ภายใน และมีคอนเนกเตอร์ที่เรียกว่า **M-Bus** และทั้งสี่ด้านมี **Pin Headers** เอาไว้สำหรับต่อสายเชื่อมต่อกับอุปกรณ์หรือวงจรภายนอกได้

![รูปภาพ: M5Stack BASIC (Source: M5Stack)](https://969412697-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MIHfYo9IV3uTFm2tkDn%2F-MKIuuEfENoFA0dBnEn5%2F-MKIxEKHNwe_jC38ekez%2Fm5stack_core_basic.png?alt=media\&token=27d2c178-d07f-454d-bc43-02c1f896131c)

![รูปภาพ: M5Stack Base Core Bottom](https://969412697-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MIHfYo9IV3uTFm2tkDn%2F-MKIuuEfENoFA0dBnEn5%2F-MKIxdJy053_BLpVfAVL%2Fm5stack_core_base.png?alt=media\&token=2b966582-1527-44d8-b586-5f4d6b6929e6)

![รูปภาพ: M5Stack FIRE](https://969412697-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MIHfYo9IV3uTFm2tkDn%2F-MKIuuEfENoFA0dBnEn5%2F-MKIy30CRHmGrU8dBkVB%2Fm5stack_fire.png?alt=media\&token=020c0e79-8570-403a-b781-8c03cc9205c8)

บอร์ดฐานยังมีอีกหลายแบบ จำแนกตามกลุ่มได้แก่ โมดูลสื่อสาร (**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**&#x20;

## **ULFlow IDE: Block-based Programming** <a href="#id-094a" id="id-094a"></a>

เพื่อสนับสนุนการเขียนโปรแกรม บริษัท [**M5Stack**](https://m5stack.com/) ได้พัฒนาซอฟต์แวร์ [**UIFlow**](http://flow.m5stack.com/) ([http://flow.m5stack.com](http://flow.m5stack.com/)) ซึ่งเป็น **Web-based IDE** และใช้งานแบบออนไลน์ (มีเวอร์ชัน [**UIFlow Desktop IDE**](https://m5stack.com/pages/download) ให้ดาวน์โหลดและติดตั้งใช้งานแบบ **Offline** ได้เช่นกัน)

> ***UIFlow = “A Web IoT programming platform using Blockly+MicroPython”***

ซอฟต์แวร์ดังกล่าวใช้สำหรับการเขียนโปรแกรมด้วยวิธีการต่อบล็อกตามรูปแบบของ [**Google Blockly**](https://developers.google.com/blockly) และสามารถใช้ในการออกแบบกราฟิกโดยใช้ [**UI Designer**](https://m5stack.github.io/UIFlow_doc/en/en/Display/UI.html)  หรือจะเปลี่ยนโหมดไปใช้ภาษาไมโครไพธอนในการเขียนโค้ดก็ได้

สำหรับผู้เริ่มต้น การใช้บล็อกคำสั่งของ [**UIFlow**](https://docs.m5stack.com/#/en/uiflow/uiflow_home_page) แล้วแปลงให้เป็นโค้ด อาจเป็นวิธีหนึ่งที่ช่วยในการศึกษา และทำให้เห็นตัวอย่างการใช้คำสั่งได้ง่ายขึ้น นอกเหนือจากการศึกษาจากเอกสารเกี่ยวกับ **API** ของ [**UIFlow**](https://m5stack.github.io/UIFlow_doc/en/) และไลบรารีที่เกี่ยวข้อง

![รูปภาพ: การใช้งาน UI Designer แบบออนไลน์](https://969412697-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MIHfYo9IV3uTFm2tkDn%2F-MKIN3pOAFUA5NZOFE5g%2F-MKINh7DngRBZYWi6Ito%2Fm5stack_uiflow_online.png?alt=media\&token=6c8fadef-77b3-45b5-a29a-e62778b93e3e)

## **การติดตั้ง UIFlow Firmware โดยใช้โปรแกรม M5Burner** <a href="#c643" id="c643"></a>

‍‍การติดตั้งไฟล์เฟิร์มแวร์ไปยัง **M5 Core** สามารถใช้โปรแกรม [**M5 Burner**](https://m5stack.com/pages/download) หรือ **UI** [**Flow Desktop IDE**](https://m5stack.com/pages/download) (มีให้ดาวน์โหลดสำหรับ **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`

![รูปภาพ: ขั้นตอนเลือกและดาวน์โหลดไฟล์เฟิร์มแวร์](https://969412697-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MIHfYo9IV3uTFm2tkDn%2F-MKIOJ6_QumzryevzATz%2F-MKIPYQyS-ONch0Gt1Ce%2Fm5stack_m5burner.png?alt=media\&token=ebd23a4c-933f-4e32-bcd3-842f16df4a36)

![รูปภาพ: M5Burner v2.2.7](https://969412697-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MIHfYo9IV3uTFm2tkDn%2F-MPnnnFpmNgb8txuKqGg%2F-MPoEYTZZEAWk08j_9Qu%2Fm5burn_v2.2.4.png?alt=media\&token=60829adc-4ff0-48e7-8eee-57f077a36b42)

เมื่อได้ดาวน์โหลดไฟล์ `.bin` มาแล้ว จะมีปุ่ม “**Burn**” ปรากฏ จากนั้นให้เสียบสาย **USB** เชื่อมต่อกับอุปกรณ์ **M5 Core** และทำขั้นตอนอัปโหลดไฟล์เฟิร์มแวร์

![รูปภาพ: ตัวอย่างข้อความที่ปรากฏเมื่อทำขั้นตอนใน M5Burner](https://969412697-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MIHfYo9IV3uTFm2tkDn%2F-MKIOJ6_QumzryevzATz%2F-MKIPl_BaRwJvytEjogd%2Fm5stack_m5burner_flashing.png?alt=media\&token=9e60453a-d754-447f-b8ea-eb755ef7af21)

## **การติดตั้ง UIFlow Firmware โดยใช้โปรแกรม esptool.py** <a href="#c643" id="c643"></a>

จากขั้นตอนที่แล้ว จะสังเกตได้ว่า **M5Burner** ได้ใช้คำสั่ง `esptool` สำหรับทำขั้นตอน **Burn Firmware** และอ่านไฟล์ `.bin` จากไดเรกทอรี `M5Burner\packages\fw\core`

ดังนั้นถ้าจะลองใช้คำสั่ง **`esptool`** ดูบ้าง ให้แน่ใจว่า ในเครื่องคอมพิวเตอร์มี **Python 3** ไว้พร้อมใช้งานแล้ว (ถ้าไม่มีให้ติดตั้งก่อน) จากนั้นให้ติดตั้ง **`esptool`** โดยใช้คำสั่ง **`pip`**

```
python3 -m pip install -U esptool
```

เสียบสาย **USB** เชื่อมต่อกับอุปกรณ์ แล้วลองทำคำสั่ง (ลองอ่านหมายเลข **MAC Address** ของอุปกรณ์)

```
python3 -m esptool read_mac
```

ถ้าทำได้สำเร็จ แสดงว่า สามารถเชื่อมต่อกับอุปกรณ์ได้ จากนั้นให้ทำคำสั่งเพื่อลบข้อมูลในหน่วยความจำ **Flash** ของ **ESP32** ดังนี้

```
python3 -m esptool --chip esp32 erase_flash
```

จากนั้นทำคำสั่งต่อไปนี้ เพื่อเขียนไฟล์เฟิร์มแวร์ไปยังอุปกรณ์ **M5 BASIC / GRAY:**

```
python3 -m esptool --chip esp32 --baud 921600 ^
  --before default_reset --after no_reset ^
  write_flash -z --flash_mode dio --flash_freq 80m ^
  --flash_size detect 0x1000 UIFlow-v1.5.4-en.bin
```

## **การตั้งค่า Wi-Fi และทำงานในโหมด Internet** <a href="#d4cd" id="d4cd"></a>

ในกรณีที่ต้องการลองใช้ [**UIFlow**](https://flow.m5stack.com/) แบบออนไลน์ จะต้องตั้งค่า **Wi-Fi** (**SSID** และ **Password**) ให้กับอุปกรณ์ก่อน เพื่อให้สามารถเชื่อมต่อไปยังอินเทอร์เน็ตได้

การตั้งค่า **Wi-Fi** ให้อุปกรณ์ ทำได้โดยเปิดใช้งานโหมด **Wi-Fi AP** โดยไปที่เมนู **Setup > “Wi-Fi via AP”** (สามารถใช้ปุ่มกดที่มีอยู่สามปุ่มของอุปกรณ์เลือกเมนูได้) ซึ่งจะเห็น **SSID** ของอุปกรณ์ที่ปรากฏชื่อเป็น **`M5-XXXX`** (`X`=แทนตัวเลขฐานสิบหก) เป็นแบบ **Open** ไม่มีรหัสผ่าน

![รูปภาพ: การเปิดใช้งานโหมด WiFi AP ของอุปกรณ์](https://969412697-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MIHfYo9IV3uTFm2tkDn%2F-MKIS3Xl59XjlL2T8-PB%2F-MKIS7S718QbzDktdC4o%2Fm5stack_wifi_setting-1.jpg?alt=media\&token=ec4331db-4a1f-4901-a2d2-60fd2e122ff4)

เมื่ออุปกรณ์อยู่ในโหมด **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)** ตามลำดับ

![รูปภาพ: การเชื่อมต่ออุปกรณ์ M5Stack Core กับเครือข่าย Wi-Fi](https://969412697-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MIHfYo9IV3uTFm2tkDn%2F-MKIS3Xl59XjlL2T8-PB%2F-MKISPDhhUyAcDBImpAX%2Fm5stack_wifi_setting-2.jpg?alt=media\&token=21edbb1f-c232-46e5-b922-e4ba656e3f5b)

![รูปภาพ: แสดงสถานะเชื่อมต่อกับ M5 Server (flow.m5stack.com) ได้สำเร็จ](https://969412697-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MIHfYo9IV3uTFm2tkDn%2F-MKIS3Xl59XjlL2T8-PB%2F-MKITXE5qTVemi_fT7Hd%2Fm5stack_wifi_setting-3.jpg?alt=media\&token=679ce61c-e2ac-45fb-a95a-f45acaec89f2)

## การใช้งาน UIFlow IDE แบบออนไลน์

การใช้ซอฟต์แวร์ **UIFlow IDE** จะต้องมีการระบุ [**API Key**](https://m5stack.github.io/UIFlow_doc/en/en/base/setting_APIkey.html) ซึ่งเป็นเลขฐานสิบหกที่มีจำนวน 8 หลัก (**8-Digit Hex String)** และมีค่าแตกต่างกันไปสำหรับแต่ละอุปกรณ์ เราจะทราบได้ก็เมื่อได้ติดตั้ง **M5 Firmware** ลงในอุปกรณ์ **M5 Core** แล้ว&#x20;

เมื่อระบบเริ่มทำงานเข้าสู่ **Internet Mode** หรือ **USB Mode** จะมีการแสดงค่าดังกล่าวบนจอ **LCD** ของอุปกรณ์ ค่า **API KEY** นี้จะต้องนำไปใช้กับ **UIFlow IDE** จึงจะรันโค้ดกับอุปกรณ์ที่เชื่อมต่อได้

จากนั้นเราก็สามารถลงเขียนโค้ด และทดสอบการทำงานกับอุปกรณ์ที่เชื่อมต่ออยู่ในขณะนั้นได้

![รูปภาพ: ระบุค่า API Key ของอุปกรณ์ก่อนเริ่มต้นใช้งาน](https://969412697-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MIHfYo9IV3uTFm2tkDn%2F-MKITexRdIaHlWR_yRSP%2F-MKIU1EBjMfvKj94ovyE%2Fm5stack_m5flow_connect.jpg?alt=media\&token=57768522-f89a-4355-8847-6f815d64a82c)

![รูปภาพ: M5 UIFlow (Cloud) เชื่อมต่อกับอุปกรณ์ได้แล้ว](https://969412697-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MIHfYo9IV3uTFm2tkDn%2F-MKITexRdIaHlWR_yRSP%2F-MKIUCPh6JTmAxJiyR2c%2Fm5stack_m5flow_online.jpg?alt=media\&token=05e2662f-bc89-435f-bacf-0f2f5fad5dd4)

ข้อคิดเห็นของผู้เขียน: จากการทดลองใช้ **UIFlow IDE** (แบบออนไลน์) การเขียนโค้ดและทดสอบการทำงานร่วมกับอุปกรณ์จริง ก็ทำได้สะดวก แต่มีข้อจำกัดอยู่บ้าง เช่น การตรวจสอบ **Syntax** ของโค้ด และการดีบักหรือแสดงเอาต์พุตการทำงานของโค้ด เช่น ด้วยวิธีการใช้คำสั่ง **`print()`** ไม่สามารถทำได้โดยตรง ยกเว้นว่า จะใช้คำสั่ง **`lcd.print()`** มาเป็นตัวช่วย

อีกประเด็นหนึ่งคือ เมื่อเกิดความผิดพลาดระหว่างที่รันโค้ด เช่น เกิด **Runtime Error** ก็จะมีข้อความแจ้งปัญหา (**Error Message**) สั้น ๆ แสดงบนหน้าจอ **LCD** ของอุปกรณ์ และจะไม่เหมือนกรณีที่ใช้ **MicroPython REPL**

## **การทำงานในโหมด USB และใช้งานร่วมกับ Thonny Python IDE** <a href="#b320" id="b320"></a>

ถ้าจะเขียนโค้ดแบบ **Offline** เช่น ใช้ **UIFlow Desktop IDE** (ดาวน์โหลดไฟล์ติดตั้งได้จาก <https://m5stack.com/pages/download>) หรือโปรแกรมอื่นเช่น [**Thonny IDE**](https://thonny.org/) หรือ [**Mu Editor**](https://codewith.mu/en/download) จะต้องทำให้อุปกรณ์อยู่ในโหมด **USB**

เมื่อกดปุ่มรีเซตที่ตัวอุปกรณ์ จะปรากฏเมนูบนหน้าจอ **LCD** จากนั้นให้เลือกโหมด **Setup** เลือกไปที่ **Switch Mode** แล้วเปลี่ยนจาก **APP Mode** เป็น **USB Mode**

ถ้าเราตั้งค่าดังกล่าวแล้ว เมื่อกดปุ่มรีเซตของตัวอุปกรณ์อีกครั้ง ระบบจะเริ่มทำงานโดยเข้าสู่โหมด **USB**

![รูปภาพ: การตั้งค่าจากเมนูเพื่อเข้าสู่โหมด USB](https://969412697-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MIHfYo9IV3uTFm2tkDn%2F-MKIV1gRf3_ncSYaesDu%2F-MKIVjQt6-yknKPnjPvH%2Fm5stack_core_usb_mode.jpg?alt=media\&token=e1f7de2a-d6a8-4ea8-8280-0378e2a3a21b)

![รูปภาพ: ตัวอย่างการใช้งาน UIFlow Desktop IDE แบบ Offline](https://969412697-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MIHfYo9IV3uTFm2tkDn%2F-MKIuA_icQzNHUEeYToN%2F-MKIugJcswj3kRcnzfUr%2Fm5stack_uiflow_desktop_ide.jpg?alt=media\&token=eea9c7e8-9acb-487e-a7b8-f771097545f4)

ถัดไปเป็นการลองใช้โปรแกรม [**Thonny IDE**](https://thonny.org/) สำหรับระบบปฏิบัติการ **Windows** (ถ้ายังไม่มี ให้ดาวน์โหลดไฟล์และติดตั้งใช้งานก่อน)

เสียบสาย **USB** เชื่อมต่อกับอุปกรณ์ **M5 Core** จากนั้นเลือกเมนูคำสั่ง **Run > Select Interpreter** ให้เป็น **MicroPython (generic)** และระบุพอร์ตของอุปกรณ์ **M5 Core** ที่กำลังเชื่อมต่ออยู่

เมื่อเราเชื่อมต่อกับอุปกรณ์ได้แล้ว ให้กดปุ่ม “**Stop**” **(Stop/Restart)** ของโปรแกรม **Thonny IDE** เพื่อหยุดการทำงานของโปรแกรมของอุปกรณ์ที่กำลังทำงานอยู่ในขณะนั้น เราจะเข้าโหมด **REPL** และปรากฎสัญลักษณ์ `>>>` สำหรับรับคำสั่งถัดไป

![รูปภาพ: ตั้งค่า Options สำหรับ Thonny IDE เพื่อเชื่อมต่อกับอุปกรณ์](https://969412697-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MIHfYo9IV3uTFm2tkDn%2F-MKJA9IrwTKN5Zt5yHsp%2F-MKJAdVhJNFVqIRbO3v7%2Fthonny_m5stack_connect.png?alt=media\&token=cd19a329-4aa8-4dc6-97fd-5c51735190bf)

ปัญหาที่อาจพบ: บ่อยครั้งที่เมื่อเชื่อมต่อครั้งแรกจาก **Thonny IDE** ผ่านทาง **USB-to-Serial** อาจไม่มีการตอบสนองจากบอร์ด และจะต้องลองหลายครั้งจึงจะสำเร็จ

ในมุมมอง **“Files**” เราจะเห็นรายการไฟล์และไดเรกทอรีย่อยภายใน **Flash Storage** ของอุปกรณ์ เช่น ไดเรกทอรี **`flash`** ที่มีไฟล์ `boot.py` และ `main.py` เป็นต้น

![รูปภาพ: Thonny IDE เมื่อเชื่อมต่อกับ MicroPython REPL ได้สำเร็จ](https://969412697-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MIHfYo9IV3uTFm2tkDn%2F-MKIVnYpY6-gLsWnMYBp%2F-MKImYczRrYBXo3RM7Wa%2Fthonny_m5stack_core_ready.png?alt=media\&token=f637f6b1-9f10-40fd-a08e-8ef9a1b33391)

เมื่อเปิดระบบ เช่น หลังจากการกดปุ่มรีเซต และระบบเริ่มทำงาน ก็จะเรียกไฟล์ `boot.py` เพื่อทำคำสั่งที่อยู่ภายในเป็นลำดับแรก ถัดจากนั้นจะตรวจสอบดูว่า มีไฟล์ `main.py` หรือไม่ ถ้ามี ก็ให้เรียกไฟล์ดังกล่าวให้ทำงานเป็นลำดับถัดไป แต่ถ้า **M5 Core** อยู่ในโหมด **USB** จะไม่มีการรันคำสั่งในไฟล์ **`main.py`**

## ตัวอย่างโค้ดที่ 1

ตัวอย่างโค้ดแรก แสดงข้อความบนกลางจอ **LCD** มีพื้นหลัง **(Background Color)** เป็นสีดำ แล้วเปลี่ยนสีของข้อความตามค่าสี (ค่าคงที่สำหรับการเลือกใช้สีแบบ **RGB**) ที่ใส่ไว้ในอาร์เรย์

ให้บันทึกโค้ดลงในไฟล์ **`/flash/temp.py`** ใน **Flash Storage** ของอุปกรณ์ สามารถทำได้โดยใช้ **Thonny IDE** ในมุมมอง **View > Files** แล้วกดปุ่ม “**Run**” (**Run Current Script**)

```python
import utime as time
from m5stack import lcd

# get screen dimension (width x height) in pixels
scr_w, scr_h = lcd.screensize()
print( 'LCD screen: {}x{}'.format(scr_w,scr_h) )
# fill color as black
lcd.fill( lcd.BLACK )
# set font for text display
lcd.font( lcd.FONT_DejaVu24 )
# list of colors to be used
COLORS = [
    lcd.BLUE, lcd.GREEN, lcd.RED,
    lcd.CYAN, lcd.GREEN, lcd.LIGHTGREY,
    lcd.MAGENTA, lcd.ORANGE, lcd.PINK,
    lcd.PURPLE, lcd.WHITE,
    lcd.YELLOW, lcd.GREENYELLOW ]

try:
    # press Ctrl+C to terminate
    while True:
        for color in COLORS:
            # set text color
            lcd.setTextColor(color)
            # get font size (width, height)
            font_w, font_h = lcd.fontSize()
            # show a text message centered on screen
            xpos, ypos = (lcd.CENTER, (scr_h - font_h)//2)
            lcd.print('Hello MicroPython', xpos, ypos )
            time.sleep_ms(1000)
except KeyboardInterrupt:
    pass
finally:
    lcd.clear()
    print('Done')
```

## ตัวอย่างโค้ดที่ 2

โค้ดตัวอย่างนี้ แสดงข้อความบนกลางจอ **LCD** แล้วเปลี่ยนฟอนต์ (**Font**) ของระบบที่ใช้ในการแสดงข้อความตามรายการที่กำหนดไว้ในอาร์เรย์

```python
import utime as time
from m5stack import lcd

# get screen dimension (width x height) in pixels
scr_w, scr_h = lcd.screensize()
print( 'LCD screen: {}x{}'.format(scr_w,scr_h) )
# fill color as black
lcd.fill( lcd.BLACK )
# list of fonts to be used
FONTS = [
    lcd.FONT_DefaultSmall, lcd.FONT_Default,
    lcd.FONT_Small, lcd.FONT_Comic, 
    lcd.FONT_DejaVu18, lcd.FONT_DejaVu24,
    lcd.FONT_DejaVu40, lcd.FONT_DejaVu56,
    lcd.FONT_DejaVu72, lcd.FONT_Minya, 
    lcd.FONT_Tooney ]

try:
    # press Ctrl+C to terminate
    lcd.setTextColor( lcd.GREENYELLOW )
    while True:
        for font in FONTS:
            # clear the LCD screen
            lcd.clear()
            # set text font
            lcd.font(font)
            # show a text message centered on screen
            font_w, font_h = lcd.fontSize()
            ypos = (scr_h - font_h)//2
            lcd.print( 'Hello', lcd.CENTER, ypos )
            time.sleep_ms(1000)
except KeyboardInterrupt:
    pass
finally:
    print('Done')
    lcd.clear()
```

## โค้ดตัวอย่างที่ 3

โค้ดตัวอย่างถัดไป สาธิตการตรวจสอบว่า มีการกดปุ่ม **A**, **B** หรือ **C** หรือไม่ โดยเราสามารถใช้ **`btnA`**, **`btnB`** และ **`btnC`** จากไลบรารี **`m5stack`** สำหรับปุ่มกดทั้งสาม และมีคำสั่งให้ใช้ เช่น **`wasPressed()`** และ **`wasReleased()`** โดยจะต้องระบุฟังก์ชันที่ทำหน้าที่เป็น **Callback Function** เมื่อเกิดเหตุการณ์ดังกล่าว (มีเกิดการกดปุ่มหรือปล่อยปุ่มในแต่ละครั้ง)

```python
from m5stack import lcd, btnA, btnB, btnC

lcd.clear()
lcd.fill( lcd.BLACK )
lcd.setTextColor( lcd.GREENYELLOW )
lcd.font( lcd.FONT_DejaVu24 )

font_w, font_h = lcd.fontSize()
ypos = 120 - font_h//2

lcd.print('Please press a button', lcd.CENTER, ypos)

text = 'Button {} was pressed!'

def btnA_wasPressed():
    lcd.clear()
    lcd.print( text.format('A'), lcd.CENTER, ypos )
    
def btnB_wasPressed():
    lcd.clear()
    lcd.print( text.format('B'), lcd.CENTER, ypos )
    
def btnC_wasPressed():
    lcd.clear()
    lcd.print( text.format('C'), lcd.CENTER, ypos )
    
btnA.wasPressed( btnA_wasPressed )
btnB.wasPressed( btnB_wasPressed )
btnC.wasPressed( btnC_wasPressed )

try:
    while True:
        pass
except KeyboardInterrupt:
    pass
finally:
    lcd.clear()
    print('Done')
```

## โค้ดตัวอย่างที่ 4

โค้ดตัวอย่างถัดไป สาธิตการใช้คำสั่งเกี่ยวกับปุ่มกดทั้งสาม เช่น การตรวจสอบว่ามีการกดปุ่ม (เช่น ปุ่ม **`btnA`**) มีระยะเวลาอย่างน้อยในการกดค้างไว้ การกดปุ่มแบบดับเบิลคลิก (เช่น ปุ่ม **`btnB`**) หรือมีการกดปุ่มแล้วปล่อยแล้วหรือไม่ (เช่น ปุ่ม **`btnC`**) เป็นต้น

```python
from m5stack import lcd, btnA, btnB, btnC

lcd.clear()
lcd.fill( lcd.BLACK )
lcd.setTextColor( lcd.GREENYELLOW )
lcd.font( lcd.FONT_DejaVu24 )

font_w, font_h = lcd.fontSize()
ypos = 120 - font_h//2
lcd.print('Please press a button', lcd.CENTER, ypos)

def btnA_callback():
    lcd.clear()
    lcd.print( 'A: long pressed', lcd.CENTER, ypos )
   
def btnB_callback():
    lcd.clear()
    lcd.print( 'B: double pressed', lcd.CENTER, ypos )
    
def btnC_callback():
    lcd.clear()
    lcd.print( 'C: released', lcd.CENTER, ypos )
    
btnA.restart()
btnB.restart()
btnC.restart()
btnA.pressFor( 2.0, btnA_callback )
btnB.wasDoublePress( btnB_callback )
btnC.wasReleased( btnC_callback )

try:
    while True:
        pass
except KeyboardInterrupt:
    pass
finally:
    lcd.clear()
    print('Done')
```

## โค้ดตัวอย่างที่ 5

ตัวอย่างถัดไปเป็นการสร้างเสียง โดยใช้สัญญาณ **PWM** เป็นเอาต์พุต และสร้างอ็อบเจกต์จากคลาส **`machine.PWM`** และเลือกใช้ขา **GPIO25** (ต่อกับวงจรลำโพงเสียงภายในของ **M5 Core Basic**) กำหนดค่าความถี่ได้ (หน่วยเป็น **Hz**) และค่า **Duty Cycle** ในช่วง **0** ถึง **100** (เลือกค่าให้น้อยลง เพื่อลดระดับความดังของสัญญาณเสียง)

ในตัวอย่างนี้ เราสร้างอ็อบเจกต์จากคลาส **`machine.Timer`** (เลือกใช้หมายเลข 0..4 สำหรับ **Hardware Timer** ของ **ESP32**) มาใช้ในโหมด **Oneshot** เพื่อกำหนดระยะเวลาในการสร้างสัญญาณเสียงแล้วปิดเสียงหลังจากนั้น

```python
import machine
import utime as time

# global variable
pwm = None

def timer_cb(t):
    global pwm
    if pwm:
       pwm.duty(0) # setPWM duty cycle to 0
       pwm.deinit()
       pwm = None
    t.deinit()
    
def tone( freq_hz, duration_ms=100 ):
    global pwm
    while pwm is not None:
        time.sleep_ms(10)
    t = machine.Timer(4)  # use timer 4
    pwm = machine.PWM(25) # use GPIO25 pin for PWM
    pwm.freq(freq_hz)     # set PWM frequency (Hz)
    pwm.duty(5.0)         # set PWM duty cycle (0..100)
    t.init( period=duration_ms, mode=t.ONE_SHOT, callback=timer_cb )
    
tone(500,200) # 500Hz, 200 msec
tone(700,200) # 700Hz, 200 msec
tone(900,200) # 900Hz, 200 msec
```

หรือเราจะใช้คำสั่ง [**`speaker`**](https://m5stack.github.io/UIFlow_doc/en/en/Hardwares/Speaker.html) แทนก็ได้ เช่น

```python
from m5stack import *
from m5ui import *
from uiflow import *

speaker.volume(1) # set speaker volume
speaker.tone(900, 200) # make a tone (freq. 900Hz, duration 200 ms)
```

ในกรณีที่เราต้องการหยุดการทำงานของอุปกรณ์เพื่อประหยัดพลังงาน เราสามารถใช้คำสั่งเพื่อทำให้ **ESP32** เข้าสู่โหมด **Deep Sleep** เช่น เมื่อกดปุ่ม **C** ของอุปกรณ์ ก็สามารถใช้คำสั่งดังนี้

```python
if btnC.wasPressed():
    machine.deepsleep( 7*24*60*60*1000 ) # sleep duration in msec
```

## โค้ดตัวอย่างที่ 6

สร้างรูปกราฟิกที่เป็นวงกลม (**Circle**) แบบสุ่มพิกัด (x,y) ขนาดรัศมี (r) โดยใช้หน่วยเป็นพิกเซล และสี **RGB** ของเส้นวงกลม (ไม่ระบายสีภายใน) สร้างทั้งหมด 100 วงกลม คำสั่งที่ใช้วาดวงกลมคือ **`lcd.circle()`** โดยที่ **`lcd`** เป็นส่วนหนึ่งของโมดูล **`m5stack`**

```python
from m5stack import lcd
import utime as time
import urandom as random

def rand_color():
    r = random.randint(50,255)
    g = (random.randint(50,255) << 8) 
    b = (random.randint(50,255) << 16)
    return (r | g | b)
    
lcd.clear( 0x111111 )
w,h = lcd.screensize()
for i in range(100):
    r = random.randint(10, 20)
    x = random.randint(r, w-r)
    y = random.randint(r, h-r)
    lcd.circle(x, y, r, rand_color())
```

![รูปภาพ: ตัวอย่างผลลัพธ์ที่ปรากฏบนจอ LCD (วงกลมสุ่มพิกัด)](https://969412697-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MIHfYo9IV3uTFm2tkDn%2F-MKIqLjKKybSFlA8rxz7%2F-MKIrJuiryH5w0wn_8_T%2Fm5stack_random_circles_demo.jpg?alt=media\&token=968bed4b-925b-44c7-b39a-b33197bc69c7)

เราสามารถเปลี่ยนมาใช้ **`M5Circle()`** ซึ่งอยู่ในโมดุล [**`m5ui`**](https://github.com/m5stack/UIFlow-Code/wiki/M5UI) เพื่อสร้างอ็อปเจกต์ (**Object**) เป็นรูปวงกลมแทนการใช้คำสั่ง **`lcd.circle()`**

```python
from m5stack import *
from m5ui import *
from uiflow import *
import utime as time
import urandom as random

def rand_color():
    r = random.randint(50,255)
    g = (random.randint(50,255) << 8) 
    b = (random.randint(50,255) << 16)
    return (r | g | b)
    
setScreenColor(0x111111)
lcd.clear()
w,h = lcd.screensize()
circles = []
for i in range(100):
    r = random.randint(10, 20)
    x = random.randint(r,w-r)
    y = random.randint(r,h-r)
    color = rand_color()
    circle = M5Circle(x, y, r, color)
    circles.append( circle )
    wait_ms(20)
    
while True: 
    i = random.randint( 0, len(circles)-1 )
    circles[i].show() # redraw on top
    wait_ms(100)
```

![รูปภาพ: วงกลมระบายสีและสุ่มพิกัด](https://969412697-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MIHfYo9IV3uTFm2tkDn%2F-MKIqLjKKybSFlA8rxz7%2F-MKIrPneIBZeZdCPpPGb%2Fm5stack_random_circles_demo-2.jpg?alt=media\&token=90725183-10b3-4e8d-9ab5-0a94ae0ddb3c)

ลองเปลี่ยนเป็นรูปกราฟิกทรงสี่เหลี่ยม (**Rectangle**) แบบสุ่มพิกัดเริ่มต้น และสุ่มขนาดของสี่เหลี่ยม (ความกว้างและความยาว) โดยใช้วิธีการสร้างอ็อปเจกต์จาก **`M5Rect`**

```python
from m5stack import *
from m5ui import *
from uiflow import *
import utime as time
import urandom as random

def rand_color():
    r = random.randint(0,255)
    g = (random.randint(0,255) << 8) 
    b = (random.randint(0,255) << 16)
    return (r | g | b)
  
setScreenColor(0x111111)
lcd.clear()
w,h = lcd.screensize()

for i in range(100):
    rw = random.randint(10,50) 
    rh = random.randint(10,50)
    x = random.randint(0,w-rw)
    y = random.randint(0,h-rh)
    color = rand_color()
    M5Rect( x, y, rw, rh, color, color )
```

![รูปภาพ: สี่เหลี่ยมระบายสีและสุ่มพิกัด](https://969412697-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MIHfYo9IV3uTFm2tkDn%2F-MKIqLjKKybSFlA8rxz7%2F-MKIrtqbOjP0BXTfm7m1%2Fm5stack_random_rectangles_demo.jpg?alt=media\&token=d5632ccb-162a-4664-995a-801ff4dde2d5)

## โค้ดตัวอย่างที่ 7

ตัวอย่างถัดไปสาธิตการสุ่มเลขจำนวนเต็มในช่วง **0..200** จำนวน **N=50** แล้วนำข้อมูลที่ได้มาแสดงเป็นกราฟแท่งตามลำดับของข้อมูลในอาร์เรย์

```python
from m5stack import *
from m5ui import *
from uiflow import *
import utime as time
import urandom as random

lcd.clear(0x222222)
w,h = lcd.screensize()
N = 50
values = [ random.randint(1,200) for i in range(N) ]

xs = (w-4)//N
if xs < 1:
   xs = 1
x = (w - xs*N)//2
if x < 0:
    x = 0
y = (h-20)
for v in values:
    rw = 1 if xs < 2 else xs-2
    lcd.rect( x, y-v, rw, v, lcd.DARKGREEN, lcd.GREEN )
    x += xs
```

![รูปภาพ: ตัวอย่างผลลัพธ์ที่ปรากฏบนจอ LCD](https://969412697-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MIHfYo9IV3uTFm2tkDn%2F-MKIsxnT3LE93KU9Zh95%2F-MKItyo6VI2q7cR2QRxK%2Fm5stack_bargraph_demo.jpg?alt=media\&token=f995abca-6c41-475a-8024-cf97826ab2cf)

## โปรเจกต์สาธิต: การเชื่อมต่อกับ ZigBee2MQTT SErver

ตัวอย่างที่ได้เลือกมาสาธิตการใช้งานคือ การเชื่อมต่อกับ **MQTT Broker** ที่ได้จากการติดตั้งโปรแกรม **Mosquitto** สำหรับบอร์ด **Raspberry Pi** และทำงานร่วมกับโปรแกรม [**Zigbee2mqtt**](https://www.zigbee2mqtt.io/) ที่ทำหน้าที่เป็นตัวเชื่อมต่อ (**Bridge**) ระหว่างเครือข่ายไร้สาย **ZigBee** กับ **MQTT Broker**

{% hint style="info" %}
ขั้นตอนการติดตั้งใช้งาน **Zigbee2mqtt** สำหรับบอร์ด **Raspberry Pi** ทางผู้พัฒนาได้เขียนอธิบายอย่างละเอียดแล้ว ดังนั้นศึกษาได้จาก <https://www.zigbee2mqtt.io/getting_started/running_zigbee2mqtt.html>
{% endhint %}

ในกรณีสาธิตนี้ เราจะใช้ **M5 Core** เชื่อมต่อไปยัง **MQTT Broker** พอร์ต **`1883`** ตามหมายเลข **IP Address** ของบอร์ด **Rasbperry Pi** ที่ได้นำมาใช้งาน และจะต้องมีการระบุชื่อผู้ใช้และรหัสผ่านสำหรับ **MQTT User Authentication** ด้วย (ในโค้ดตัวอย่างได้ตั้งค่าไว้เป็น `zigbee2mqtt` : `zigbee2mqtt`)

![รูปภาพ: ตัวอย่างอุปกรณ์ Xiaomi Mijia Sensor Module (Source: Xiaomi)](https://969412697-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MIHfYo9IV3uTFm2tkDn%2F-MKJ22yEIhRL-TLz5tWY%2F-MKJ2v6BaTHMpT-yFXZf%2F%20xiaomi_mijia.jpg?alt=media\&token=010052c4-8879-4b90-825e-8a8a2435b73d)

เมื่อเริ่มต้นการทำงาน อุปกรณ์ **M5 Core** จะเชื่อมต่อกับ **Wi-Fi** เข้าสู่ระบบเครือข่ายโดยอัตโนมัติ (ถ้าเคยได้ตั้งค่าใช้งานอย่างถูกต้องไว้แล้ว) และเชื่อมต่อกับ **MQTT Broker** ได้แล้ว จะทำหน้าที่คอยรับข้อความในหัวข้อ (**Topic**) ตามที่ระบุได้&#x20;

เมื่อมีข้อความซึ่งอยู่ในรูปแบบของ **JSON String** ถูกส่งมาจาก **MQTT Broker** ด้วยรูปแบบการสื่อสาร (**Protocol**) ที่เรียกว่า [**MQTT**](https://mqtt.org/) ข้อมูลในข้อความที่ได้รับ จะถูกนำมาแสดงผลบนจอ **LCD**&#x20;

ในกรณีตัวอย่างนี้เป็นข้อมูลของโมดูลเซ็นเซอร์ **Xiaomi Mijia Temperature and Humidity Sensor** ได้แก่ ค่าอุณหภูมิ ค่าความชื้นสัมพัทธ์ ระดับของแบตเตอรี่ที่เหลืออยู่ และแรงดันของแบตเตอรี่

```python
from m5stack import *
from m5ui import *
from uiflow import *
import ujson as json
import wifiCfg
from m5mqtt import M5mqtt

# set the friendly_name of your Xiaomi Mijia device
friendly_name = '0x00158d00xxxxxxxx'
# set the IP address of your MQTT server
mqtt_host   = '192.168.x.x'
mqtt_port   = 1883
mqtt_user   = 'zigbee2mqtt'
mqtt_passwd = 'zigbee2mqtt'

setScreenColor(0x222222)
lcd.clear()
lcd.font(lcd.FONT_DejaVu24)

m5mqtt = M5mqtt('m5stack', mqtt_host, mqtt_port,
                mqtt_user, mqtt_passwd, 300 )
while True:
    if wifiCfg.wlan_sta.isconnected():
        lcd.print('Wi-Fi connected', lcd.CENTER, 60, lcd.GREENYELLOW)
        break
    else:
        lcd.print('Wi-Fi reconnecting', lcd.CENTER, 100, lcd.RED)
        wifiCfg.reconnect()
        wait_ms(1000)

lcd.font(lcd.FONT_DejaVu18)
lcd.print('Waiting for MQTT messages', lcd.CENTER, 150) 
wait_ms(1000)

def mqtt_sub_cb(topic_data):
    msg = topic_data.decode()
    data =  json.loads(msg)
    battery = data['battery']
    voltage = data['voltage']
    humid = data['humidity']
    temp = data['temperature']
    xpos = 20
    ypos = 10
    lcd.clear()
    lcd.font(lcd.FONT_DejaVu18)
    lcd.rect(0, 0, 320, 36, 0xafafaf, 0xafafaf)
    name = friendly_name[2:]
    lcd.print('Device: ' + name, xpos, ypos, lcd.CYAN)
    ypos += 50
  
    lcd.font(lcd.FONT_DejaVu18)
    lcd.print('Battery [%]', xpos, ypos, lcd.WHITE)
    lcd.font(lcd.FONT_DejaVu24)
    lcd.print(battery, xpos+200, ypos, lcd.GREENYELLOW)
    ypos += 40
  
    lcd.font(lcd.FONT_DejaVu18)
    lcd.print('Voltage [mV]', xpos, ypos, lcd.WHITE)
    lcd.font(lcd.FONT_DejaVu24)
    lcd.print(voltage, xpos+200, ypos, lcd.GREENYELLOW)
    ypos += 40
  
    lcd.font(lcd.FONT_DejaVu18)
    lcd.print('Temperature [C]', xpos, ypos, lcd.WHITE)
    lcd.font(lcd.FONT_DejaVu24)
    lcd.print('%.2f' % float(temp), xpos+200, ypos, lcd.GREENYELLOW)
    ypos += 40
  
    lcd.font(lcd.FONT_DejaVu18)
    lcd.print('Humidity [%RH]', xpos, ypos, lcd.WHITE)
    lcd.font(lcd.FONT_DejaVu24)
    lcd.print('%.2f' % float(humid), xpos+200, ypos, lcd.GREENYELLOW)
  
# subscribe messages on the specified topic
m5mqtt.subscribe( 'zigbee2mqtt/' + friendly_name, mqtt_sub_cb )
# start mqtt thread 
m5mqtt.start()
while True:
    wait_ms(100)
```

![รูปภาพ: การแสดงข้อมูลที่ได้จากโมดูลเซ็นเซอร์บนหน้าจอ LCD](https://969412697-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MIHfYo9IV3uTFm2tkDn%2F-MKJ1-F5Xq9kOkZMN4z0%2F-MKJ1P_tH8W-hdrN_-iI%2Fm5stack_basic_zigbee2mqtt_demo.jpg?alt=media\&token=6c532fe1-682e-4fb1-a6f2-eac0105ccc42)

## กล่าวสรุป

โดยสรุป การใช้งานซอฟต์แวร์ **UIFlow / UIFlow-Desktop IDE** และเฟิร์มแวร์ที่เกี่ยวข้องร่วมกับอุปกรณ์ **M5 Core** (**ESP32**) เพื่อเขียนโปรแกรมด้วยภาษาไมโครไพธอน ก็ถือว่าทำได้สะดวก และสามารถใช้ชุดคำสั่งหรือไลบรรีที่ทาง M5Stack ได้จัดทำไว้แล้ว แต่ก็มีข้อจำกัดอยู่บ้างในการใช้งาน จุดเด่นน่าจะเป็นตัวช่วยในการออกแบบ **UI** แบบกราฟิกที่แสดงผลบนจอ **TFT-LCD** ขนาด **320x240** พิกเซล เราสามารถนำไปประยุกต์ใช้งาน เช่น การสร้างอุปกรณ์ **IoT** ควบคุมและแสดงผลที่มีขนาดเล็กสำหรับผู้ใช้และเชื่อมต่อ **Wi-Fi** ได้

{% hint style="info" %}
**เผยแพร่ภายใต้ลิขสิทธิ์**\
**Attribution-ShareAlike 4.0 International (**[**CC BY-SA 4.0**](https://creativecommons.org/licenses/by-sa/4.0/)**)**
{% endhint %}
