關於MicroPython mpremote工具 的一些用例,閑聊
- 2022 年 9 月 5 日
- 筆記
- MicroPython
我嘗試了很多不同的第三方micropython工具,有些是Windows應用程式,有些是VScode插件。
但是當我嘗試過MicroPython的mpremote工具後,我幾乎決定它將成為我的首選工具。😄
我通常將其與VScode結合使用。它的程式碼突出顯示,自動完成和自動縮進非常有用。同時打開其他插件也很容易。另外VScode也是一個多平台的IDE,我比較習慣在幾個不同的作業系統里用同一個IDE,來回切換不會生手。
也許有些極簡主義者,我認為mpremote工具也會很合適,只需將系統的終端與任何文本編輯器一起使用即可,如果你是命令行老手,則只需要一個終端即可完成所有操作。
目錄 (Table of Contents)
鏈接
PyPI 頁面 在終端用pip install mpremote
命令即可安裝。(推薦)
本文在GitHub micropython/discussions/9096的頁面
1. cp
這可能是除 repl 之外最常見的命令,用於將文件從本地複製到設備,或從設備複製到本地。可能是因為我還不熟悉終端命令語法,起初我無法從MicroPython文檔中的幾個用例中完全掌握cp命令的用法,反覆運用和嘗試後就漸漸上手了。
1.1 在終端的當前路徑中複製文件
首先創建一個乾淨的臨時文件夾,並在其中寫入一個main.py
文件。
print ("start")
for i in range(2):
print(i)
print ("end")
最簡單的用例,在終端中輸入此文件夾路徑,將文件從本地複製到設備:
mpremote connect COM1 cp main.py :
mpremote connect COM1 cp main.py :main.py
這兩個命令實現完全相同的功能。
在:
符號之後,如果輸入文件名,則文件在複製到設備時將重命名為此文件名。
將文件從設備複製到本地 :
mpremote connect COM1 cp :main.py .
mpremote connect COM1 cp :main.py main.py
這兩個命令實現完全相同的功能。
如果要重命名,可以刪除.
符號並輸入所需的文件名。
1.2 複製絕對路徑中的文件
它有點複雜。
在 Windows 上,使用文件的絕對路徑從本地複製到設備:
mpremote connect COM1 cp D:\temp\main.py :main.py
將文件從設備複製到本地 :
mpremote connect COM1 cp :main.py D:\temp\main.py
目前在mpremote 0.3.0版本,應特別注意在Windows中不能省略目標文件名!
我在 GitHub 上已提交PR #9148 對 Windows 路徑名分隔符的支援,下一個版本應該就可以隨意在Windows里使用相對路徑和絕對路徑了,不影響其他功能。
在 Linux(如 Ubuntu)中,從絕對路徑複製文件可以省略目標文件名:
mpremote connect /dev/ttyACM0 cp ~/temp/main.py :
mpremote connect /dev/ttyACM0 cp /home/wind/temp/main.py :
mpremote connect /dev/ttyACM0 cp :main.py ~/temp/
mpremote connect /dev/ttyACM0 cp :main.py /home/wind/temp/
1.3 同時複製多個文件
在Linux中,例如Ubuntu,將多個文件從本地複製到具有絕對路徑的設備:
mpremote connect /dev/ttyACM0 cp ~/temp/main.py ~/temp/main2.py :
將多個文件從設備複製到本地絕對路徑:
mpremote connect /dev/ttyACM0 cp :main.py :main2.py ~/temp/
2. exec, run
這些命令用於控制遠程設備在不複製文件的情況下運行 Python 程式碼或腳本。
2.1 執行給定的 Python 程式碼
mpremote connect COM1 exec "print(1234)"
就像在REPL中輸入一行Python程式碼一樣。
2.2 從本地文件系統運行腳本
mpremote connect COM1 run test_1.py
就像在REPL中進入粘貼模式一樣,將程式碼複製並粘貼到指定的Python腳本中,然後運行它。
3. mount
我未曾想過有這種使用MicroPython設備的方法,請看以下用例並嘗試理解它,隨後你就會像我一樣對這個功能愛不釋手~~
3.1 在遠程設備上掛載本地目錄
首先創建一個乾淨的臨時目錄,並在其中寫入一些Python腳本,如下所示:
# numbers.py
num_1 = 21
num_2 = 22
num_3 = 23
num_4 = 24
# test_1.py
print("test_1 start")
import numbers
print(numbers.num_1)
print(numbers.num_2)
print(numbers.num_4)
print("test_1 end")
# test_2.py
print("test_2 start")
import numbers
temp1 = numbers.num_3 - numbers.num_2
print(temp1)
temp1 = numbers.num_3 - numbers.num_1
print(temp1)
print("test_2 end")
在終端中輸入此目錄的路徑。
我們先確認一些資訊,列出設備上的文件:
mpremote connect COM1 ls
ls :
139 boot.py
進入 REPL 並再次確認:
mpremote connect COM1 repl
>>> uos.listdir()
['boot.py']
>>>
退出 REPL,掛載本地目錄,再次進入 repl:
mpremote connect COM1 mount . repl
再次確認文件:
>>> uos.listdir()
['numbers.py','test_1.py', 'test_2.py']
這裡沒有boot.py
,但我們在本地目錄創建的Python腳本出現在列表中。
導入並運行兩個測試腳本:
>>> import test_1,test_2
test_1 start
21
22
24
test_1 end
test_2 start
1
2
test_2 end
>>>
查看一個文件:
>>> f=open("numbers.py")
>>> print(f.read())
# numbers.py
num_1 = 21
num_2 = 22
num_3 = 23
num_4 = 24
>>>
驚訝之餘,你可能想知道,這些python腳本文件是不是全部都上傳到設備上並存儲起來了?我最初也是這麼猜測的。
現在,我們將終端保留在REPL中,在本地修改此文件:
# numbers.py
num_1 = 1
num_2 = 12
num_3 = 23
num_4 = 35
返回 REPL 並再次檢查:
>>> f=open("numbers.py")
>>> print(f.read())
# numbers.py
num_1 = 1
num_2 = 12
num_3 = 23
num_4 = 35
>>>
這樣就解除疑惑了,文件只保存在本地目錄中,並且這個目錄被掛載在設備上。
軟體重置後,並將重新掛載目錄。
這就像是一個移動硬碟,或者是說像是NAS,雲盤,連在MicroPython設備上,顯然這個功能能極大節約設備的flash壽命,通常只需要在必須離線運行的時候再把python腳本文件拷貝到flash里即可。
推薦使用以下組合命令執行python腳本:
mpremote connect COM1 mount . exec "import test_1"
3.2 在掛載了本地目錄後繼續使用原flash中的腳本
在REPL中使用uos.listdir("/")
命令你將看到原來存儲在flash中的文件:
>>> uos.listdir("/")
['remote', 'boot.py', 'main.py']
如果你想保持掛載本地目錄的狀態下使用flash中的腳本(例如main.py
),你可以使用如下命令將原flash根目錄路徑添加進sys.path
列表中:
>>> import sys
>>> sys.path
['', '.frozen', '/lib']
>>> sys.path.append("/")
>>> sys.path
['', '.frozen', '/lib', '/']
>>> import main
如果掛載的本地目錄中已有main.py
,則僅會運行本地目錄的main.py
,可通過reverse()
調換列表順序:
>>> sys.path
['', '.frozen', '/lib', '/']
>>> sys.path.reverse()
>>> sys.path
['/', '/lib', '.frozen', '']
>>> import main
現在就會優先運行flash中的腳本。
3.3 加快測試速度的一種方法
如果我們需要對一個腳本一遍測試一遍修改,而腳本中已經導入了很多存儲在本地的腳本模組,這樣的情況下,每一次掛載測試都將花費數秒甚至數十秒的時間。
我總結了一種方法,在REPL中設法不重複的import
模組即可有效減少運行時間。
以測試SSD1306 OLED顯示器為例,main.py
是主程式,ssd1306.py
是驅動模組,此處就不再完整列舉程式程式碼了。
通過time.tick_ms()來驗證測試本地目錄的main.py
腳本所需的時間,可見大概需要6秒:
>>> import time;t1 = time.ticks_ms();import main;time.ticks_diff(time.ticks_ms(),t1)
6032
使用sys.modules
可以查看當前已經導入的腳本模組,可見ssd1306.py
已經導入:
>>> import sys;sys.modules
{'main': <module 'main' from 'main.py'>, 'ssd1306': <module 'ssd1306' from 'ssd1306.py'>, 'flashbdev': <module 'flashbdev' from 'flashbdev.py'>}
我們僅需移除main
而保留其他的模組:
>>> del main;sys.modules.pop('main')
<module 'main' from 'main.py'>
>>> import sys;sys.modules
{'ssd1306': <module 'ssd1306' from 'ssd1306.py'>, 'flashbdev': <module 'flashbdev' from 'flashbdev.py'>}
再次測試:
>>> import time;t1 = time.ticks_ms();import main;time.ticks_diff(time.ticks_ms(),t1)
1612
得到明顯改善。