MicroPython-On-ESP8266——擷取溫濕度傳感器資料(DHT11 / AHT10)
0. [外話] 後期基于nodemuc做開發學習與測試
之前用的青蛙創客的europa開發闆,接口封裝得太好,以緻于想自由接線的時候很是頭大。從淘寶上又買了塊nodemcu開發闆,不到十塊錢,用起來不心疼,真的是買不了吃虧買不了上當。
兩塊闆一主一從,後面有需要主從通訊什麼的,也可以實驗了。nodemcu刷micropython固件方法跟前面提到刷europa是一樣的,不過這麼會兒功夫,官方固件已經更新到 1.16了。 哎,咱這學習進度又拉下了。。。
強調一下 nodemcu闆子上的管腳字元标注跟實際GPIO管腳号是有差別的,需要按網上提供的接線圖做對照使用。
比如要使用GPIO0控制或讀取信号時,不能接到闆子上标注D0的針腳處,需要按對照圖接到D3(GPIO 00)上。這個一定要注意。
1. 擷取DHT11資料
1.1. 接線
手上有N年時買Arduino開發闆時送的DHT11子產品。DHT11子產品有4根針腳,有3根是有用的,見圖示。
我們把資料腳接入到D5(GPIO 14),旁邊就有正負極腳,走線整齊。
1.2. 讀取資料
micropython标準庫已經對DHT驅動進行了封裝,咱們直接用就可以了
import dht
import machine
d = dht.DHT11(machine.Pin(14))
d.measure() # 先調用測量函數
d.temperature() # 然後可以查濕度
d.humidity() # 和濕度了
廣東的天氣吓死人,房間裡面都32度。空調開起來~~
DHT11精度隻到整數,這就不要談什麼誤差了吧,真的是僅限學習使用了。
2. 擷取AHT10資料
2.1. AHT10子產品說明
買nodemcu時,順手也買了個AHT10子產品,這個子產品精度要高于DHT11,網上找了下讀取資料的資料。
在廠商奧松官網産品頁,赫然看到該子產品已停産。流年不利,且行且珍惜吧。不過産品說明書還是能下載下傳。
産品手冊前面啰裡吧嗦的那些就先不管了,直接在第8頁看到有對使用方法和解析資料的說明。幹脆也貼下圖吧
“傳感器讀取流程”的意思來看,子產品接線并上電後,需要先從主機給它發送初始化指令,然後就跟DHT11的measure一樣測量一下,就可以讀取溫濕度資料了。中間要注意的就是傳回的資料可能因為傳感器狀态忙而無效。
咱們學習時候就先不管狀态的事兒了,按正常流程手動指令去執行,晶片怎麼地都忙完了。
2.2. 接線
AHT10購買時介紹中說的資料走的I2C總線,官方手冊前面也提到這一點了。I2C總線需要4條線來連接配接,子產品背後也标注了。nodemcu上需要用正負極加兩個GPIO接口來與之對應。我這裡的接線方式為(AHT10 – nodemcu) vin – 3v, GND – G, SCL – GPIO 05 (D1), SDA – GPIO 04 (D2)
如圖:
另外還要注意一點,AHT10手冊上有說VIN輸入的電壓範圍是1.8V到3.6V之間,是以咱們接線時隻能接到3.3V針腳上,不要接到5V了,燒穿就沒得玩了。
2.3. micropython讀取資料
引入基礎庫,并定義I2C總結協定使用的引腳
from machine import Pin, I2C
i2c = I2C(scl=Pin(5), sda=Pin(4), freq=100000)
官方手冊裡面寫了AHT10子產品的從機位址是0x38,如果不放心,可以自己掃找描去拿位址:
掃描到的位址是56(十進制),跟官方寫的0x38(十六進制)是一緻的。
線已經接好了,咱們就直接先初始化裝置,然後就可以測量了
i2c.writeto(addr, b'\xE1\x08\x00') # 初始化
i2c.writeto(addr, b'\xAC\x33\x00') # 測量
測量完按手冊說的,要先查狀态再決定要不要讀取結果,這裡先直接讀結果到中間變量,友善後面計算
讀取到6個位元組的資料,其中第1個位元組是狀态位,後面5個位元組分兩半存儲了濕度和溫度資料
rst0 = data[1]<<12 | data[2]<<4 | data[3]>>4
rst1 = (data[3]&0x0f)<<16 | data[4]<<8 | data[5]
這裡涉及到位運算和位移的操作,目的是把紅框和綠框兩個數拆分開。
基本方法是把高位數向左移位後,與後面的低位數按位或運算,就得到各自的二進制完整數值。綠框最高位因為隻有一半,是以先跟0x0F做與運算,把該位元組的前4位置為0而保留後4位的原始值。
另外手冊第9頁有轉換資料的公式,按圖索骥
from math import pow
# 濕度轉換公式
humidity = rst0 / pow(2, 20) * 100
# 溫度轉換公式
temperature = rst1 * 200 / pow(2, 20) - 50
REPL實測效果:
開了空調果然不一樣,溫度下來不說,濕度變低就沒那麼躁了。
2.4. AHT10三方驅動庫
淘寶購買AHT10子產品時,産品介紹頁資料中有C++版本的驅動庫檔案。(前面按位操作取值也是參考該庫來着)
網上搜尋到有大神已經對mpy版本進行封裝和開源了,見 Gitee庫AHT10
有了這個庫其實直接拿來用就好了,省去翻看官方手冊的時間了。相見恨晚呐~~
2.5. 自用驅動庫
上面大神庫加入了溫度取攝氏度還是華氏度模式,也跟官方驅動一樣實作了露/霜點的計算,這些咱用不到,就按DHT11的模式做個近似的封裝。
按官方手機的說明來看,加入了狀态位的判斷,空閑時取到的溫濕度才有效
import utime
class AHT10:
def __init__(self, i2c, address=0x38):
if i2c is None:
raise ValueError('I2C object required.')
self.i2c = i2c
self.address = address
self.i2c.writeto(self.address, b'\xE1\x08\x00') # 初始化子產品
self._h, self._t = 0, 0 # 濕度,溫度
def status(self, data=None):
'檢查忙閑狀态'
if not data:
self.i2c.writeto(self.address, b'\x71')
data = self.i2c.readfrom(self.address, 1)
return data & 0x40 # 最高位為1是忙(測量中)
def measure(self):
'測量'
self._h, self._t = 0, 0
for _ in range(3): # 最多重試3次
self.i2c.writeto(self.address, b'\xAC\x33\x00')
utime.sleep_ms(100) # 子產品需要80ms以上的測量時間
raw = self.i2c.readfrom(self.address, 6)
if self.status(raw[0]):
utime.sleep_ms(20) # 忙就稍等再測
else:
data_h = raw[1] << 12 | raw[2] << 4 | raw[3] >> 4
data_t = (raw[3] & 0x0F) << 16 | raw[4] << 8 | raw[5]
self._h, self._t = data_h * 100 / 1048576, ((200 * data_t) / 1048576) - 50
break
def humidity(self):
'傳回測量到的濕度 %RH'
return self._h
def temperature(self):
'傳回測量到的溫度 C'
return self._t
def reset(self):
'軟複位'
self.i2c.writeto(self.address, b'\xBA')
utime.sleep_ms(20)