| ESP32 教學 | MicroPython | DHT11 溫濕度感測器 | 402 |

DHT11 或 DHT22 這兩顆感測器是我們在進行濕度感測應用時,最常使用的模組,不僅設計簡單,其規格也很符合日常生活使用,今天這篇就來試試如何利用 DHT11 與 OLED 顯示器結合,架設簡易的 ESP32 的溫濕度感測平台。

1. DHT11 溫濕度感測器介紹

要快速了解 DHT11相關的規格與操作,最快的方法當然去打開 datasheet 來查閱,不過做這個模組的廠商眾多,規格上都大同小異,JIMI哥 在網路上找了 Aosong Electronics (www.aosong.com) 公司所製作的感測器來做說明,下表為 DHT11 的基本規格:

dht11

DTH11 的操作範圍可以從 3.3V – 5.5V,也就是不管是 arduino 、microbit 或 ESP32 等都可以連接使用,最重要的規格就是使用範圍與精確度,此顆感測器可以測試 濕度 20 %-90 %&溫度 0-50 度,精確度分別為濕度正負5%& 溫度正負2度,換句話說,這個就是適合量測室內環境的感測器,各位朋友在使用一些感測器時,一定要事先確定量測的條件與環境,才不會發生無法量測或不合用的情況。

在來看一下這顆感測器接法,這顆是採用單線雙向傳輸傳輸方式,標準的接法為將 DATA 線接到 MCU 即可,並透過 MCU 下達開始指令。

DHT11 感測器便會依照 Datasheet 規範傳遞出濕度與溫度的數值,下面是 MCU 控制器與 DHT11 的時序圖。

JIMI哥 簡單解釋一下整個流程:

  1. 主機發送開始訊號 (呼叫 DHT11 開始量測訊號)
  2. 主機開始等待 DHT11 回應
  3. DHT11 回應訊息
  4. DHT11 準備發送資料(Ready Status)
  5. DTH11 開始丟出資料
  6. 結束傳輸程序

其實過程大約就是上述的這幾種狀態,這邊有個重要的地方要注意,DHT11 datasheet 規範每段完整通訊流程間隔,必須超過2秒以上,也就是當在MCU下完指令後,需等候2秒以上,再下達下一次的指令,避免會有通訊異常的狀態。

至於可能有朋友好奇 DHT11的資料格式長怎樣,這部分也可以查閱 datasheet:

資料會編成 40bit 的格式,先傳出濕度(共 16bits),再傳出溫度(共 16bits),最後則是 checksum 檢查資料傳遞過程是否有發生錯誤,每種資料都會有整數部分(integral part)跟小數點部分(decimal part),但小數部分都是會回傳0,後續我們只需要處理整數部分就好。

其實網路上有很多前輩針對 DHT11 或 DHT12 這顆感測器,教學如何撰寫底層的溝通程式,不管是 Uno、STM32 等,各位朋友如果有興趣的話,可以 google 相關的關鍵字,試著自己動手做一個,也可以更瞭解相關的知識。

2. Micropython DHT11 類別

DHT11 或 DHT22 感測器 Library 在 micropython 中也已內建,相關的用法很簡單:

import machine, dht
d11=dht.DHT11(machine.Pin(14))
d11.measure()					# start to measure
d11_temp=d11.temperature()		# return the temperature
d11_humid=d11.humidity()		# return the humidity

首先匯入 dht 與 machine 模組,並建立 dht11 的物件。

.measure() 這個方法是對 dht11 感測器下達開始量測濕度與溫度,.temperture() 會回傳溫度值(單位為攝氏度C),.humidity() (單位為濕度 %),只要注意每次量測的間距大於 2s,就不會發生通訊異常狀態。

3. DHT11 + OLED 顯示溫濕度值

接著來整合 DHT11 感測器與 0.96吋 OLED Display 動態顯示目前房間的溫濕度,更新的頻率設定為2秒更新一次。如果不知道 OLED 如何使用可以參考 JIMI哥之前寫的這2篇:

  1. 如果要顯示文字:208 I2C通訊界面與OLED 顯示文字TEXT
  2. 如果要顯示圖像:209 I2C通訊介面與OLED 顯示圖像IMAGE

– 電路連接

這邊 DHT11 的資料線選擇 ESP32 的 GPIO14, 連接 I2C 的腳位選用預設的硬體I2C ID1 SCL=GPIO25 SDA=GPIO26,電源選擇3.3V,完整電路連接如下:

– 完整程式碼

import machine, dht, utime,ssd1306
d11=dht.DHT11(machine.Pin(14))
hw_i2c1 = machine.I2C(1, freq=200000)        
oled096=ssd1306.SSD1306_I2C(128, 64, hw_i2c1)
oled096.fill(0) 
oled096.text('~ TEMP & HUMID ~',0,0)
oled096.text('Temp =    C',0,16)
oled096.text('Humid=    %',0,32)
oled096.show()
try:
    while 1:
        utime.sleep_ms(2000)
        d11.measure()
        oled096.fill(0)     
        oled096.text('~ TEMP & HUMID ~',0,0) 
        oled096.text('Temp = {} C'.format(d11.temperature()),0,16)
        oled096.text('Humid= {} %'.format(d11.humidity()),0,32)
        oled096.show()
        print('today temp ={}, humidity= {}'.format(d11.temperature(),d11.humidity()))
except Exception as e: print(e)

– 程式說明

import machine, dht, utime,ssd1306
d11=dht.DHT11(machine.Pin(14))
hw_i2c1 = machine.I2C(1, freq=200000)        
oled096=ssd1306.SSD1306_I2C(128, 64, hw_i2c1)

一開始先匯入 machine、dht、 utime、 ssd1306 這 4 個模組,目的是建立 GPIO、dht11、delay 、OLED的物件,d11( DHT11 物件 )使用 ESP32 GPIO14 做為資料傳輸,hw_i2c1 是 ESP32 硬體I2C id1的預設腳位物件,最後建立一個 OLED 的物件– oled096,解析度為128*64,使用 hw_i2c1 為底層I2C介面。

(此處記得要先將 ssd1306.py 這個模組上傳到 ESP32內,不然會有錯誤發生)

oled096.fill(0) 
oled096.text('~ TEMP & HUMID ~',0,0)
oled096.text('Temp =    C',0,16)
oled096.text('Humid=    %',0,32)
oled096.show()

oled096.fill(0) 將 OLED 的顯示資料清為 0 後,在畫面的第 0 行填入標題資訊,第 2 行顯示溫度欄位,第 4 行顯示濕度欄位,顯示文字 oled096.text()刮號內數字代表基於 OLED 像素位置的 XY 座標,因為 ssd1306 模組的字大小為 8*8 像素,所以 oled096.text(‘Temp = C’,0,16) 就是在畫面第 2 行開始顯示文字(OLED 第 0 行啟始位置為 0,0,第 1 行為 0,8),以此類推,並透過 oled096.show() 將上述資訊資訊顯示到 OLED 畫面上。

try:
    while 1:
        d11.measure()
        oled096.fill(0)     
        oled096.text('~ TEMP & HUMID ~',0,0) 
        oled096.text('Temp = {} C'.format(d11.temperature()),0,16)
        oled096.text('Humid= {} %'.format(d11.humidity()),0,32)
        oled096.show()
        print('today temp ={}, humidity= {}'.format(d11.temperature(),d11.humidity()))
        utime.sleep_ms(2000)
except Exception as e: print(e)

在 while 迴圈內,程式第 12 行開始對 DHT11 下指令進行量測溫度與濕度(d11.measure()),程式第 13 行的功能是為了避免每次溫濕度更新後,OLED 顯示數字畫面會有重疊現象,所以在每次迴圈都清除畫面一次。後續就是將溫度與濕度按照既定的位置分別在 OLED 畫面的第 0、2、4 行顯示,同時也透過 UART0 print 指令傳輸出資料進行比對。程式第 19 行為根據 DHT11 datasheet 規格,每次量測需間隔 2 秒以上,所以這邊 delay 設定為2000ms。最後如在整個通訊過程中如有發生異常,像 i2c 或 dht11 Timeout 的話,ESP32 將會輸出錯誤 Exception 訊息並停止。

4. 總結

DHT11 的各種相關實驗在網路上都可以搜尋到很多資料,這篇主要就是講解在 micropython 平台上,DHT11使用與 0.96吋 OLED 顯示器的基本整合,當然 ESP32 的強項就是物聯網應用,將溫濕度資料上傳到像 Thingspeak 這類的雲端收集平台也是容易的,下次 JIMI 哥就來分享如何利用 MQTT 通訊協定上傳資料的內容吧!請大家持續關注囉!

今天的內容就到這邊,如果有遇到什麼問題,歡迎在下面留言或寫信與我討論!~

發佈留言

Close Menu