---
# System prepended metadata

title: 在 ESP32/ESP8266 MicroPython 使用 USB 傳輸線與電腦上的程式互動
tags: [MicroPython, ESP8266, ESP32]

---

# 在 ESP32/ESP8266 MicroPython 使用 USB 傳輸線與電腦上的程式互動

###### tags: `MicroPython` `ESP32` `ESP8266`

在 ESP32/ESP8266 上撰寫 MicroPython 程式時, 你可能會希望可以讓 控制板透過 USB 傳輸線和電腦上的其他程式互動, 例如可以從 PuTTY 輸入指令控制控制板上內建的 LED 燈。要做到這件事, 最簡單的方式就是使用 Python 內建的 [input](http://docs.micropython.org/en/latest/library/builtins.html#input) 來讀取輸入資料, 不過這個方式必須要在輸入資料後按下 <kbd>Enter</kbd>, 有點麻煩, 我們希望的是可以直接按下例如 <kbd>O</kbd>/<kbd>X</kbd> 就點亮/熄滅 LED 的方式。

對於習慣使用 Arduino 的人可能會想到這不就開啟序列通訊就好了？沒錯, MicroPython 在 machine 模組中也提供了 [UART](http://docs.micropython.org/en/latest/library/machine.UART.html) 類別, 可以使用控制板上的 UART, 可惜的是 UART0 已經被 REPL (互動介面) 佔用了, 無法在程式中使用。難道這樣就沒輒了嗎？

還好, 山不轉路轉, 由於 REPL 的輸入就是 Python 的 sys.stdin 資料流, 所以我們可以直接操作 [sys.stdin](http://docs.micropython.org/en/latest/library/sys.html#sys.stdin) 來獲取輸入的資料, 在 Python 中也提供有標準的 [select](http://docs.micropython.org/en/latest/library/uselect.html) 機制, 可以偵測輸入用的資料流是否已經有資料等待讀取？結合以上, 我們就可以讀取輸入的指令來做出回應了。

以下就是一個簡單的程式, 可以從電腦端透過 USB 傳輸線輸入 <kbd>O</kbd>/<kbd>X</kbd> 指令到控制板**點亮/熄滅**內建的 LED：

```python=
import sys
import select
import time
from machine import Pin

p = select.poll()     # 建立偵測物件
p.register(
    sys.stdin,        # 偵測標準輸入 (REPL)
    select.POLLIN     # 偵測是否有資料待讀取
) 

led = Pin(2, Pin.OUT) # 控制內建的 LED
led.value(0)          # 預設熄燈

while 1:
  time.sleep(0.1)
   
  while p.poll(0):   # 測試是否有資料待讀取並等待 0 毫秒
    ch = sys.stdin.read(1) # 讀取資料
    if ch == 'O':    # 輸入指定 O
        print('點亮')
        led.value(1) # 點亮 (esp8266 是熄滅)
    elif ch == 'X':  # 輸入指令 X
        print('熄滅')
        led.value(0) # 熄滅 (esp8266 是點亮)
```
其中 [poll(0)](http://docs.micropython.org/en/latest/library/uselect.html#uselect.poll.poll) 就是偵測是否有資料待讀取？傳入的參數代表要等待多少毫秒？如果超過時間仍然沒有資料可讀取, 就會傳回一個空的串列, 否則就會傳回一個由元素組 (tuple) 組成的串列。因此只要判斷傳回值就可以知道是否有資料待讀取了。這裡傳入 0 表示不等待, 這樣可以在沒有輸入資料時去做別的事情, 不用枯等 (block) 資料進來。

要測試這個程式, 必須將程式儲存成 main.py, 放到控制板上重開機讓它自動執行, 如果直接在 thonny 之類的環境執行, 輸入資料會被 REPL 搶走。接著, 就可以開啟 PuTTY 之類的終端機軟體連接控制板下指令控制 LED 了：

![](https://i.imgur.com/crf5dUx.png)


