# 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 %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://think-embedded.gitbook.io/micropython/micropython-for-esp32.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
