[教學] 認識 MicroPython (一) - 安裝 MicroPython 核心進去 NodeMCU v3

NodeMCU v3 with MicroPython
買來 Node MCU v3 也快一年了,開始試著學用 Arduino IDE 來操作,之前也先試驗過 ESP8266。但總覺得用 Arduino IDE 來開發 IoT ,實在不是個聰明的方法,太多瑣碎的東西需要處理。C語言缺乏一些簡單現成的資料結構、沒有好用的字串處理功能,加上Arduino IDE 對網路、檔案的處理還停留在韌體的概念,對於需要大量處理資料、字串的 IoT 應用,Arduino IDE 簡直是個惡夢。所以自從設計了 Node MCU + NodeMCU Base Ver 1.0 的殼子之後,這玩意兒就這麼擱置了。最近重新發現 MicroPython 這個社群,原來 NodeMCU (ESP8266) 或 NodeMCU 可以裝上他們的 Firmware,並用 Python 語言來開發應用,前幾年曾經看過 MicroPython,但那時還沒有學會 Python,也沒有特別注意。
如果 Microcontroller 單片機,可以用 Python 開發程式,那該是多幸福的事情啊?

在此之前,曾經想過學 ESP8266 原廠支援的 Lua 語言。但經過了解、評估相關教學說明,知道它有多冷門之後,也放棄了。就算再簡單,只能用在 ESP8266 別的地方用不上,經濟效益太低。綜觀目前比較熱門的「新」程式語言,我認為 Python 的潛力還是比較大的。一直到今天,它還在不斷地發展新的語法,慢慢朝嚴謹的 C++ 等語言靠近。有朝一日,要變成像 Java 那樣普遍用在 Embeded 領域、成為主流也不無可能。只要 Python 別像 Java SE 8 那樣變成見錢眼開、或者最後被某家公司買去營利... 非常期待這個領域持續有新的創意出來。

MicroPython 簡介

它就是個微型實時作業系統 RTOS

若是要說 MicroPython 是一套簡易型「作業系統」+ 「Python 直譯器」,可能比單純稱呼他為韌體來得貼切。因為它長得很像古早8位元電腦時代、只有文字介面的 MSDOS 系統,開機之後,可以執行一些指令,或者自動開啟執行檔,讓電腦去做事情。
當你把一片 NodeMCU 的原本的韌體換成 MicroPython 之後,這片板子便就具備了作業系統的靈魂,板子裡面還有一個微型檔案系統,以及一個名為 boot.py 的開機設定檔。它有點像 MSDOS 開機設定檔 Config.sys,讓你可以預先定義、執行一些開機過程要做的事情。另外還有一個檔案, "main.py" ,它就像 Autoexec.bat,開機後自動執行程式。這個 main.py 其實就是主程式進入點,你可以在這個檔案裡面,用 Python 語法,寫出你在 Arduino 裡面用 C/C++ 寫的程式。如果這個程式,放在一個無窮迴圈裡面,那麼硬體就會一直執行。剛安裝完韌體時,main.py 檔案並不存在,你必須稍後上傳這個檔案。

一進去系統,就是 Python 直譯器

在開始寫第一個程式之前,你可以先用 Python 直譯器玩一下這個「作業系統」。NodeMCU 內建 REPL 通訊介面 (UART0, GPIO1=TX, GPIO3=RX) ,也就是 NodeMCU 的 USB 插頭上。可以讓你透過USB串列埠,連線進去之後,進入 Python 直譯器。因為 NodeMCU 跟 Arduino 一樣,本身就有 USB Serial 串口,你可以用 Putty,執行一個 Serial 終端機連線,連進去之後,按一下鍵盤 Enter 鍵,就會直接進入 Python 直譯器,並出現 Python 提示符號  >>>。
你可以將這個畫面,想成 「DOS 命令提示字元」或者是Windows 10 的「Power Shell」,只不過之後所有對 REPL 的操作,都得用 Python 語言來執行,而不是 DOS Shell ,包含查看檔案列表、列印檔案內容等等。

NodeMCU 的直譯器畫面,用 Python 指令,來看檔案系統裡面的檔案,並將該檔案內容列印出來

在直譯器中,因為你執行的是 Python 指令,一些資料會用 List 列表資料格式呈現。在上面操作截圖中,你甚至可以把 uos.listdir() 的結果傳給 lst_file 變數:
lst_file = uos.listdir()
然後用這個變數來開檔、讀檔案內容:
f=open(lst_file[0], 'r')
f.readlines()
註:以上指令,屬於 MicroPython 即時作業系統RTOS的一部分,開機時已經載入,所以不用另外 import uos 模組指令。

WiFi 連線與內建 WebREPL 網頁伺服器

稍後你可以在直譯器介面中啟動 WiFi 連線,把 NodeMCU 變成一個 WiFi AP,或者當作一個WiFi Station,連上家裡或辦公室的 WiFi 內網。然後啟用內建的 WebREPL 網頁伺服器,也就是網頁版的REPL、並設定密碼,你就可以用瀏覽器跟 NodeMCU 的直譯器對話,或上傳、查看內部檔案。你的第一個 main.py 主程式,在你的電腦寫出來以後,也可以透過 WebREPL 上傳。

MicroPython 的設計,真是太符合我的需求了,之後的學習過程中,將慢慢來體會這個系統的優缺點,逐步紀錄下來:

優點

  • 作業系統架構,操作起來像極了在作業系統下工作,就像樹莓派那樣
  • 就算還沒寫任何程式,已經可以在直譯器下面,執行NodeMCU網路連線等等作業
  • 有檔案系統,開發、上傳程式,就像你在其他作業系統下操作那樣直覺
  • 得以用 Python 語言開發比較複雜的程式、輕鬆處理資料、字串等等

缺點

  • 需要比較大的記憶體
    Flash至少需要 1MB 的空間,雖然目前有 512 KB的閹割板。但我覺得這不會是問題,早期手機的記憶體也很少,到現在都快跟電腦一樣大了。
  • ESP8266 不支援 Multi-threading。Arduino有實做 multi-threading 的例子,但那也只是用手動排程方式,而不是真正的 multi-threading。

將 NodeMCU 換成 MicroPython 固件韌體

下載最新版固件韌體

到這裡下載 MicroPython 韌體:
下載檔名叫做 esp8266-1m-20210902-v1.17.bin,或更新日期的韌體。(2021/9/2 更新到 v1.17,下載這個檔:esp8266-1m-20210902-v1.17.bin)

準備 Python 3 跟 esptool 模組來刷韌體

剛買到的 NodeMCU v3 通常預裝 Arduino 或 Lua 固件韌體,你需要先把 NodeMCU 改成 MicroPython。安裝 MicroPython 韌體,建議你必須先有 Python3,如果你的電腦還沒有 Python3,可以參考這篇教學,先把 Python 安裝好。然後再安裝 esptool 這個模組,如果本來就有安裝,這個指令也會把原來的 esptool 升級到最新版:
pip3 install --upgrade esptool
有些比較新的電腦,如果找不到 pip3,可以改成用 pip install --upgrade esptool
Ubuntu Linux系統下,可以用管理員身份安裝:
sudo pip3 install --upgrade esptool

確定 NodeMCU CH340 USB串口在哪個 COM 上面

Python3 跟 esptool 安裝好了之後,便能用 esptool.py 這個程式來安裝韌體,正常狀況下,你在任何目錄都可以執行這個檔案,如果不行的話,可以試著搜尋這個檔案放在哪裡,然後在 PATH 環境變數裡面,加入這個目錄名稱。
先插上NodeMCU v3 到電腦 USB,這時候,你應該會找到 CH340 這個串列埠(串口),在 Windows 用裝置管理員查看:
Windows Device Manager CH340 at COM4

在 Linux ,可用 lsusb 指令查看是否已經存在 CH340。接著確定NodeMCU 的 USB Serial 是哪個 /dev/ttyUSB*,通常會是 ttyUSB0。
在能夠執行 Python 指令的地方(Windows 的命令提示字元、Linux,MacOS 的終端機),用下列指令先抹除 NodeMCU 中的 Flash。未來如果要清掉整個 NodeMCU v3 裡面的資料,也可以用這個指令,如果純粹更新韌體,沒有這個指令,並不會抹除flash,之前所有檔案也都會續存:
sudo esptool.py --port /dev/ttyUSB0 erase_flash
可得到以下安裝過程
esptool.py v2.8
Serial port /dev/ttyUSB0
Connecting....
Detecting chip type... ESP8266
Chip is ESP8266EX
Features: WiFi
Crystal is 26MHz
MAC: 2c:f4:32:2d:6a:08
Uploading stub...
Running stub...
Stub running...
Erasing flash (this may take a while)...
Chip erase completed successfully in 10.3s
Hard resetting via RTS pin...
其中,/dev/ttyUSB0 是在 Linux 下的 COM 埠,在 Mac OS,也是叫 ttyxxxx之類的名字;在 Windows 下,COM埠的名字會是 COM1, 或 COM2, ... COM11,不同的主機板上,號碼可能有所不同。你可以去裝置管理員,找 CH340 是被配到哪個 COM Port。比如是在 COM2,指令則改成:
sudo esptool.py --port COM2 erase_flash

然後執行下面這個指令,把韌體刷進去 NodeMCU,指令中第二個變數,就是剛剛你下載的韌體的檔名:
esptool.py --port /dev/ttyUSB0 --baud 460800 write_flash --flash_size=detect 0 esp8266-1m-20210902-v1.17.bin

esptool.py v3.1
Serial port /dev/ttyUSB0
Connecting....
Detecting chip type... ESP8266
Chip is ESP8266EX
Features: WiFi
Crystal is 26MHz
MAC: 2c:f4:32:2d:6a:08
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 460800
Changed.
Configuring flash size...
Auto-detected Flash size: 4MB
Flash will be erased from 0x00000000 to 0x00090fff...
Flash params set to 0x0040
Compressed 589912 bytes to 389772...
Wrote 589912 bytes (389772 compressed) at 0x00000000 in 9.0 seconds (effective 523.7 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...

如果遇到一些問題,可以看看之前這篇 「用 Arduino 寫 NodeMCU V3 的 Blink 程式但 LED 不會閃」,裡面有一些可以參考的資料,或許有助於解決問題。

安裝在 ESP32

後來又買了更厲害的 ESP32,這片有雙核心,240MHz,內建 WiFi、藍芽,支援一路硬體 I2C Bus,IO也更多,且都支援 PWM,價格也貴幾十塊錢而已,一百出頭台幣就買得到。簡直打趴所有在抽屜中的MCU了。
ESP-WROOM-32 外觀 (39針腳版本)
ESP-WROOM-32 39針腳版本

一樣到這裡下載 ESP32使用的 MicroPython 韌體:

步驟跟指令都一樣,只是這片ESP32在執行燒寫前,需要把板子上的那顆 BOOT 按鈕,按著不要放開,才能完成抹除或燒寫韌體的過程,執行過程不能放開。
抹除 Flash
esptool.py --port /dev/ttyUSB0 --chip esp32 erase_flash
esptool.py v3.1
Serial port /dev/ttyUSB0
Connecting.......
Chip is ESP32-D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
Crystal is 40MHz
MAC: 94:b9:7e:d5:c9:54
Uploading stub...
Running stub...
Stub running...
Erasing flash (this may take a while)...
Chip erase completed successfully in 4.0s
Hard resetting via RTS pin...

 安裝 MicroPython 韌體,指令跟 ESP8266有些不同,必須從位址 0x1000 開始寫入

esptool.py --chip esp32 --port /dev/ttyUSB0 --baud 460800 write_flash -z 0x1000 esp32-20210902-v1.17.bin
esptool.py v3.1
Serial port /dev/ttyUSB0
Connecting....
Chip is ESP32-D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
Crystal is 40MHz
MAC: 94:b9:7e:d5:c9:54
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 460800
Changed.
Configuring flash size...
Flash will be erased from 0x00001000 to 0x00175fff...
Compressed 1527504 bytes to 987584...
Wrote 1527504 bytes (987584 compressed) at 0x00001000 in 24.9 seconds (effective 489.9 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...

ampy ls
/boot.py

跟之前一樣順利完成!執行 ampy ls 的指令後,顯示內容有一個 boot.py 的檔案。

連進去 NodeMCU 跟它對話

刷完韌體以後,可以馬上用終端機程式連線進去看看。MicroPython 在 UART0 (GPIO1=TX, GPIO3=RX) 預留 REPL 通訊介面, 鮑率速度是 115200 bps。
你可以安裝 Putty 這個跨平台終端機程式,開啟一個新的 Serial 連線,並儲存下來。然後執行連線之後,按一下 Enter 按鍵,就可以看到上面 MicroPython 簡介的那個畫面了。MicroPython 的終端機通訊寫得很好,不會有 ESP8266 原廠模組的通訊介面,存在 CR LF要另外按鍵的麻煩問題。
在 Ubuntu 下用 Putty 建立終端機連線


到此為止,你已經可以搜尋一些 MicroPython 程式教學,試驗一下 Python 程式,並實際打一些硬體控制的指令試試看。建議可以先瀏覽一下官方教學:Quick reference for the ESP8266

Winodws下,Putty 連線 NodeMCU
Windows 下的 Putty 設定

按 Ctrl-D 重開機

這個「作業系統」預留了一個快速軟體重開機的方法。在任何地方,按下鍵盤的 Ctrl-D,就可以執行重開機 Soft Reboot。
後篇:認識 MicroPython (二) - 啟用 WebREPL 遠端 WebSocket 服務

沒有留言:

張貼留言