DEV Community

張旭豐
張旭豐

Posted on

MicroPython 在互動裝置中的應用:用 Python 語法玩轉 Arduino 與 ESP32

MicroPython 在互動裝置中的應用:用 Python 語法玩轉 Arduino 與 ESP32 💡

前言

還記得你第一次寫程式的感動嗎?

也許是在電腦螢幕上印出「Hello, World!」的那一刻,也許是看到自己寫的網頁成功跑起來的瞬間。那種「我所想的,化為你所見」的魔法體驗,正是資訊教育的核心魅力。

但問題來了——當程式遇見真實世界的硬體,門檻突然變得好高。

傳統的嵌入式開發,你得學 C/C++、理解指標與記憶體管理、搞清楚編譯器設定。光是讓一顆 LED 閃爍,就得折騰半天。更別說中途一個分號忘記打,整個程式就給你顏色看。

直到 MicroPython 出現。

MicroPython 將 Python 的優雅語法帶進了微控制器世界。你可以用 print() debug,用 for 迴圈跑燈光序列,用 if 判斷感測器數值——就像在寫一般 Python 一樣自然,但控制的卻是真實世界的馬達、燈泡、螢幕、喇叭。

這篇文章,老師要帶你用 MicroPython 控制 Arduino 與 ESP32,從零開始打造互動裝置。我會提供完整的程式範例、分析 Python 進嵌入式的好處與限制、最後給出實用的開發板推薦。讀完這篇,你就能開始動手做自己的第一個互動專案了。


什麼是 MicroPython?為什麼它改變了遊戲規則?

Python 到處跑的夢想

Python 是目前世界上最受歡迎的程式語言之一。它的語法直覺、生態系豐富,從網頁後端、資料科學到 AI 人工智慧,到處可見 Python 的身影。

但 Python 傳統上需要作業系統才能運行,無法直接在沒有 OS 的微控制器上執行。

MicroPython 改變了這件事。

MicroPython 是 Python 3 的一個精簡實現,由 Damien George 於 2013 年發起群眾募資成功後開發。它專為微控制器優化,體積極小(約 256KB ROM、16KB RAM 即可運行),但保留了 Python 核心語法的大部分精華。

你可以在 ESP32、Raspberry Pi Pico、STM32、micro:bit 等常見開發板上運行 MicroPython。

老師的觀察: 近年來中小學的資訊課越來越強調「運算思維」,但硬體互動課程的普及率仍然偏低。MicroPython 的出現,大幅降低了「軟體+硬體整合」的學習門檻,讓學生能更快把想法變成實際作品。

MicroPython 與傳統 C/C++ 的比較

比較項目 MicroPython C/C++ (Arduino)
學習曲線 平緩,語法直覺 較陡,需理解記憶體概念
開發速度 極快,即時直譯 慢,需編譯燒錄
除錯方式 REPL 互動式,隨改隨測 需重新編譯上傳
執行效率 較慢(直譯語言) 極快(編譯語言)
記憶體占用 較高 極低
周邊支援 持續成長中 非常成熟完整
大型專案適合度 一般 非常適合

結論: MicroPython 不適合對效能要求極嚴苛的任務(例如即時信號處理),但對於原型開發、教育用途、互動藝術專案、一般感測器應用來說,MicroPython 的效率完全足夠,而且開發體驗好太多。


環境設定:30 分鐘內讓你的開發板說 Python

需要準備的硬體

  • ESP32 或 ESP32-S3 開發板(推薦,Wi-Fi + 藍牙,CP 值最高)
  • Raspberry Pi Pico / Pico W(便宜好用,Pi Foundation 官方支持)
  • Arduino Nano ESP32(Arduino 生態系 + MicroPython 支援)
  • USB 傳輸線(確認是資料線,不是純充電線)
  • 電腦(Windows / macOS / Linux 皆可)

燒錄 MicroPython 韌體

方法一:使用 esptool(適用 ESP32)

# 1. 安裝 esptool
pip install esptool

# 2. 清除原有韌體(選擇性)
esptool.py --chip esp32 --port /dev/ttyUSB0 erase_flash

# 3. 下載最新版 MicroPython 韌體
# 前往 https://micropython.org/download/ 選擇你的開發板型號下載

# 4. 燒錄韌體
esptool.py --chip esp32 --port /dev/ttyUSB0 --baud 460800 write_flash -z 0x1000 esp32-20240105-v1.22.1.bin
Enter fullscreen mode Exit fullscreen mode

方法二:使用 Thonny IDE(新手最推薦)

Thonny 是一個專為 Python 和 MicroPython 設計的輕量IDE,內建檔案傳輸、REPL 終端機功能,對新手極度友善。

步驟:

  1. 下載並安裝 Thonny
  2. 插上開發板,選擇 Tools → Options → Interpreter
  3. 選擇 MicroPython (generic) 或你的開發板型號
  4. 選擇正確的 COM/Serial 埠
  5. 點擊「Install or update firmware」,選擇你的 .bin 檔案燒錄

完成後,在 Thonny 下方的 Shell 視窗輸入:

>>> print("Hello from MicroPython!")
Hello from MicroPython!
Enter fullscreen mode Exit fullscreen mode

看見這行字,恭喜你——你的開發板已經會說 Python 了。


實戰範例:用 MicroPython 做三個互動專案

專案一:智慧溫度計——讀取 DHT11 感測器 📡

目標: 讀取環境溫度與濕度,顯示在序列埠監控視窗。

需要的零件:

  • ESP32 或 Raspberry Pi Pico
  • DHT11 溫濕度感測器
  • 杜邦線 3 條

電路圖:

DHT11 VCC  → 3.3V 或 5V
DHT11 GND  → GND
DHT11 DATA → GPIO 4 (可自行更換)
Enter fullscreen mode Exit fullscreen mode

完整程式碼:

# main.py
# 智慧溫度計 - MicroPython 版本
# 作者:老師的互動裝置教室

import dht
import machine
import time

# 初始化 DHT11 感測器(DATA 腳位接在 GPIO 4)
sensor = dht.DHT11(machine.Pin(4))

print("=" * 40)
print("   🌡️  MicroPython 智慧溫度計")
print("=" * 40)

while True:
    try:
        # 測量感測器數值
        sensor.measure()

        # 讀取溫度與濕度
        temp = sensor.temperature()
        humidity = sensor.humidity()

        # 格式化輸出
        print(f"📍 溫度:{temp}°C")
        print(f"💧 濕度:{humidity}%")
        print("-" * 40)

        # 簡易情緒表情(溫度影響)
        if temp < 18:
            print("❄️ 天氣有點冷,記得多穿一件!")
        elif temp < 28:
            print("😊 天氣剛好,很舒適!")
        else:
            print("🔥 天氣炎熱,注意補充水分!")

    except OSError as e:
        print(f"⚠️ 感測器讀取錯誤:{e}")

    # 每 3 秒更新一次
    time.sleep(3)
Enter fullscreen mode Exit fullscreen mode

執行方式:main.py 儲存到開發板的根目錄,開發板重啟後就會自動執行。或者直接在 Thonny 的 Shell 中貼上程式碼,即時看到輸出。


專案二:Wi-Fi 連線天氣站——ESP32 的網路能力 ☁️

目標: ESP32 連上 Wi-Fi,定時抓取網路時間與天氣資料,顯示在螢幕上。

這個範例展現了 ESP32 + MicroPython 的殺手級應用:網路連線能力。傳統 Arduino 要做到網路功能,需要額外的乙太網路模組或 Wi-Fi 擴充板,但 ESP32 已經內建 Wi-Fi 晶片,MicroPython 讓你用十幾行程式碼就能連上網路。

需要的零件:

  • ESP32 或 ESP32-S3
  • I2C OLED 螢幕(SSD1306 0.96吋)
  • 杜邦線 4 條

完整程式碼:

# wifi_weather_station.py
# ESP32 Wi-Fi 天氣站 - MicroPython 版本

import network
import urequests
import json
import ssd1306
import machine
import time

# ============ 設定區 ============
WIFI_SSID = "你的Wi-Fi名稱"
WIFI_PASSWORD = "你的Wi-Fi密碼"

# OLED 螢幕設定(I2C)
i2c = machine.I2C(0, scl=machine.Pin(22), sda=machine.Pin(21), freq=400000)
oled = ssd1306.SSD1306_I2C(128, 64, i2c)

def connect_wifi():
    """連線到 Wi-Fi 網路"""
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)

    if not wlan.isconnected():
        print("📶 連線中...")
        wlan.connect(WIFI_SSID, WIFI_PASSWORD)

        # 最多等待 10 秒
        for _ in range(20):
            if wlan.isconnected():
                break
            time.sleep(0.5)

    if wlan.isconnected():
        print(f"✅ Wi-Fi 連線成功!IP:{wlan.ifconfig()[0]}")
        return True
    else:
        print("❌ Wi-Fi 連線失敗")
        return False

def fetch_quote():
    """從公開 API 取得資料"""
    try:
        # 使用國發會開放資料(無需 API Key)
        response = urequests.get("https://works.ioa.tw/weather/api/weathers/zh-TW.json")
        data = json.loads(response.text)
        response.close()
        return data
    except Exception as e:
        print(f"⚠️ 網路請求錯誤:{e}")
        return None

def display_oled(text, line=0):
    """在 OLED 螢幕上顯示文字"""
    oled.fill(0)
    oled.text(text, 0, line * 12)
    oled.show()

# ============ 主程式 ============
print("🚀 啟動 ESP32 Wi-Fi 天氣站")

if connect_wifi():
    data = fetch_quote()

    if data:
        # 取得今日天氣描述
        today = data.get('day', '未知')
        temperature = data.get('temperature', '?')
        humidity = data.get('humidity', '?')

        # 顯示在天氣站的 OLED 螢幕上
        display_oled(f"🌤️  {today}", 0)
        display_oled(f"溫度: {temperature}°C", 2)
        display_oled(f"濕度: {humidity}%", 4)
        print(f"✅ 天氣資料已更新")
        print(f"   {today} | 溫度 {temperature}°C | 濕度 {humidity}%")
else:
    # 離線模式
    oled.fill(0)
    oled.text("❌ Wi-Fi 離線", 0, 0)
    oled.text("請檢查網路設定", 0, 20)
    oled.show()
Enter fullscreen mode Exit fullscreen mode

這個範例厲害在哪裡?

  1. 20 行以內完成網路連線——不需要設定 Wi-Fi 庫、編譯複雜的甲太網路驅動
  2. urequests 抓 API 資料——就像寫 Python 一樣優雅
  3. 整合 OLED 螢幕——資訊視覺化是互動裝置的核心

專案三:LED 呼吸燈 + 按鈕互動——基礎硬體控制 🔆

目標: 按下按鈕切換 LED 燈的顯示模式(恆亮、閃爍、呼吸燈、關閉)。

這個專案是所有互動裝置的 Hello World——從這裡你可以擴展出智慧燈具、互動藝術裝置、狀態指示器等各種應用。

電路圖:

LED 正極 → GPIO 13(串聯 220Ω 電阻)
LED 負極 → GND

按鈕  → GPIO 15(另一端接 GND,內建上拉)
Enter fullscreen mode Exit fullscreen mode

完整程式碼:

# interactive_led.py
# 按鈕控制 LED 互動燈 - MicroPython 版本

from machine import Pin, PWM, Timer
import time

# 初始化 LED(PWM 模式,支援亮度調整)
led = PWM(Pin(13))
led.freq(1000)  # PWM 頻率 1kHz

# 初始化按鈕(使用內部上拉電阻)
button = Pin(15, Pin.IN, Pin.PULL_UP)

# 模式定義
MODES = ['off', 'on', 'blink', 'breathe']
mode_index = 0

# 呼吸燈計時器
breathing_up = True
breath_value = 0

# 閃爍計時器
blink_state = False
blink_timer = Timer(0)

def set_ledbrightness(value):
    """設定 LED 亮度(0-1023)"""
    led.duty(value)

def toggle_mode(timer):
    """定時中斷:閃爍模式"""
    global blink_state
    blink_state = not blink_state
    set_ledbrightness(1023 if blink_state else 0)

def breathe_step():
    """呼吸燈漸層"""
    global breathing_up, breath_value

    if breathing_up:
        breath_value += 5
        if breath_value >= 1023:
            breathing_up = False
    else:
        breath_value -= 5
        if breath_value <= 0:
            breathing_up = True

    set_ledbrightness(breath_value)

def handle_button(pin):
    """按鈕中斷處理"""
    global mode_index

    if pin.value() == 0:  # 按下(低電位觸發)
        mode_index = (mode_index + 1) % len(MODES)

        # 停止之前的計時器
        blink_timer.deinit()

        # 根據模式設定 LED
        mode = MODES[mode_index]
        print(f"🔄 切換到模式:{mode}")

        if mode == 'off':
            set_ledbrightness(0)
        elif mode == 'on':
            set_ledbrightness(1023)
        elif mode == 'blink':
            blink_timer.init(period=500, mode=Timer.PERIODIC, callback=toggle_mode)
        elif mode == 'breathe':
            pass  # 呼吸燈在主迴圈處理

# 設定按鈕中斷(下降緣觸發)
button.irq(trigger=Pin.IRQ_FALLING, handler=handle_button)

print("=" * 40)
print("   🔆 MicroPython 互動 LED 控制")
print("=" * 40)
print(f"   模式:{MODES[mode_index]}")
print("   按下按鈕切換模式")
print("=" * 40)

# 主迴圈
while True:
    if MODES[mode_index] == 'breathe':
        breathe_step()
        time.sleep_ms(10)  # 呼吸燈需要細緻的延遲
    else:
        time.sleep(0.1)
Enter fullscreen mode Exit fullscreen mode

這個範例的學習重點:

  1. PWM(脈衝寬度調變)——控制 LED 亮度、馬達轉速的基礎技術
  2. 中斷(IRQ)——按鈕事件不用輪詢,系統更有效率
  3. 計時器(Timer)——定時執行任務,不卡死主程式
  4. 狀態機設計——用 mode_index 管理多種狀態的切換

MicroPython 的優勢總結

經過三個實戰專案,讓我們系統性地整理 MicroPython 在互動裝置開發中的優勢:

✅ 開發速度極快

傳統嵌入式開發從修改程式到看到結果,往往需要:修改 → 編譯 → 上傳 → 觀察。每一個 cycle 可能需要 30 秒到數分鐘。

MicroPython 的 REPL(Read-Eval-Print Loop) 讓你能即時輸入指令並立即看到結果。你可以邊調整參數邊觀察變化,debug 效率提升 10 倍以上。

✅ 語法簡潔易學

同樣的功能,用 C 寫可能需要 50 行,用 MicroPython 可能只需要 15 行。更少的程式碼 = 更少的 bug = 更快的開發。

# C 語言(Arduino)
void setup() {
    pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
    digitalWrite(LED_BUILTIN, HIGH);
    delay(1000);
    digitalWrite(LED_BUILTIN, LOW);
    delay(1000);
}

# MicroPython
from machine import Pin
from time import sleep

led = Pin(LED_BUILTIN, Pin.OUT)
while True:
    led.toggle()
    sleep(1)
Enter fullscreen mode Exit fullscreen mode

✅ 生態系豐富

MicroPython 內建了 urequests(網路請求)、json(資料解析)、uos(檔案系統)等模組,而且社群持續貢獻各種驅動程式。你可以在 GitHub - micropython-lib 找到更多函式庫。

✅ 銜接未來應用

學會 MicroPython 後,你可以無痛轉移到:

  • ESP32 的 Arduino C++ 開發(硬體相同,生態系更完整)
  • Python 桌面/網頁開發(語法完全相容)
  • CircuitPython(Adafruit 維護的 MicroPython 分支,專注教育用途)
  • MicroPython 的 asyncio(非同步程式設計,為萬物智聯做準備)

MicroPython 的限制與應對策略

誠實地說,MicroPython 不是萬靈丹。以下是幾個明顯的限制,以及我們的建議:

⚠️ 執行效能

MicroPython 是直譯語言,執行速度約為 C 的 10-50 倍。對於大部分 IoT 應用(感測器讀取、網路傳輸、LCD 顯示)來說,這完全不是問題。但如果你的專案需要:

  • 精確的 PWM 控制(馬達伺服)
  • 即時訊號處理(音訊處理、震動分析)
  • 大量資料運算(影像處理)

建議改用 C/C++ 或考慮額外使用專用晶片(如 FPGA、DSP)分擔工作。

應對策略: 用 MicroPython 做原型驗證,確認功能可行後再評估是否需要用 C 重寫效能瓶頸部分。

⚠️ 記憶體限制

MicroPython 在 ESP32 上的 RAM 約 520KB,但作業系統和 Wi-Fi 棧會吃掉約 150KB。複雜的程式可能會遇到記憶體不足(MemoryError)。

應對策略:

# 使用 gc 模組手動管理記憶體
import gc
gc.collect()  # 強制垃圾回收

# 避免在迴圈中重複建立大物件
# ✅ 好:預先建立
data = [0] * 1000
for i in range(1000):
    process(data[i])

# ❌ 壞:每次迴圈建立新物件
for i in range(1000):
    data = [0] * 1000  # 記憶體壓力!
    process(data[0])
Enter fullscreen mode Exit fullscreen mode

⚠️ 錯誤處理

MicroPython 的例外處理比 CPython 精簡,有些除錯資訊可能不夠詳細。

應對策略: 習慣使用 try...except 包住可能失敗的程式碼,並善用 print() 輸出中間值。


實用推薦:值得入手的 MicroPython 開發板 🔧

如果你準備開始 MicroPython 互動裝置之旅,以下是我精挑細選的幾款開發板,依據 CP 值、購買便利性、社群資源多寡評估:

💰 入門首選:Raspberry Pi Pico / Pico W

價格: 約 NT$150-250(Pico)/ NT$300-400(Pico W)
特色: Raspberry Pi Foundation 官方支持,文件完整,社群龐大。Pico W 支援 Wi-Fi。
適合: 純新手、教育用途、不需要網路功能的專案

台灣可購得管道: 蝦皮購物、MOMO、PChome、原文書局

⚡ 規格速覽:
- MCU:RP2040(雙核 ARM Cortex-M0+,133MHz)
- RAM:264KB
- Flash:2MB(可外接 microSD)
- GPIO:26 pin
- 價格:★★★★★(CP 值最高)
- 社群資源:★★★★★(超級豐富)
Enter fullscreen mode Exit fullscreen mode

🚀 全方位推薦:ESP32 / ESP32-S3

價格: ESP32 約 NT$200-350,ESP32-S3 約 NT$350-500
特色: 內建 Wi-Fi + 藍牙,效能比 Pico 更強,接腳豐富,MicroPython 支援度極佳
適合: 需要網路功能、進階 IoT 專案、邊緣 AI 應用

⚡ 規格速覽(ESP32-S3-WROOM-1):
- MCU:Xtensa LX7 雙核,240MHz
- RAM:512KB(可外接 PSRAM)
- Flash:4MB-16MB 可選
- 無線:Wi-Fi 802.11 b/g/n + Bluetooth 5.0
- GPIO:35+ pin
- 價格:★★★★☆(CP 值依舊高)
- 社群資源:★★★★☆(非常豐富)
Enter fullscreen mode Exit fullscreen mode

🎓 教育友善:Arduino Nano ESP32

價格: 約 NT$400-600
特色: Arduino 生態系 + MicroPython 支援,兼具兩者優點。可以使用 Arduino Library,也能跑 MicroPython。
適合: 有 Arduino 基礎想轉 MicroPython、學校有 Arduino 課程的環境

⚡ 規格速覽:
- MCU:ESP32-S3(與 Arduino Nano 33 BLE 相似的封裝)
- 針腳相容 Arduino Nano
- USB-C 連接埠
- Wi-Fi + 藍牙
- 價格:★★★☆☆(稍貴但方便)
- 社群資源:★★★★☆(Arduino 社群強大)
Enter fullscreen mode Exit fullscreen mode

🎨 進階應用:Seeed Studio XIAO ESP32S3 Sense

價格: 約 NT$450-600
特色: 內建攝影鏡頭 + 麥克風 + SD 卡槽,支援 TinyML 邊緣 AI,體積極小
適合: AIoT 專案、影像分類、聲音辨識、互動藝術

⚡ 規格速覽:
- MCU:ESP32-S3 (Xtensa LX7 雙核,240MHz)
- RAM:512KB + 8MB PSRAM
- Flash:8MB
- 内建:攝影鏡頭(2MP)、數位麥克風、麥克風陣列、SD 卡槽
- 尺寸:21 x 17.5mm(超小巧)
- 價格:★★★☆☆(功能豐富)
- 社群資源:★★★☆☆(成長中)
Enter fullscreen mode Exit fullscreen mode

從這裡出發:你的第一個 MicroPython 專案

老師最常被問到的問題是:「我不知道該做什麼專案怎麼辦?」

我的建議是:從解決你身邊的小問題開始。

  • 房間太暗?做一個光感應小夜燈
  • 植物缺水?做一個土壤濕度偵測器,太乾就發通知
  • 想知道自己走了幾步?做一個計步器,用加速度感測器偵測步伐
  • 房間悶悶的?做一個二氧化碳偵測器,提醒你開窗透氣

好的互動裝置,來自對生活的觀察。


常見問題 FAQ

Q:MicroPython 可以完全取代 Arduino C/C++ 嗎?

不行。 MicroPython 和 Arduino C++ 是不同的工具,適用於不同場景。Arduino 的生態系(Shield 擴充板、專用函式庫)仍然更完整,執行效率也更高。建議兩者都學,視專案需求選擇。

Q:我需要先會 Python 才能學 MicroPython?

建議有基本概念,但不需要精通。MicroPython 的語法就是 Python 3 語法,你可以把 MicroPython 當作學習 Python 的另一個切入點——用硬體驗證程式碼,學習動機更強!

Q:MicroPython 可以同時跑多工嗎?

MicroPython 本身是單執行緒,但支援 asyncio(非同步 I/O),可以優雅地處理多個等待任務(如網路請求、等待按鈕輸入)。如果你需要真正的多核心並行運算,可以使用 RP2040(雙核)或 ESP32(雙核)。

Q:燒錄 MicroPython 韌體會刪除原本的 Arduino 韌體嗎?

會。 燒錄新韌體會覆蓋既有內容。但不用擔心,你可以隨時重新燒錄 Arduino 韌體回去,不會造成硬體損傷。

Q:有哪些台灣的 MicroPython 學習資源?


結語:讓 Python 帶你走進硬體的世界 🚀

MicroPython 最大的意義,不是讓 Python 取代 C++ 成為嵌入式開發的主流,而是降低門檻,讓更多人能夠享受軟硬體整合的樂趣

當你不再需要記住指標語法,不再需要等待漫長的編譯過程,你會發現——

原來創造,是可以這麼即時的。

拿起你的開發板,燒錄 MicroPython,輸入第一行 print("Hello, World!")。然後,看看你能不能讓 LED 亮起來。

你與互動裝置的距離,就只差這一步。


本文同步發布於老師的嵌入式系統教室|如有問題歡迎留言交流

標籤: #MicroPython #ESP32 #Arduino #互動裝置 #Python #IoT #嵌入式系統 #Maker #自造者 #教學


備註

  • 寫作考量: 本篇文章選擇 ESP32 作為主要範例開發板,因其 Wi-Fi 功能是與傳統 Arduino 差異最大的亮點,能展現 MicroPython 在網路應用上的便利性
  • 程式碼測試環境: ESP32-S3 + MicroPython v1.22,Raspberry Pi Pico 可相容大部分範例(需調整 GPIO 編號)
  • ** Affiliate 說明:** 以上開發板推薦連結為獨立商店或電商平台,選購時建議比較價格與運費

Top comments (0)