3.3. 虛擬計時器¶
計時 頁面涵蓋了時間戳記以及由 time.ticks_diff() 驅動的非阻塞迴圈。虛擬計時器 則是另一面:軟體要求執行階段按排程呼叫某個函式,執行階段便會呼叫該回呼函式,而指令碼本身無需檢查時鐘。
3.3.1. machine.Timer 類別¶
machine.Timer 用來建構一個虛擬計時器。跨埠的行為需要使用特殊的 id -1;其餘的一切 —— period、mode、callback —— 都透過關鍵字引數來設定:
from machine import Timer
def tick(t):
print("tick")
tim = Timer(-1)
tim.init(period=100, callback=tick) # 10 Hz
回呼函式的呼叫方式與任何普通的函式呼叫無異 —— 它可以配置物件、print(),並呼叫其他函式庫程式碼,沒有任何特殊限制。
3.3.2. 週期性與單次¶
有兩種模式可用:
Timer.PERIODIC(預設值)。回呼函式每period毫秒觸發一次,永遠持續,直到呼叫deinit()或計時器被重新初始化為止。Timer.ONE_SHOT。回呼函式在init()之後period毫秒觸發一次,然後計時器即停止。
Timer(-1).init(mode=Timer.ONE_SHOT, period=2000, callback=fire)
deinit() 會停止一個週期性計時器並取消任何待處理的回呼:
tim.deinit()
3.3.3. 何時該使用計時器¶
虛擬計時器與 計時 中的 ticks_diff() 輪詢模式,是從相反的方向解決同一個問題。輪詢迴圈每次反覆都檢查時鐘,並在足夠的時間過去後採取行動;計時器則要求執行階段在足夠的時間過去後喚醒指令碼。
輪詢式
ticks_diff。一切都保持在同一處 —— 由迴圈掌管計時,沒有額外的回呼要追蹤。最適合把數個時間驅動的任務綁在一起、短而定義明確的工作。虛擬計時器。 把排程移出迴圈本體之外。最適合週期性任務獨立於主流程之外的情況(心跳 LED、週期性的感測器取樣),讓主迴圈得以把時間花在其他工作上。
這兩種做法都使用相同的底層時鐘,在一毫秒或更長的週期下能提供相同的準確度。兩者都不適合用於精準的接腳切換或次毫秒等級的波形產生 —— 回呼的延遲是排程器計時的等級,而非奈秒等級。