[TH] How to build MicroPython for esp32-s2.

บทความนี้กล่าวถึงการคอมไพล์ (build) และใช้งาน MicroPython สำหรับไมโครคอนโทรลเลอร์ esp32-s2 ที่เป็นบอร์ด TTGO ESP32-S2 V1.1 หรือ TTGO ESP32-S2-WOOR V1.1 ซึ่งมีพอร์ต USB แบบ Type-C ที่รองรับการทำงานผ่าน CH340C และแบบ OTG ด้วยการใช้ดิปสวิตช์ดังภาพที่ 1 ทำให้สามารถใช้ MicroPython ได้ เนื่องจากการโปรแกรมชิพใช้การโปรแกรมผ่านทางวงจรของ CH340 และการใช้งานภาษาไพธอนจะต้องอาศัยพอร์ตที่ทำงานแบบ OTG

TTGO ESP32-S2 V1.1
ภาพที่ 1 TTGO ESP32-S2 V1.1

TTGO ESP32-S2 V1.1

TTGO ESP32-S2 V1.1 มีคุณสมบัติเป็นดังนี้

  • ใช้ชิพเซ็ต espressif-esp32-s2
  • หน่วยความจำแฟลช ขนาด 4MB
  • หน่วยความจำ SRAM ขนาด 320KB
  • หน่วยความจำ SPIRAM ขนาด 8MB
  • ปุ่ม
    • Power Switch
    • Reset button
    • Boot button
    • Customize
    • DPI Switch
  • ช่องอ่านการ์ด microSD
  • โมดูล USB-to-TTL ใช้ชิพ CH340C
  • XTal บนบอร์ด 32.768KHz
  • แรงดันที่รองรับ 2.7V-3.6V
  • ช่วงอุณหภูมิที่ทำงานได้  -40℃ ~ +85℃
  • มีวงจรเชื่อมต่อแบตเตอรีภายนอก
    • รองรับแหล่งจ่ายไฟจากพอร์ต USB ที่แรงดัน 5V กระแส 1A
    • กระแสสำหรับชาร์จแบตเตอรี 500mA
    • แบตเตอรีที่ใช้งานได้ต้องเป็นแรงดันในช่วง 3.7-4.2V
  • สามารถต่อสายอากาศภายนอกได้

ขั้นตอน

ก่อนจะคอมไพล์ผู้อ่านจะต้องมีชุด ESP-IDF ก่อนซึ่งสามารถอ่านได้จากบทความก่อนหน้านี้ หรือจากตัวอย่างการคอมไพล์สำหรับ ESP32 ผ่านทาง WSL เมื่อมีคอมไพล์เลอร์ติดตั้งในระบบเป็นที่เรียบร้อยก็มาสู่ ขั้นตอนการคอมไพล์ MicroPython เป็นดังนี้

ดาวน์โหลด

ให้ดาวน์โหลดไฟล์ต้นฉบับของ MicroPython จาก github ด้วยคำสั่งต่อไปนี้

git clone --recurse-submodules https://github.com/micropython/micropython.git

ตัวอย่างผลลัพธ์ของการทำงานเป็นดังภาพที่ 2

git clone --recurse-submodules https://github.com/micropython/micropython.git
ภาพที่ 2 ตัวอย่างผลลัพธ์จากการสั่ง git clone

เมื่อดาวน์โหลดเป็นที่เรียบร้อยให้ใช้คำสั่งย้ายเข้าไปในโฟลเดอร์ของ micropython ดังนี้

cd ~/micropython

คอมไพล์ mpy-cross

ตัวคอมไพล์ภาษาไพธอนของ MicroPython หรือ mpy-cross ให้เป็นไบต์โค้ดที่มีนามสกุลเป็น .mpy ซึ่งมีประโยชน์ในแง่ของการทำให้โค้ดนั้นมีขนาดเล็กลงสะดวกต่อการนำไปใช้เนื่องจากประหยัดพื้นที่ของรอม/แรม และไม่ต้องประมวลผลขณะที่เรียกทำงาน นอกจากนี้ ในการคอมไพล์ MicroPython เองก็ต้องใช้ตัว mpy-cross ด้วยเช่นกัน ดังนั้น สิ่งที่ต้องทำในขัเนตอนที่ 2 คือ คอมไพล์ mpy-cross เพื่อเป็นเครื่องมือสำหรับคอมไพล์ MicroPython ต่ออีกชั้นหนึ่ง โดยเข้าไปที่ mpy-xxx หลังจากนั้นสั่ง make ดังนี้

cd mpy-cross

make clean

make

เมื่อคอมไพล์เสร็จจะพบไฟล์ชื่อ mpy-cross

คอมไพล์ submodules ของ esp32

เมื่อมี mpy-cross แล้ว ขั้นตอนต่อไปคือสร้างไลบรารีที่จะถูกเรียกใช้ด้วย esp32-s2 โดยเข้าไปที่ ports ของ ESP32 ดังนี้

cd ~/micropython/ports/esp32

หลังจากนั้นสั่งคอมไพล์ด้วยคำสั่งดังต่อไปนี้

make  clean
make  submodules

คอมไพล์ MicroPython

คำสั่งสำหรับคอมไพล์ MicroPython เพื่อใช้กับ ESP32-S2 คือ กำหนดให้บอร์ดที่ใช้งานเป็น ESP32_S2_WROVER ดังนี้

make BOARD=ESP32_S2_WROVER

เมื่อการคอมไพล์เสร็จสิ้นโดยไม่เกิดข้อผิดพลาดเกี่ยวกับ ESP-IDF หรือลืม mpy-cross จะได้โฟลเดอร์ชื่อ xxx

อัพโหลด

เมื่อคอมไพล์เรียบร้อย ขั้นตอนต่อไปคืออัพโหลดเข้าบอร์ด ซึ่งต้องตรวจสอบการตั้งค่าของสวิตช์ให้เป็นดังภาพที่ 3 หลังจากนั้นสั่งงานดังนี้

~/.espressif/python_env/idf4.4_py3.8_env/bin/python ../../../esp-idf/components/esptool_py/esptool/esptool.py -p (PORT) -b 460800 --before default_reset --after no_reset --chip esp32s2  write_flash --flash_mode dio --flash_size detect --flash_freq 80m 0x1000 build-ESP32_S2_WROVER/bootloader/bootloader.bin 0x8000 build-ESP32_S2_WROVER/partition_table/partition-table.bin 0x10000 build-ESP32_S2_WROVER/micropython.bin

โดยให้เปลี่ยน (PORT) เป็นไดเร็กทีรีของพอร์ต เช่น /dev/ttyUSB0 เป็นต้น

USB MOde
ภาพที่ 3 การตั้งโหมดเป็น USB

การใช้งาน

เมื่ออัพโหลดเฟิร์มแวร์เป็นที่เรียบร้อย ให้เปลี่ยนโหมดเป็น OTG โดยการเลื่อนสวิตช์ให้เป็นดังภาพที่ 4

OTG Mode
ภาพที่ 4 การตั้งโหมดเป็น OTG

ทดสอบการทำงาน

หลังจากเปลี่ยนโหมดเป็น OTG ตามภาพที่ 4 ให้จ่ายไฟเข้าบอร์ด หลังจากนั้นเข้าโปรแกรม thonny และเปลี่ยนบอร์ดเป็น ESP32 ด้วยการเข้าเมนู Run และเลือก Select interpreter… ตามภาพที่ ภาพที่ 5 และหลังจากนั้นเลือกใช้บอร์ดเป็น Micropython (ESP32) และพอร์ตสื่อสารดังภาพที่ 6

Run/Select interpreter...
ภาพที่ 5 เมนู Run
Interpreter/MicroPython (ESP32)
ภาพที่ 6 หน้าจอ Select interpreter…

เมื่อคลิกที่ปุ่ม OK และการตั้งค่าถูกต้องจะเป็นหน้าจอเหมือนกับภาพที่ 6

MicroPython v1.17-84-gba940250a on 2021-10-17; ESP32-S2-WROVER with ESP32-S2
ภาพที่ 7 รายงานผลรุ่นของ MicroPython

ตัวอย่างโปรแกรมอ่านข้อมูลของบอร์ด TTGO ESP32-S2 V1.1 และทดลองหาค่าจำนวนเฉพาะเขียนได้ดังนี้

##################################################################################
# coreInfo
# JarutEx (https://www.jarutex.com)
##################################################################################
import gc
import os
import sys
import time as tm
import machine as mc

##################################################################################
# system setting
##################################################################################
gc.enable()
gc.collect()

mc.freq(240000000)

##################################################################################
# show_hw_info()
##################################################################################
def show_hw_info():
    uname = os.uname()
    mem_total = gc.mem_alloc()+gc.mem_free()
    free_percent = "("+str((gc.mem_free())/mem_total*100.0)+"%)"
    alloc_percent = "("+str((gc.mem_alloc())/mem_total*100.0)+"%)"
    stat = os.statvfs('/flash')
    block_size = stat[0]
    total_blocks = stat[2]
    free_blocks  = stat[3]
    rom_total = (total_blocks * block_size)/1024
    rom_free = (free_blocks * block_size)/1024
    rom_usage = (rom_total-rom_free)
    rfree_percent = "("+str(rom_free/rom_total*100.0)+"%)"
    rusage_percent = "("+str(rom_usage/rom_total*100.0)+"%)"
    print("ID ............:",mc.unique_id())
    print("Platform ......:",sys.platform)
    print("Version .......:",sys.version)
    print("Memory")
    print("   total ......:",mem_total/1024,"KB")
    print("   usage ......:",gc.mem_alloc()/1024,"KB",alloc_percent)
    print("   free .......:",gc.mem_free()/1024,"KB",free_percent)
    print("ROM")
    print("   total ......:", rom_total,"KB" )
    print("   usage ......:", rom_usage,"KB",rfree_percent )
    print("   Free .......:", rom_free,"KB",rusage_percent )
    print("system name ...:",uname.sysname)
    print("node name .....:",uname.nodename)
    print("release .......:",uname.release)
    print("version .......:",uname.version)
    print("machine .......:",uname.machine)
    print("Frequency .....:",mc.freq())


##################################################################################
# is_prime()
##################################################################################
def is_prime(x):
    i = 2
    while (i < x):
        if x%i == 0:
            return False
        i = i+1
    if (i == x):
        return True
    return False

##################################################################################
# test_prime_number()
##################################################################################
def test_prime_number(maxN):
    counter = 0
    t0 = tm.ticks_ms()
    for n in range(2, maxN):
        if is_prime(n):
            counter+=1
    t1 = tm.ticks_ms()
    print("Found {} in {} msecs.".format(counter,abs(t1-t0)))

    
##################################################################################
# main program
##################################################################################
try:
    show_hw_info()
    test_prime_number(2000)
except KeyboardInterrupt:
    pass
print("end of program")


ตัวอย่างผลลัพธ์ของการทำงานเป็นดังภาพที่ 8

result
ภาพที่ 8 ตัวอย่างผลลัพธ์ของโปรแกรม

สรุป

จากบทความนี้จะพบว่าการสร้าง MicroPython เพื่อใช้กับไมโครคอนโทรลเลอร์ ESP32-S2 นั้นมีขั้นตอนเหมือนกับ ESP32 แต่จุดที่แตกต่างคือขั้นตอนของการสลับโหมดทำงานของพอร์ต USB ตามเงื่อนไขดังนี้

  • การติดตั้ง MicroPython จะต้องเป็นโหมด USB
  • การใช้งาน MicroPython จะต้องเป็นโหมด OTG

ส่วนหลักภาษาเขียนโปรแกรมยังคงเป็นภาษาไพธอนเหมือนกับ ESP32 และ สุดท้ายขอให้สนุกกับการเขียนโปรแกรมครับ

ท่านใดต้องการพูดคุยสามารถคอมเมนท์ได้เลยครับ

แหล่งอ้างอิง

  1. MicroPython
  2. LILYGO® TTGO T8 ESP32-S2 V1.1

(C) 2020-2021, โดย อ.ดนัย เจษฎาฐิติกุล/อ.จารุต บุศราทิจ
ปรับปรุงเมื่อ 2021-10-17, 2021-12-30