📃
micropython
  • Programming with MicroPython
  • MicroPython for BBC Micro:bit
    • BBC Micro:bit Overview
    • Micro:bit Code Examples
  • MicroPython for STM32
    • MicroPython Firmware Flashing for STM32
    • STM32 Code Examples
  • MicroPython for ESP32
    • WebREPL
    • ESP32 Code Examples
    • How To Blink LEDs with ESP32
    • ESP32 Programming with M5Stack Core
    • ESP32 with Dual-Channel DAC Output
    • ESP32 Networking
  • Arduino C/C++ versus MicroPython
  • Building MicroPython Firmware
  • MicroPython Benchmarking
  • MicroPython for RP2040 Pico
    • RPi Pico RP2040 Code Examples
    • PIO Programming
    • PIO Signaling and Measurement
  • CircuitPython
    • CircuitPython with Piper Make
    • CircuitPython for SAMD21
    • SAMD21 Code Examples
    • CircuitPython for STM32
    • STM32 Code Examples
    • CircuitPython for Pico RP2040
  • List of PDF Files
Powered by GitBook
On this page
  • แนะนำอุปกรณ์ ESP32-M5Stack
  • ULFlow IDE: Block-based Programming
  • การติดตั้ง UIFlow Firmware โดยใช้โปรแกรม M5Burner
  • การติดตั้ง UIFlow Firmware โดยใช้โปรแกรม esptool.py
  • การตั้งค่า Wi-Fi และทำงานในโหมด Internet
  • การใช้งาน UIFlow IDE แบบออนไลน์
  • การทำงานในโหมด USB และใช้งานร่วมกับ Thonny Python IDE
  • ตัวอย่างโค้ดที่ 1
  • ตัวอย่างโค้ดที่ 2
  • โค้ดตัวอย่างที่ 3
  • โค้ดตัวอย่างที่ 4
  • โค้ดตัวอย่างที่ 5
  • โค้ดตัวอย่างที่ 6
  • โค้ดตัวอย่างที่ 7
  • โปรเจกต์สาธิต: การเชื่อมต่อกับ ZigBee2MQTT SErver
  • กล่าวสรุป

Was this helpful?

  1. MicroPython for ESP32

ESP32 Programming with M5Stack Core

แนะนำการอุปกรณ์สมองกลฝังตัวที่เรียกว่า M5Stack M5 Core ซึ่งใช้ตัวประมวลผลเป็นชิป ESP32 และเขียนโปรแกรมได้โดยใช้ภาษา MicroPython และใช้เฟิร์มแวร์ของ M5Stack UIFlow

PreviousHow To Blink LEDs with ESP32NextESP32 with Dual-Channel DAC Output

Last updated 4 years ago

Was this helpful?

แนะนำอุปกรณ์ ESP32-M5Stack

(Shenzhen, China) ได้พัฒนาและจำหน่ายโมดูลหรืออุปกรณ์อิเล็กทรอนิกส์ที่ใช้ เป็นตัวประมวลผลหลัก แบ่งออกได้เป็นหลายรุ่น เช่น M5 Core ( / / ), และ รองรับการเขียนโปรแกรมด้วย 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)

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

ULFlow IDE: Block-based Programming

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

การติดตั้ง UIFlow Firmware โดยใช้โปรแกรม M5Burner

เราจะไม่ใช้ไฟล์สำหรับติดตั้งเฟิร์มแวร์ 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 และทำขั้นตอนอัปโหลดไฟล์เฟิร์มแวร์

การติดตั้ง UIFlow Firmware โดยใช้โปรแกรม esptool.py

จากขั้นตอนที่แล้ว จะสังเกตได้ว่า 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

การตั้งค่า 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 แบบออนไลน์

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

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

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

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

การทำงานในโหมด USB และใช้งานร่วมกับ Thonny Python IDE

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

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

เสียบสาย 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

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

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

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

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) ของระบบที่ใช้ในการแสดงข้อความตามรายการที่กำหนดไว้ในอาร์เรย์

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 เมื่อเกิดเหตุการณ์ดังกล่าว (มีเกิดการกดปุ่มหรือปล่อยปุ่มในแต่ละครั้ง)

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) เป็นต้น

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 เพื่อกำหนดระยะเวลาในการสร้างสัญญาณเสียงแล้วปิดเสียงหลังจากนั้น

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
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 ของอุปกรณ์ ก็สามารถใช้คำสั่งดังนี้

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

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())

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)

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

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 )

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

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

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

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

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

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

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

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)

กล่าวสรุป

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

โมดูล M5 Basic และ M5 Gray จะมีบอร์ดฐานปิดด้านล่าง เรียกว่า ซึ่งมีแบตเตอรี LiPo (110 mAh @ 3.7V) อยู่ภายใน และมีคอนเนกเตอร์ที่เรียกว่า M-Bus และทั้งสี่ด้านมี Pin Headers เอาไว้สำหรับต่อสายเชื่อมต่อกับอุปกรณ์หรือวงจรภายนอกได้

เพื่อสนับสนุนการเขียนโปรแกรม บริษัท ได้พัฒนาซอฟต์แวร์ () ซึ่งเป็น Web-based IDE และใช้งานแบบออนไลน์ (มีเวอร์ชัน ให้ดาวน์โหลดและติดตั้งใช้งานแบบ Offline ได้เช่นกัน)

ซอฟต์แวร์ดังกล่าวใช้สำหรับการเขียนโปรแกรมด้วยวิธีการต่อบล็อกตามรูปแบบของ และสามารถใช้ในการออกแบบกราฟิกโดยใช้ หรือจะเปลี่ยนโหมดไปใช้ภาษาไมโครไพธอนในการเขียนโค้ดก็ได้

สำหรับผู้เริ่มต้น การใช้บล็อกคำสั่งของ แล้วแปลงให้เป็นโค้ด อาจเป็นวิธีหนึ่งที่ช่วยในการศึกษา และทำให้เห็นตัวอย่างการใช้คำสั่งได้ง่ายขึ้น นอกเหนือจากการศึกษาจากเอกสารเกี่ยวกับ API ของ และไลบรารีที่เกี่ยวข้อง

‍‍การติดตั้งไฟล์เฟิร์มแวร์ไปยัง M5 Core สามารถใช้โปรแกรม หรือ UI (มีให้ดาวน์โหลดสำหรับ Windows 64-bit, Linux และ Mac OS X) ในบทความนี้จะสาธิตวิธีการใช้โปรแกรมชื่อ esptool ที่ทำงานโดยใช้ Python 3 เป็นอีกหนึ่งวิธี

ในกรณีที่ต้องการลองใช้ แบบออนไลน์ จะต้องตั้งค่า Wi-Fi (SSID และ Password) ให้กับอุปกรณ์ก่อน เพื่อให้สามารถเชื่อมต่อไปยังอินเทอร์เน็ตได้

การใช้ซอฟต์แวร์ UIFlow IDE จะต้องมีการระบุ ซึ่งเป็นเลขฐานสิบหกที่มีจำนวน 8 หลัก (8-Digit Hex String) และมีค่าแตกต่างกันไปสำหรับแต่ละอุปกรณ์ เราจะทราบได้ก็เมื่อได้ติดตั้ง M5 Firmware ลงในอุปกรณ์ M5 Core แล้ว

ถ้าจะเขียนโค้ดแบบ Offline เช่น ใช้ UIFlow Desktop IDE (ดาวน์โหลดไฟล์ติดตั้งได้จาก ) หรือโปรแกรมอื่นเช่น หรือ จะต้องทำให้อุปกรณ์อยู่ในโหมด USB

ถัดไปเป็นการลองใช้โปรแกรม สำหรับระบบปฏิบัติการ Windows (ถ้ายังไม่มี ให้ดาวน์โหลดไฟล์และติดตั้งใช้งานก่อน)

หรือเราจะใช้คำสั่ง แทนก็ได้ เช่น

เราสามารถเปลี่ยนมาใช้ M5Circle() ซึ่งอยู่ในโมดุล เพื่อสร้างอ็อปเจกต์ (Object) เป็นรูปวงกลมแทนการใช้คำสั่ง lcd.circle()

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

ขั้นตอนการติดตั้งใช้งาน Zigbee2mqtt สำหรับบอร์ด Raspberry Pi ทางผู้พัฒนาได้เขียนอธิบายอย่างละเอียดแล้ว ดังนั้นศึกษาได้จาก

เมื่อมีข้อความซึ่งอยู่ในรูปแบบของ JSON String ถูกส่งมาจาก MQTT Broker ด้วยรูปแบบการสื่อสาร (Protocol) ที่เรียกว่า ข้อมูลในข้อความที่ได้รับ จะถูกนำมาแสดงผลบนจอ LCD

เผยแพร่ภายใต้ลิขสิทธิ์ Attribution-ShareAlike 4.0 International ()

Base CORE Bottom
M5Stack
UIFlow
http://flow.m5stack.com
UIFlow Desktop IDE
Google Blockly
UI Designer
UIFlow
UIFlow
M5 Burner
Flow Desktop IDE
UIFlow
API Key
https://m5stack.com/pages/download
Thonny IDE
Mu Editor
Thonny IDE
speaker
m5ui
Zigbee2mqtt
https://www.zigbee2mqtt.io/getting_started/running_zigbee2mqtt.html
MQTT
CC BY-SA 4.0
M5Stack.com
Espressif ESP32
BASIC
GRAY
FIRE
M5Stick-C
M5 ATOM
รูปภาพ: M5 Core / Kit Products (Source: M5Stack)
รูปภาพ: M5Stack BASIC (Source: M5Stack)
รูปภาพ: M5Stack Base Core Bottom
รูปภาพ: M5Stack FIRE
รูปภาพ: การใช้งาน UI Designer แบบออนไลน์
รูปภาพ: ขั้นตอนเลือกและดาวน์โหลดไฟล์เฟิร์มแวร์
รูปภาพ: M5Burner v2.2.7
รูปภาพ: ตัวอย่างข้อความที่ปรากฏเมื่อทำขั้นตอนใน M5Burner
รูปภาพ: การเปิดใช้งานโหมด WiFi AP ของอุปกรณ์
รูปภาพ: การเชื่อมต่ออุปกรณ์ M5Stack Core กับเครือข่าย Wi-Fi
รูปภาพ: แสดงสถานะเชื่อมต่อกับ M5 Server (flow.m5stack.com) ได้สำเร็จ
รูปภาพ: ระบุค่า API Key ของอุปกรณ์ก่อนเริ่มต้นใช้งาน
รูปภาพ: M5 UIFlow (Cloud) เชื่อมต่อกับอุปกรณ์ได้แล้ว
รูปภาพ: การตั้งค่าจากเมนูเพื่อเข้าสู่โหมด USB
รูปภาพ: ตัวอย่างการใช้งาน UIFlow Desktop IDE แบบ Offline
รูปภาพ: ตั้งค่า Options สำหรับ Thonny IDE เพื่อเชื่อมต่อกับอุปกรณ์
รูปภาพ: Thonny IDE เมื่อเชื่อมต่อกับ MicroPython REPL ได้สำเร็จ
รูปภาพ: ตัวอย่างผลลัพธ์ที่ปรากฏบนจอ LCD (วงกลมสุ่มพิกัด)
รูปภาพ: วงกลมระบายสีและสุ่มพิกัด
รูปภาพ: สี่เหลี่ยมระบายสีและสุ่มพิกัด
รูปภาพ: ตัวอย่างผลลัพธ์ที่ปรากฏบนจอ LCD
รูปภาพ: ตัวอย่างอุปกรณ์ Xiaomi Mijia Sensor Module (Source: Xiaomi)
รูปภาพ: การแสดงข้อมูลที่ได้จากโมดูลเซ็นเซอร์บนหน้าจอ LCD