計時器與感測資料的定期量測

對於一個感測器的模組來說,能夠定時地量測資訊是非常重要的功能之一。在這一個單元中,我們將介紹如何使用MicroPython 中的計時器功能,讓NodeMCU可以訂時地量測感測器上的資訊,並且把它們都記錄下來。

為了測試計時器功能,請先使用NodeMCU以及擴充板,連接2個簡單的LED輸出。為了方便起見,在這裡我們就不另外接2個不同的LED,而是利用內建有限流電阻的RGB LED來做練習,接線如下:

我們把NodeMCU的D1接上LED的R端,D2接到LED的B端,然後把NodeMCU的GND連接到LED的負極。仔細看LED端的連接如下:

而在NodeMCU端的連線則如下所示:

連接完成之後,請把此NodeMCU連接上電腦,然後使用以下的程式碼測試一下是否能夠正常地依序點亮並熄滅紅色和藍色的燈號:

from machine import Pin
import time
ledR = Pin(5, Pin.OUT)
ledB = Pin(4, Pin.OUT)
for i in range(10):
ledR.on()
time.sleep(0.5)
ledR.off()
ledB.on()
time.sleep(0.5)
ledB.off()

執行結果如下:

上述的程式可以順利地執行燈光閃爍的動作,但是如果同學利用REPL的方式執行此程式的時候會發現,因為是使用for迴圈在專心地執行閃爍的動作,此時在迴圈之外並沒有辦法做些什麼其它的事。

為了避免此種定期執行的作業佔用系統資源的情形發生,我們需要計時器的幫忙。

計時器的模組是Timer,它最重要的兩個函數是 init()以及deinit()。其中init()函數是用來設定計時器的函數,此函數需要3個參數,分別是定時的週期(以毫秒為單位)、執行的模式(只執行一次Timer.ONE_SHOT或週期性的循環Timer.PERIODIC)、以及回呼函數,也就是時間到了要執行的是哪一個函數。

以下是一個計時器的方式來實作紅藍LED閃爍的程式例:

from machine import Pin, Timer
def blink(t):
ledR.value(not ledR.value())
ledB.value(not ledB.value())
ledR = Pin(5, Pin.OUT)
ledB = Pin(4, Pin.OUT)
ledR.on()
ledB.off()
t = Timer(0)
t.init(period=200, mode=Timer.PERIODIC, callback=blink)

有了計時器之後,接著我們就可以讓程式定期量測感測器數值,然後把它記錄下來。首先,請先再一次連接溫濕度感測器,這一次我們使用是DHT22,連接如下:

如上圖所示,DHT22在這個方向的最左邊是PIN1,請把它連接到正極(5V),最右邊是PIN4,請把它連接到負極(GND)。PIN3請留空,至於PIN2在連接之前,請先連接一個5K歐姆的電阻,再連接到正極,同時也要從PIN2處連接一條線到NodeMCU的D1。

連接完成之後可以使用進入REPL,使用以下的程式測試一下目前的溫濕度:

>>> import dht
>>> from machine import Pin
>>> d = dht.DHT22(Pin(5))
>>> d.measure()
>>> d.temperature()
31.1
>>> d.humidity()
64.8

測試完成之後,我們就可以利用計時器來完成定時量測的工作,如下所示:

from machine import Pin, Timer
import dht
def m(t):
d.measure()
print("{},{}".format(d.temperature(), d.humidity()))
d = dht.DHT22(Pin(5))
t = Timer(0)
t.init(period=50000, mode=Timer.PERIODIC, callback=m)
try:
pass
except:
t.dinit()

此程式在輸入完畢之後 每隔5秒就會顯示一次目前的溫濕度數值,直到你按下Ctrl-Break或是按下板子上的Reset按鈕為止。