--- title: MicroPython 與有採樣間距需求的感測器 image: https://i.imgur.com/f2cjXwk.png disqus: paoyung --- # MicroPython 與有採樣間距需求的感測器 ###### tags: `MicroPython` `ESP32` > [color=#58f][name=Paoyung][time=Jun 06, 2022] [:snake: ℳ𝒾𝒸𝓇ℴ𝒫𝓎𝓉𝒽ℴ𝓃 隨手記](/@PaoyungChang/mpy_trifiles) 前言 --- 在 MicroPython 的創作中,常常要用上多種感測或顯示元件,以標準的撰寫風格會以 while 讓任務輪詢,當遇上有採樣間距的元件則以 sleep 稍做停等,但一旦遇上多種感測元件却有著不同停等間隔時,就很容易造成干擾或卡頓。若每個被調用元件的模組都能做好時間的管理,令人困擾的問題或許就能得以改善。在此以坊間經常使用的 DHT11 溫濕度傳感器配搭 ESP32 做為例子。 Timer --- MicroPython 在 ESP32 上有 4 組 Timer 可用,模式有 ONE_SHOT 和 PERIODIC,相當於 Javascript 中的 setTimeout 和 setInterval。相關文件可參閱官方說明。而在下方的範例中,要做時間管理就必須佔用一組,預設是 Timer3,也可視情況自行指定。 > [color=green][Quick reference for the ESP32](https://docs.micropython.org/en/latest/esp32/quickref.html#timers) 數據與異常 --- - DHT11 的官方文件說其採樣週期間隔不得低於 1 秒,網路上的教學則建議為 2 秒,以下的範例仍依官方建議,**可視個人需求再行修改**。  - 而在某些元件或應用時,數據容易產生跳動,但正常情況下溫濕度是不會在幾秒內產生明顯變化,所以通常會用上一點小技巧做去抖均化,不過 DHT11 的精度不高,比較看不出其差別,因此暫不納入考量,待日後有機會再行展示。 > [color=green][DHT11 datasheet](https://cdn-shop.adafruit.com/datasheets/DHT11-chinese.pdf) 穿外套 --- MicroPython 的 dht 模組如前所述,採樣週期過短時會發出異常,造成程式執行的中斷,若希望能有一個可自行管理時間,不管何時呼叫它都不要阻斷和中斷的程式模組,就必須擴充模組的功能。擴充的方式有很多,正規做法是用 class 的繼承再加上 funtion 的覆寫來達成,在此不打算這麼做,而只是要幫原來的模組穿個外套:coat:,將原來的 dht 包在裡面,利用 timer 在安全的時間才做動作,僅此而已。其用法必須和原來的 dht 一致,才能讓已套用它的程式碼做最小幅的修改,即能改善異常的問題。 程式 --- [dht11.py](https://gist.githubusercontent.com/paoyung/664cc0367fe310fe7edac1b687d32c03/raw/17881cc3f2b47ea7b650f44ae05d8e5d97a9ab5a/dht11.py) {%gist paoyung/664cc0367fe310fe7edac1b687d32c03%} 將上述的程式存為 [dht11.py]() 並上傳至 ESP32。用法就和原來的相同,僅做小幅的改變即可。 範例1 --- ```python= from machine import Pin from dht11 import DHT11 from time import sleep def demo(): # 未指定 Timer,預設使用 Timer3 d11 = DHT11(Pin(13)) led = Pin(2, Pin.OUT) while 1: led.value(not led.value()) d11.measure() print('T:', d11.temperature()) print('H:', d11.humidity()) print('---------') sleep(0.5) ``` 範例2 --- ```python= from machine import Pin, Timer from dht11 import DHT11 from time import sleep def demo_interval(): # 指定使用 Timer0 tim0 = Timer(0) d11 = DHT11(Pin(13), tim0) led = Pin(2, Pin.OUT) def callback(t): d11.measure() print('T:', d11.temperature()) print('H:', d11.humidity()) print('---------') tim2 = Timer(2) tim2.init(period=1200, mode=Timer.PERIODIC, callback=callback) while 1: led.value(not led.value()) sleep(0.5) ``` 使用建議 --- 範例 1 因在 measure 後執行了 sleep,而 measure 執行會佔用一小段時間,因此會增加實際 sleep 的時間,相對於較為要求精確的 case 會建議使用範例 2 的做法。 :sunglasses: {%hackmd /@PaoyungChang/intro_v0702 %}
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up