# MicroPython for ESP32

**MicroPython** (<https://micropython.org/>**)** เกิดจากความต้องการที่จะนำภาษา **Python 3** มาใช้กับไมโครคอนโทรลเลอร์ขนาด 32 บิต เริ่มต้นการพัฒนาตั้งแต่ราวปีค.ศ. **2014** และในปัจจุบันก็ได้มีการปรับให้สามารถทำงานได้กับไมโครคอนโทรลเลอร์หลายตระกูล เช่น **ARM Cortex M Series** และมีตัวอย่างดังนี้ (ดูได้จาก [**MicroPython Ports**](https://github.com/micropython/micropython/tree/master/ports))

* **STMicroelectronics STM32F4 / F7 / L4**
* **Atmel / Microchip ATSAMD21 / D51**
* **Nordic nRF51 / nRF52**&#x20;
* **Espressif ESP8266 / ESP32**&#x20;

นอกเหนือจาก **STM32** แล้ว ได้มีการนำไมโครไพธอนมาใช้กับบอร์ดไมโครคอนโทรลเลอร์ **ESP8266** (เริ่มประมาณปีค.ศ. 2016) และถัดไปเป็น **ESP32** ซึ่งทั้งสองกรณีเป็นชิป **SoC** ที่ไม่ได้ใช้ซีพียูตระกูล **ARM Cortex-M Series** และมีจุดเด่นคือ ความสามารถในการเชื่อมต่อ **Wi-Fi (2.4GHz)** ได้ ทำให้เชื่อมต่อกับระบบเครือข่ายและอินเทอร์เน็ตได้สะดวก ดังนั้นจึงเหมาะสำหรับการนำมาสร้างอุปกรณ์หรือระบบ **IoT (Internet of Things)**

เนื้อหาในส่วนนี้จะกล่าวถึง การใช้บอร์ด **ESP32** สำหรับไมโครไพธอน  เนื่องจาก **ESP32** มีประสิทธิภาพและความสามารถทำงานได้สูงกว่า **ESP8266** และในปัจจุบันก็มีบอร์ดหรือโมดูล **ESP32** ให้เลือกใช้ได้หลายรูปแบบ &#x20;

แนะนำให้ศึกษาเพิ่มเติมจากแหล่งข้อมูลอ้างอิงต่อไปนี้

* **MicroPython Online Documentation:** <http://docs.micropython.org/en/latest/>
* **Quick Reference for the ESP32:** <https://docs.micropython.org/en/latest/esp32/quickref.html>
* **MicroPython Libraries:** <https://docs.micropython.org/en/latest/library/index.html>

## การเลือกใช้เฟิร์มแวร์ของไมโครไพธอนสำหรับบอร์ด ESP32

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

บอร์ด **ESP32** บางรุ่น มีวงจรอย่างเช่น **3.7V LiPo Battery Charger** สามารถใช้กับแบตเตอรี **LiPo** ได้ หรือช่องเสียบการ์ดหน่วยความจำแบบ **microSD** ทำให้มีพื้นที่เพิ่มในการเก็บข้อมูลลงในไฟล์ เช่น ไฟล์รูปภาพ หรือมีวงจรเพื่อใช้งานร่วมกับโมดูลจอภาพแบบ **TFT** หรือ **OLED** หรือ **e-Ink (e-Paper)** เพื่อใช้เป็นส่วนแสดงผลแบบกราฟิก เป็นต้น

![รูปภาพ: TTGO T8 ESP32 - Pin Map (Source: LilyGO) ](https://969412697-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MIHfYo9IV3uTFm2tkDn%2F-MKL7eE4Bb6XBsU-swZZ%2F-MKL8TdYBw2dOQBDilif%2Flilygo_ttgo-t8-esp32.jpg?alt=media\&token=d1ea1269-4664-479d-870f-c66ad68e2d8b)

![รูปภาพ: TTGO T8 ESP32 WROVER with PSRAM Pin Map (Source: LilyGO)](https://969412697-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MIHfYo9IV3uTFm2tkDn%2F-MQoM8nSDWaAPkeAk1Gn%2F-MQoPivo1XyW96VS1Now%2Fttgo_esp32_wrover_t8_8mb_psram_pinmap.png?alt=media\&token=2ed31afd-2298-4c28-ba4d-a49a2367d783)

บอร์ด **ESP32** ส่วนใหญ่ ที่เป็น **Development Board** ก็มีรูปแบบที่เหมาะสำหรับการเสียบขาลงบนเบรดบอร์ดได้ ทำให้ต่อวงจรใช้งานร่วมกับโมดูลหรือวงจรอิเล็กทรอนิกส์อื่นได้อย่างสะดวก

เราสามารถจำแนกบอร์ด **ESP32** ได้เป็นสองกลุ่ม เรียกว่า **non-psRAM** กับ **psRAM-enabled** ซึ่งขึ้นอยู่กับว่า มีการเพิ่มชิป **psRAM (pseudo-static RAM)** ภายนอกหรือไม่ มีความจุตั้งแต่ **4MB** หรือ **8MB** เป็นต้น บอร์ด **ESP32** ที่มี **psRAM** ก็มักจะมีราคาสูงกว่าบอร์ดที่ไม่มี

{% hint style="info" %}
การเลือกใช้เฟิร์มแวร์ของ **MicroPython** เพื่อนำมาใช้กับบอร์ดไมโครคอนโทรลเลอร์ที่ใช้ชิปหรือโมดูล **ESP32** แบ่งเป็น **GENERIC** แต่ถ้ามี **psRAM** จะเรียกว่า **GENERIC-PSRAM** เวอร์ชันล่าสุดสามารถดาวน์โหลดได้จากเว็บ <http://micropython.org/download/esp32/>
{% endhint %}

*“Non-SPIRAM firmware will work on any board, whereas SPIRAM enabled firmware will only work on boards with 4MiB of external pSRAM.”*

**ข้อสังเกต**: เฟิร์มแวร์ของ **ESP32** นอกจากแบ่งเป็น “**GENERIC**” และ “**GENERIC-PSRAM**” ให้เลือกแล้ว (อ้างอิงตามเวอร์ชัน **v1.13** ในขณะที่จัดทำเอกสารนี้) ยังมีการแบ่งเป็น 2 ตัวเลือกอีก ขึ้นอยู่กับว่า มีการใช้ **ESP-IDF v3.x** หรือ **ESP-IDF v4.x** ในการคอมไพล์โค้ด

* **Firmware built with ESP-IDF v3.x, with support for BLE, LAN and PPP**
* **Firmware built with ESP-IDF v4.x, with support for BLE, but no LAN or PPP**

![รายการไฟล์เฟิร์มแวร์ (built with ESP-IDF v3.x) สำหรับ ESP32](https://969412697-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MIHfYo9IV3uTFm2tkDn%2F-MK7sGKKwZ49JVH3hzhJ%2F-MK7t0-CLCe4koGMfG3J%2Fmicropython_esp32_firmware-1.png?alt=media\&token=30e87054-0570-4ac5-a927-2da16efd16b6)

![รายการไฟล์เฟิร์มแวร์ (built with ESP-IDF v4.x) สำหรับ ESP32](https://969412697-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MIHfYo9IV3uTFm2tkDn%2F-MK7tgpVWPDk3vhhCyta%2F-MK7uGZorI0JWtGmKeYH%2Fmicropython_esp32_firmware-2.png?alt=media\&token=127e4de0-4707-40b3-8614-652b381678e2)

## การติดตั้งเฟิร์มแวร์เพื่อใช้งานไมโครไพธอน

การติดตั้งเฟิร์มแวร์สำหรับ **MicroPython** ไปยังบอร์ด **ESP32** จะอาศัยโปรแกรม **Python Script** ที่มีชื่อว่า `esptool.py` และเชื่อมต่อระหว่างคอมพิวเตอร์ผ่านพอร์ต **USB-to-serial** ไปยังบอร์ด **ESP32**

ดังนั้นถ้าจะใช้ `esptool.py` คอมพิวเตอร์จะต้องมี **Python 3.x** ติดตั้งไว้ใช้งานพร้อมแล้ว (สำหรับผู้ใช้ **Windows** สามารถดาวน์โหลดไฟล์สำหรับติดตั้ง **Python**  ได้จาก <https://www.python.org/downloads/>)

การติดตั้ง `esptool.py` ก็ทำได้ไม่ยาก โดยใช้คำสั่ง `pip` สำหรับ **Linux** (แต่ถ้าใช้ **Windows** ให้ทำคำสั่งผ่าน **CMD Shell**)

```
$ pip3 install --user esptool
```

จากนั้นให้ลองทำคำสั่งต่อไปนี้ เพื่อดูว่า มีการติดตั้ง `esptool` ไว้แล้วหรือไม่ และเป็นเวอร์ชันใด

```
$ pip3 show -f esptool
```

เมื่อเชื่อมต่อบอร์ด **ESP32** กับคอมพิวเตอร์ของผู้ใช้ ผ่านทาง **USB** ให้ลองทำคำสั่งต่อไปนี้ เพื่ออ่านค่า **MAC Address** จากบอร์ดดังกล่าว (ไม่จำเป็นต้องระบุหมายเลข **COM port** เมื่อทำคำสั่งดังกล่าว จะมีการค้นหาพอร์ตที่เชื่อมต่อกับบอร์ด **ESP32** โดยอัตโนมัติ ถ้ามีเพียงบอร์ดเดียวที่เชื่อมต่ออยู่)

```
$ python3 -m esptool read_mac
```

การใช้คำสั่ง `esptool` เพื่อติดตั้งเฟิร์มแวร์ไปยังบอร์ด **ESP32** จะมีสองขั้นตอนตามลำดับคือ ขั้นแรกเป็นการลบหน่วยความจำ **Flash (erase flash)** และจากนั้นจึงเป็นการเขียนข้อมูลจากไฟล์ (**MicroPython Firmware**) เช่น ใช้ชื่อว่า **`firmware.bin`** ไปยังหน่วยความจำ **Flash (write flash)** ตามคำสั่งตัวอย่างในรูปแบบต่อไปนี้

```
$ python3 -m esptool --chip esp32 \
  --port /dev/ttyUSB0 erase_flash

$ python3 -m esptool --chip esp32 \
  --port /dev/ttyUSB0 --baud 460800 \
  write_flash -z 0x1000 firmware.bin 
```

ข้อสังเกต: ถ้าใช้ **Linux** ชื่อของพอร์ตที่ปรากฏ เช่น `/dev/ttyUSB0` แต่ถ้าเป็น **Windows** จะเป็นชื่อที่ขึ้นต้นด้วย `COM`

![รูปภาพ: ตัวอย่างข้อความเมื่อทำคำสั่ง esptool โดยใช้ Raspberry Pi Desktop](https://969412697-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MIHfYo9IV3uTFm2tkDn%2F-MKLg_EVinVDgJ5yYu6K%2F-MKNheH_i_ORScr3Xxhg%2Frpi4_esp32_spiram_flashing.png?alt=media\&token=d4ce4f2f-87e2-4adb-a4cd-edff49b3a40e)

## การใช้งานร่วมกับ Thonny IDE&#x20;

ถัดไปให้ลองใช้โปรแกรม เช่น [**Thonny IDE**](https://thonny.org/) เชื่อมต่อกับ **MicroPython REPL** ของบอร์ด **ESP32** โดยไปยังเมนูคำสั่ง **Run > Select Interpreter** แล้วตั้งค่าตามตัวอย่าง เลือกพอร์ตให้ตรงกับอุปกรณ์ **ESP32** ที่เชื่อมต่ออยู่

บอร์ด **ESP32** ที่ได้นำมาทดลองใช้งานคือ [**TTGO T8 ESP32 v1.3**](https://github.com/LilyGO/TTGO-T8-ESP32) **(ESP32, 4MB Flash, 4MB psRAM)** ผลิตโดยบริษัท **LilyGO** ผลิตในประเทศจีน สามารถเสียบลงบนเบรดบอร์ดได้ และมี **MicroSD Slot** ในกรณีที่ต้องการใช้การ์ดหน่วยความจำ เพื่อเก็บบันทึกข้อมูลอยู่ในรูปของไฟล์ต่าง ๆ

![รูปภาพ: เมนู Run > Select Interpreter](https://969412697-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MIHfYo9IV3uTFm2tkDn%2F-MKL6b9L9v2TzsW1pT57%2F-MKL7-rn_Vzugp3PVshn%2Fthonny_esp32_connect.png?alt=media\&token=4ef32472-078c-4919-b885-80ebcb1b35f1)

![รูปภาพ: Thonny IDE v3.2.6 ที่ใช้งานร่วมกับบอร์ด Raspberry Pi Desktop](https://969412697-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MIHfYo9IV3uTFm2tkDn%2F-MKL21as1Sb3wqtPPtmo%2F-MKL372zNRYFe3BozkF7%2Fthonny_rpi4_esp32_repl.png?alt=media\&token=9dffce42-96f7-4c52-a325-0ab8b7c4e20c)

ภายในระบบไฟล์ของ **MicroPython-ESP32** ภายใต้ไดเรกทอรี `/flash` จะมีไฟล์ที่ได้มีการใส่มาให้แล้วคือ `boot.py` และ `main.py` ทุกครั้งมีการรีเซตระบบ จะมีการทำคำสั่ง **Python** (ถ้ามี) ในไฟล์ `boot.py` แล้วตามด้วย `main.py` (สำหรับ **Main Application/Script**) ตามลำดับ

ยกตัวอย่างเช่น ในไฟล์ `boot.py` เราสามารถใส่คำสั่งที่เชื่อมต่อ **ESP32** ด้วย **Wi-Fi** ไปยังอุปกรณ์ **Wireless Access Point (AP)** ตามที่กำหนดไว้โดยอัตโนมัติ หรือ มีคำสั่งให้ทำขั้นตอน **microSD Mounting** โดยอัตโนมัติ เป็นต้น

## การเขียนและรันโค้ดไมโครไพธอนโดยใช้ Thonny IDE

ถัดไปลองมาเขียนโค้ดไมโครไพธอน และบันทึกลงไฟล์โดยใช้ชื่อ `hello.py` เก็บไฟล์นี้ไว้ในหน่วยความจำของบอร์ด **ESP32 (MicroPython Device)**

โค้ดตัวอย่างนี้จะแสดงข้อความ **`"Hello world!"`** จำนวน 10 ครั้ง โดยใช้คำสั่ง **`print()`** และมีการเว้นระยะเวลา 1000 มิลลิวินาที

```python
import utime as time

for i in range(10):
    print( "Hello world! {}".format(i) )
    time.sleep_ms(1000)
```

![รูปภาพ: การบันทึกไฟล์ชื่อ hello.py ไปยัง MicroPython Device](https://969412697-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MIHfYo9IV3uTFm2tkDn%2F-MKLAvnvLW9Yzl0OaJvJ%2F-MKLC-0go-w9OihnPPzK%2Fthonny_esp32_save_file-1.png?alt=media\&token=88b03448-9d48-4085-950c-bf906866a9e7)

เมื่อบันทึกไฟล์แล้ว เราก็สามารถทำคำสั่ง **Run (Run Current Script)** สำหรับไฟล์ดังกล่าวได้ (กด **F5**) ในกรณีที่การทำคำสั่ง ก็สามารถกดปุ่ม **Stop** ได้ (กด **Ctrl+F2**) อาจกดซ้ำแล้วรอจนกว่า เครื่องหมาย **Prompt** (`>>>`) จะปรากฏในส่วน **Interactive Shell**

![รูปภาพ: เมื่อบันทึกไฟล์ hello.py ได้สำเร็จแล้ว](https://969412697-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MIHfYo9IV3uTFm2tkDn%2F-MKLAvnvLW9Yzl0OaJvJ%2F-MKLC94h9fhEWlLrPzba%2Fthonny_saved_file-2.png?alt=media\&token=c735e637-088d-4b97-9548-79ce95df5524)

เมื่อทำคำสั่ง **Run** ก็จะได้ข้อความเอาต์พุตดังนี้

![รูปภาพ: ข้อความเอาต์พุตที่ได้จากการทำงานของโค้ดตัวอย่าง](https://969412697-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MIHfYo9IV3uTFm2tkDn%2F-MKLAvnvLW9Yzl0OaJvJ%2F-MKLClC86Bms4CFWLVNY%2Fthonny_esp32_run_script.png?alt=media\&token=816a28cc-11b6-44dd-8874-069ec1c82337)

ถ้าอยากทราบว่า มีโมดูลของ **MicroPython** อะไรบ้าง ให้ใช้งานได้ (โดยการใช้คำสั่ง `import` แล้วตามด้วยชื่อโมดูล) ให้ลองทำคำสั่ง `help("modules")`

![รูปภาพ: แสดงรายการโมดูลของไมโครไพธอนที่ใช้งานได้](https://969412697-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MIHfYo9IV3uTFm2tkDn%2F-MKLCuhMEyx_OS3ZuhF3%2F-MKLE8KvGeEdJX4hIxxz%2Fmicropython_esp32_repl_show_modules.png?alt=media\&token=ffe28e93-5879-41b0-9316-7a98cff8239a)

หรือจะดูว่า มีคำสั่งหรือฟังก์ชันที่เกี่ยวข้องกับโมดูลหรือไลบรารี ก็ลองทำคำสั่ง **`dir()`** เช่น  **`utime`** ตามตัวอย่างดังนี้

![รูปภาพ: ตัวอย่างข้อความเอาต์พุต](https://969412697-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MIHfYo9IV3uTFm2tkDn%2F-MKLFYawnTX7CuJ1T7C0%2F-MKLHBDnALdlGHSCWcYO%2Fmicropython_esp32_repl_dir_module.png?alt=media\&token=3fc83ec4-fedf-4957-aa09-35ce288a3968)

## โค้ดตัวอย่าง: LED Blink

โค้ดตัวอย่างถัดไปสาธิตการใช้ขา **GPIO** ให้เป็นเอาต์พุต-ดิจิทัล (เช่น ขา **GPIO21**) เพื่อนำไปต่อกับวงจร **LED** และกำหนดสถานะลอจิกที่ขาเอาต์พุตดังกล่าว&#x20;

ส่วนแรกของโค้ด **Python** เป็นการใช้คำสั่ง `import` เพื่อระบุว่า จะใช้โมดูลหรือไลบรารีใดบ้าง เช่น [`machine`](https://docs.micropython.org/en/latest/library/machine.html), [`utime`](https://docs.micropython.org/en/latest/library/utime.html) และ [`micropython`](https://docs.micropython.org/en/latest/library/micropython.html) เป็นต้น ภายในไลบรารี [`machine`](https://docs.micropython.org/en/latest/library/machine.html) ก็มีคลาสต่าง ๆ ที่เกี่ยวข้องกับการใช้งานวงจรภายในของ **ESP32** เช่น [`Pin`](https://docs.micropython.org/en/latest/library/machine.Pin.html), [`I2C`](https://docs.micropython.org/en/latest/library/machine.I2C.html), [`SPI`](https://docs.micropython.org/en/latest/library/machine.SPI.html), [`UART`](https://docs.micropython.org/en/latest/library/machine.UART.html), [`ADC`](https://docs.micropython.org/en/latest/library/machine.ADC.html),  [`WDT`](https://docs.micropython.org/en/latest/library/machine.WDT.html), [`RTC`](https://docs.micropython.org/en/latest/library/machine.RTC.html), [`SDCard`](https://docs.micropython.org/en/latest/library/machine.SDCard.html) เป็นต้น

คลาส `Pin` เกี่ยวข้องกับการใช้งาน **GPIO (Digital I/O pins)** ของฮาร์ดแวร์ เช่น ใช้งานเป็นขาดิจิทัล-อินพุต หรือเอาต์พุต และการเปิดใช้งาน **Internal Pull-Up** หรือ **Pull-Down** สำหรับขาที่จะถูกใช้เป็นอินพุต เป็นต้น

```python
from micropython import const
import machine
import utime as time

LED_GPIO = const(21)  # define a constant
led = machine.Pin( LED_GPIO, mode=machine.Pin.OUT ) # GPIO output

state = False # LED output state
try:
    while True:
        state = not state
        led.value(state)
        print('LED state: {}'.format( int(state) ))
        time.sleep_ms(500)
except KeyboardInterrupt:
    print('Done..')
```

ถ้าต้องการหยุดการทำงานของโปรแกรม ให้กดปุ่ม **Ctrl+C** ในช่อง **Shell** ของ **Thonny IDE** หรือถ้าต้องการรีเซตการทำงาน (**Soft Reset**) ให้กดปุ่ม **Ctrl+D**

![รูปภาพ: การรันโค้ด led\_blink.py โดยใช้บอร์ด ESP32](https://969412697-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MIHfYo9IV3uTFm2tkDn%2F-MKLdhjL4r0a-4RxE7on%2F-MKL_PCnMyOiuguAhFLw%2Fmicropython_esp32_led_blink.png?alt=media\&token=c7bb7885-2a70-4d93-b4ae-2641a5d18d3f)

![รูปภาพ: บอร์ด ESP32 สำหรับการทดสอบการทำงานของโค้ด led\_blink.py ](https://969412697-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MIHfYo9IV3uTFm2tkDn%2F-MKLb7c3S31y3Q3KL4XJ%2F-MKLbkgUBUGV2epsIxgB%2Fttgo_esp32_led_green.jpg?alt=media\&token=ea7e2335-8a8e-46f2-b483-9faaa9adc94c)

## กล่าวสรุป

เราได้เรียนรู้ขั้นตอนการติดตั้งไฟล์เฟิร์มแวร์สำหรับบอร์ด **ESP32** และทดลองเขียนโค้ดแล้วใช้คำสั่งต่าง ๆ ของไมโครไพธอน เพื่อนำไปทดสอบกับบอร์ด **ESP32** ในเบื้องต้น โดยใช้ร่วมกับโปรแกรม **Thonny IDE**

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