Learning Objectives
- 說明 MicroPython 開機時依序執行 boot.py、main.py,以及兩個檔案各放什麼
- 用 os 模組列出板子上的檔案,用 open 讀寫檔案
- 把 Wi-Fi 名稱、密碼與作品參數放進 JSON 設定檔,程式讀取設定來執行
- 在設定檔不存在或格式錯誤時改用預設值,並把修改後的設定存回檔案
拔掉 USB 之後,程式還在嗎
到目前為止,你在 Thonny 按「執行」,程式是從電腦送到 ESP32 的記憶體裡執行;拔掉 USB、重新接上電源,程式就不見了。 真正的作品要做到:接上電池,不用電腦,自己開始工作。
這靠的是 ESP32 快閃記憶體(flash)上的檔案系統。MicroPython 把快閃記憶體的一部分格式化成檔案系統,
你可以在上面放 .py 程式、設定檔、紀錄檔,和電腦上的資料夾很像(容量小得多,通常是幾 MB)。
開機時執行哪些檔案
MicroPython 文件寫的開機順序是:
接上電源或按重設鍵(深度睡眠醒來也一樣)
→ 執行 boot.py(如果有)
→ 執行 main.py(如果有)
→ 進入 REPL(main.py 結束或出錯時)
| 檔案 | 放什麼 | 規則 |
|---|---|---|
boot.py |
最基本的設定 | 一定要執行完就結束,不要放無窮迴圈 |
main.py |
作品的主程式 | 可以是 while True 永遠執行 |
所以作品完成後的步驟是:把程式存成 main.py 上傳到板子,重新開機,它就自動執行。
如果 boot.py 卡在無窮迴圈,main.py 永遠輪不到,連 REPL 都很難進去,只好重新燒錄韌體;這是新手最常踩的雷。
逐步看:板子上有哪些檔案
這個範例的工作目錄放了三個檔案:boot.py、main.py、config.json,模擬一塊已經裝好作品的 ESP32。
執行完可以切到輸出區的「檔案」分頁,看三個檔案的內容。
為什麼要有設定檔
把 Wi-Fi 密碼直接寫在 main.py 裡有幾個問題:
- 換一個地方(家裡、教室、實驗室)就要改程式。
- 同一份程式要裝到十塊板子,只差在名稱或主題,要改十份。
- 程式要分享給別人(上傳 GitHub、交作業)時,密碼跟著被公開。
所以常見的作法是:程式只放邏輯,會變的值放進設定檔。設定檔最常用 JSON:
{"wifi": {"ssid": "Uedu-Lab", "password": "makers123"}, "blink_ms": 300, "name": "room101"}
MicroPython 內建 json 模組(舊版叫 ujson):
| 函式 | 作用 |
|---|---|
json.load(檔案) |
讀檔案裡的 JSON,變成字典 |
json.loads(字串) |
把 JSON 字串變成字典(第 14 課處理 MQTT 訊息用過) |
json.dump(資料, 檔案) |
把字典寫成 JSON 存進檔案 |
json.dumps(資料) |
把字典變成 JSON 字串 |
設定檔存在板子上仍然是明文,拿到板子的人讀得到。分享程式時,只分享一份把密碼換成假值的範本(例如
config.example.json)。
逐步看:讀設定檔、連 Wi-Fi、照設定閃燈
程式裡沒有寫死任何 Wi-Fi 名稱、密碼或時間:全部從 config.json 讀出來。注意怎麼從巢狀字典裡取值。
逐步看:設定檔壞掉時用預設值,修改後存回去
這次工作目錄裡的 config.json 少了最後的右大括號,就像手動編輯時打錯字。看 load_config 怎麼接住錯誤、改用預設值;
執行完切到「檔案」分頁,會看到程式重新寫好的 config.json。
在電腦上管理板子的檔案(mpremote)
Thonny 的「檔案」面板可以用滑鼠上傳、下載(第 2 課)。也可以用 MicroPython 官方的命令列工具 mpremote
(pip install mpremote 安裝),適合要一次上傳很多檔案時。下面的輸出是範例,檔案大小依內容而定。
-
1
列出板子上的檔案
mpremote會自動找到用 USB 連接的開發板。ls列出檔案大小(位元組)與檔名。 -
2
上傳設定檔
cp 本機檔案 :把檔案複製到板子;冒號開頭的路徑代表「板子上」。 -
3
看板子上的檔案內容
cat印出板子上檔案的內容,確認上傳的是對的版本。 -
4
重新開機,讓 main.py 自動執行
reset等於在板子上執行machine.reset():重新開機後依序執行 boot.py、main.py。之後拔掉 USB、改接電池,作品一樣會自己開始工作。
小測驗:開機與檔案
MicroPython 開機時,下面哪一個順序正確?
把 Wi-Fi 密碼放進 config.json,而不是寫在 main.py 裡,最主要的好處是?
小測驗:JSON 與錯誤處理
下面的程式會印出什麼?
import json
text = '{"wifi": {"ssid": "Lab"}, "blink_ms": 250}'
cfg = json.loads(text)
print(cfg["wifi"]["ssid"], cfg["blink_ms"] / 1000)
設定檔少打了一個右大括號。下面的程式會印出什麼?
import json
try:
cfg = json.loads('{"blink_ms": 300')
except ValueError:
cfg = {"blink_ms": 500}
print(cfg["blink_ms"])
DEFAULT = {"blink_ms": 500},cfg = DEFAULT 之後執行 cfg["blink_ms"] = 200,DEFAULT["blink_ms"] 會是多少?
重點整理
- MicroPython 在快閃記憶體上有檔案系統;開機(含深度睡眠醒來)依序執行
boot.py、main.py,結束或出錯才進入 REPL。 boot.py只放基本設定,一定要執行完就結束;作品的主程式存成main.py。os.listdir()列檔案、os.stat(檔名)[6]是大小;讀寫檔案和電腦上的 Python 一樣用open。- 會變的值(Wi-Fi、主題名稱、間隔)放進 JSON 設定檔:
json.load讀、json.dump寫。 - 讀設定要接住
OSError(檔案不存在)與ValueError(格式錯誤),改用預設值;預設值用dict()複製一份再修改。 - 設定檔是明文;分享程式時只放密碼換成假值的範本。
下一課介紹 ESP32 的另一種無線通訊:藍牙低功耗(BLE)。