資料介紹
描述
介紹
在這個(gè)項(xiàng)目中,我開發(fā)了一個(gè) Arduino 庫來讀取 DHT11 濕度和溫度傳感器生成的數(shù)據(jù),并使用 AZDelivery ESP8266 ESP-12F NodeMCU Lua Amica V2 將其連續(xù)發(fā)送到 ThingSpeak 云服務(wù)。
有許多庫可以用來讀取 DHT11 傳感器數(shù)據(jù)。那么,為什么要重新發(fā)明輪子呢?只是為了了解事物的運(yùn)作方式并可能改進(jìn)它們的樂趣。
我使用邏輯分析儀和 DHT11 傳感器數(shù)據(jù)表來了解協(xié)議并為傳感器開發(fā)自己的庫。DHT11 溫度和濕度傳感器
DHT11 溫度和濕度傳感器具有溫度和濕度傳感器復(fù)合體,具有校準(zhǔn)的數(shù)字信號(hào)輸出。采用獨(dú)有的數(shù)字信號(hào)采集技術(shù)和溫濕度傳感技術(shù),確保高可靠性和出色的長期穩(wěn)定性。該傳感器包括一個(gè)電阻式濕度測(cè)量元件和一個(gè)NTC溫度測(cè)量元件,并連接到一個(gè)高性能8位微控制器,具有卓越的品質(zhì)、快速的響應(yīng)、抗干擾能力和成本效益。
PINOUT 和 MCU 連接
MCU 到 DHT11 連接
使用的分線模塊已經(jīng)有一個(gè) 10 KOhm 的上拉電阻。
DHT11 數(shù)據(jù)引腳連接到 D1 (GPIO5)
GPIO 0-15 都有一個(gè)內(nèi)置的上拉電阻器,如果直接使用 DHT11 而不是分線器,我們可以使用它。
有關(guān)如何在我的NodeMCU Amica V2 路試中設(shè)置此模塊的更多信息
AZ Delivery NodeMCU V2 路試,作者:Enrique Albertos。
https://www.hackster.io/javagoza/nodemcu-amica-v2-road-test-2e8bff
MCU 到 DHT11 通信
DHT11 單總線數(shù)據(jù)格式
單總線數(shù)據(jù)格式用于 MCU 和 DHT11 傳感器之間的通信和同步。一個(gè)通信過程大約是4ms。數(shù)據(jù)由小數(shù)部分和整數(shù)部分組成。一次完整的數(shù)據(jù)傳輸為 40 位,傳感器先發(fā)送高位數(shù)據(jù)。
數(shù)據(jù)格式:
8
bit integral RH data + 8
bit decimal RH data + 8
bit integral T data + 8
bit decimal T data + 8
bit checksum.
如果數(shù)據(jù)傳輸正確,校驗(yàn)和應(yīng)該是:
8
bit integral RH data + 8
bit decimal RH data + 8
bit integral T data + 8
bit decimal T data
PulseView 和邏輯分析儀
PulseView 是 libsigrok 和 libsigrok 解碼庫的圖形前端,允許訪問各種設(shè)備和協(xié)議解碼器,讓您記錄、分析、處理和導(dǎo)出模擬和邏輯數(shù)據(jù)。
邏輯分析儀
我們正在使用 AZ-Delivery 的這款廉價(jià)邏輯分析儀來監(jiān)視 MCU 和 AZ Delivery NodeMCU 8266 Amica 模塊之間的通信。
邏輯分析儀有 8 個(gè)并行輸入 (0-5 V),每秒最多允許 2400 萬個(gè)測(cè)量步驟。對(duì)于數(shù)字信號(hào),采樣速度必須比帶寬快 4 倍。這意味著帶寬是采樣率的四分之一。
- 最大數(shù)字采樣率:24 MSPS
- 最大數(shù)字帶寬:6 MHz
這足以監(jiān)視這種簡單的通信所需的 200 Khz。
脈沖視圖
安裝后,您會(huì)在開始菜單中找到一個(gè)名為 Zadig 的程序。默認(rèn)情況下,Windows 識(shí)別的某些設(shè)備將安裝 PulseView 無法使用的驅(qū)動(dòng)程序。Zadig 的目的是讓您更改 Windows 用于特定設(shè)備的驅(qū)動(dòng)程序 - 對(duì)于大多數(shù)設(shè)備,您需要選擇 WinUSB 以將它們與 PulseView 或原始專有 Windows 驅(qū)動(dòng)程序一起使用以將其與您訪問設(shè)備的任何其他軟件一起使用和。
新會(huì)話
- 打開一個(gè)新會(huì)話
- 選擇您要使用的設(shè)備:
- 點(diǎn)擊“運(yùn)行”獲取信號(hào)數(shù)據(jù)(設(shè)置了則等待觸發(fā))
放大直到看到信號(hào),MCU 和 DHT11 之間的通信大約需要 135 毫秒。
這是向傳感器請(qǐng)求數(shù)據(jù)時(shí)的位流。
DHT11單線通訊協(xié)議解碼器
Pulseview 帶有一個(gè) DHT11 協(xié)議解碼器。讓我們使用它。
添加解碼器并將其關(guān)聯(lián)到串行數(shù)據(jù)線。D1 在我們的例子中。
該解碼器處理傲松 AM230x/DHTxx/RHTxx 系列數(shù)字濕度和溫度傳感器使用的專有單線通信協(xié)議。
采樣率:建議使用至少200 kHz的采樣率來正確檢測(cè)協(xié)議的所有元素。
選項(xiàng):
AM230x 和 DHTxx/RHTxx 數(shù)字濕度和溫度傳感器使用相同的單線協(xié)議,測(cè)量值的編碼不同。因此,必須使用選項(xiàng)“設(shè)備”來正確解碼各個(gè)傳感器的通信。“ dht11 設(shè)備類型”用于我們的目的。
縮放以查看解碼數(shù)據(jù)
相對(duì)濕度 %
8 位積分 RH 數(shù)據(jù) + 8 位十進(jìn)制 RH 數(shù)據(jù)
溫度
8位整數(shù)T數(shù)據(jù)+8位十進(jìn)制T數(shù)據(jù)
校驗(yàn)和
8 位積分 RH 數(shù)據(jù) + 8 位十進(jìn)制 RH 數(shù)據(jù) + 8 位積分 T 數(shù)據(jù) + 8 位十進(jìn)制 T 數(shù)據(jù)
使用 ESP8266 內(nèi)核為 Arduino 讀取傳感器數(shù)據(jù)
我們有幾種方法來讀取數(shù)據(jù)并處理 DHT11 使用的專有單線通信協(xié)議:
- 盲循環(huán):等待固定的時(shí)間,并假設(shè) I/O 將在該固定延遲過去之前完成。此方法不適合我們讀取傳感器數(shù)據(jù),因?yàn)?0s 和 1s 時(shí)序不同,您可能會(huì)失去同步,但我們將使用它來啟動(dòng)信號(hào)到 DHT,因?yàn)檫@是使 DHT11 從低電平變化的盲信號(hào)-power-consumption mode 到 running-mode。
- 忙等待同步或輪詢。檢查完成狀態(tài)的 I/O 狀態(tài)的軟件循環(huán)。這可能是我們讀取 DHT11 發(fā)送數(shù)據(jù)的第一個(gè)候選者,因?yàn)橄到y(tǒng)非常簡單,實(shí)時(shí)響應(yīng)并不重要。
- 中斷。使用硬件導(dǎo)致特殊的軟件執(zhí)行。當(dāng)輸入設(shè)備有新數(shù)據(jù)時(shí),硬件將請(qǐng)求并中斷。軟件中斷服務(wù)將從輸入設(shè)備中讀取并保存在全局 RAM 中。為了簡單起見,我們不會(huì)使用這種方法。
開始信號(hào) - 盲循環(huán)
Data Single-bus free 狀態(tài)為高電平。當(dāng) MCU 和 DHT11 開始通信時(shí),MCU 程序會(huì)將 Data Single-bus 電壓電平從高電平設(shè)置為低電平,這個(gè)過程必須至少需要 18 ms 才能確保 DHT 檢測(cè)到 MCU 的信號(hào),然后 MCU 會(huì)拉高電壓并等待 20 -40 我們 DHT 的回應(yīng)。
/**
MCU Sends Start Signal to DHT as this is a blind cycle that makes DHT11
to change from the low-power-consumption mode to the running-mode
Consists of a pulse of at least 18 ms voltage-length
@params void
@return true if there no problem
*/
boolean DHT11::sendStartSignal(void) {
digitalWrite(pin, LOW); // MCU Send start signal
pinMode(pin, OUTPUT);
delay(timeLengthWakeupSignal_ms); // at least 18 ms
// MCU Pulls up voltage
pinMode(pin, INPUT);
digitalWrite(pin, HIGH); // Switch to receive data
return true;
}
本項(xiàng)目使用的 DHT11 模塊有一個(gè) 10K 的上拉電阻,所以我們不設(shè)置 INPUT_PULLUP。
DHT一旦檢測(cè)到啟動(dòng)信號(hào),就會(huì)發(fā)出一個(gè)低電平響應(yīng)信號(hào),持續(xù)80us。然后DHT程序?qū)ata Single-bus電壓電平由低到高并保持80us,為DHT發(fā)送數(shù)據(jù)做準(zhǔn)備。
忙等待同步
然后我們將使用忙等待同步來檢測(cè)以下脈沖沿,從 RAISING 到 FALLIN 以及從 FALLING 到 RAISING
/**
Waits until digital port changes to final state or timeout occurs
@param pin to check
@param state to wait for
@param maximum time to wait
@return the elapsed time to reach the final state if less than timeout
or the elapsed time that forced the timeout
*/
int DHT11::busyWait(const int pin, const int finalState, const int timeout) {
int elapsedTime = 0;
int startTime = micros();
while ( digitalRead(pin) != finalState && elapsedTime < timeout ) {
elapsedTime = micros() - startTime;
}
return elapsedTime;
}
忙于等待啟動(dòng)信號(hào)響應(yīng)
首先等待啟動(dòng)信號(hào)響應(yīng)
DHT一旦檢測(cè)到啟動(dòng)信號(hào),就會(huì)發(fā)出一個(gè)低電平響應(yīng)信號(hào),持續(xù)80us。所以我們將等待 DHT11 準(zhǔn)備好。
/**
Once DHT detects the start signal, it will send out a low-voltage-level
response signal, which lasts 80us. So we will wait for the DHT11 to be ready.
@param void
@return true if there no problem
*/
boolean DHT11::waitForStartSignalResponse(void) {
return busyWait(pin, LOW, timeoutForStartData_us) < timeoutForStartData_us;
}
忙于等待起始位
然后等待起始位
/**
DHT sends out response signal and keeps it for 80 us
then DHT pulls up voltage and keeps it for 80 us
@param void
@return true if there no problem
*/
boolean DHT11::waitForStartBit(void) {
if ( busyWait(pin, HIGH, timeoutForResponseSignal_us) < timeoutForResponseSignal_us) { // DHT sends oit response signal and keeps it for 80 us
return (busyWait(pin, LOW, timeoutForStartData_us) < timeoutForStartData_us); // then DHT pulls up voltage and keeps it for 80 us
}
return false;
}
忙等待讀取 40 位數(shù)據(jù)
最后讀取 40 位數(shù)據(jù)
/*
Read the 40 bits in a Dht11 data record
@param pointer to the record to be actualized
@return true if there no problem
*/
boolean DHT11::readDht11DataRecord(DHT11::Dht11_data_type * dataRead)
{
uint8_t integralRh = readByte(pin, timeoutForStartToTransmitData_us, timeoutForData_us, zeroLength_us);
uint8_t decimalRh = readByte(pin, timeoutForStartToTransmitData_us, timeoutForData_us, zeroLength_us);
uint8_t integralTemp = readByte(pin, timeoutForStartToTransmitData_us, timeoutForData_us, zeroLength_us);
uint8_t decimalTemp = readByte(pin, timeoutForStartToTransmitData_us, timeoutForData_us, zeroLength_us);
uint8_t checksum = readByte(pin, timeoutForStartToTransmitData_us, timeoutForData_us, zeroLength_us);
// Verify checksum: integral RH + decimal RH + integral Temp data + decimal Temp data
if ( (integralRh + decimalRh + integralTemp + decimalTemp ) != checksum ) {
dataRead->error = ERROR_CHECKSUM;
dataRead->status = statusString[ERROR_CHECKSUM];
return false;
}
dataRead->error = ERROR_NONE;
dataRead->status = statusString[ERROR_NONE];
dataRead->temperature = (float)integralTemp + (float)decimalTemp / 10.0;
dataRead->humidity = (float)integralRh + (float)decimalRh / 10.0;
return true;
}
讀取一個(gè)字節(jié)
如果檢測(cè)到“1”位,則字節(jié)初始化為 b0000 0000,位位置使用 BIT_MASK 切換
const uint8_t BIT_MASK[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
/*
Read 8 bits in a byte from the line
@param pointer to the record to be actualized
@param int pin,
@param int timeout For Start To Transmit Data in us
@param int timeout For Data in us,
@param int bit Zero Length in us
@return the read byte if any or FF if there is any problem reading
*/
uint8_t DHT11::readByte(const int pin,
const int timeoutForStartToTransmitData_us,
const int timeoutForData_us,
const int bitZeroLength_us) {
uint8_t data = 0;
for (int i = 7; i >= 0; i--) {
if (busyWait(pin, HIGH, timeoutForStartToTransmitData_us) < timeoutForStartToTransmitData_us) { // wait for RAISING
int bitLength = busyWait(pin, LOW, timeoutForData_us) ; // wait for FALLING
if (bitLength > timeoutForData_us) {
return 0xFF;
}
if (bitLength > bitZeroLength_us) { // 1 bit value, toggle bit
data |= BIT_MASK[i];
}
}
}
return data;
}
檢查解決方案
- 創(chuàng)建 DHT11 對(duì)象
- 通話設(shè)置
- 需要新講座時(shí)調(diào)用 readSensor。注意:間隔采樣周期應(yīng)不少于 1 秒。
#include "DHT11.h"
DHT11 dht11; // DHT11 sensor
void setup()
{
Serial.begin(115200); // for debugging
Serial.println();
Serial.println("Status\tHumidity (%)\tTemperature (C)");
// Initialize DHT11 sensor
dht11.setup(D1); // sensor in D1
}
void loop()
{
DHT11::Dht11_data_type sensorData = dht11.readSensor();
logData(&sensorData);
// NOTE: Sampling periods at intervals should be no less than 1 second
delay(2000); // Wait 2000 milliseconds for the next reading
}
/*
* Logs sensor data to serial log
*
* @params void
* @retun void
*/
void logData(DHT11::Dht11_data_type *sensorData){
Serial.print(sensorData->status);/* status of communication */
Serial.print("\t");
Serial.print(sensorData->humidity, 0);
Serial.print("\t\t");
Serial.println(sensorData->temperature, 2);
}
通過串口記錄數(shù)據(jù)。
向 ThinkSpeak 發(fā)送數(shù)據(jù)
首先注冊(cè):
使用兩個(gè)字段創(chuàng)建通道:
- 濕度
- 溫度
在文件 secrets.h 中填寫您的秘密數(shù)據(jù)
// Use this file to store all of the private credentials
// and connection details
#define SECRET_SSID "MySSID" // replace MySSID with your WiFi network name
#define SECRET_PASS "MyPassword" // replace MyPassword with your WiFi password
#define SECRET_CH_ID 0000000 // replace 0000000 with your channel number
#define SECRET_WRITE_APIKEY "XYZ" // replace XYZ with your channel write API Key
最終代碼
主要代碼:
void setup()
{
Serial.begin(115200); // for debugging
// Begin ThinkSpeak connection
WiFi.mode(WIFI_STA);
ThingSpeak.begin(client); // Initialize ThingSpeak
Serial.println();
Serial.println("Status\tHumidity (%)\tTemperature (C)");
// Initialize DHT11 sensor
dht11.setup(D1); // sensor in D1
}
void loop()
{
checkWifiConnection();
DHT11::Dht11_data_type sensorData = dht11.readSensor();
logData(&sensorData);
if (DHT11::ERROR_NONE == sensorData.error) {
sendDataToThingSpeak(&sensorData);
}
delay(120000); // Wait 120 seconds to update the channel again
}
檢查WIFI連接
/*
* Check if wifi is connected
* if not reconnect
*
* @params void
* @retun void
*/
void checkWifiConnection(void) {
// Connect or reconnect to WiFi
if (WiFi.status() != WL_CONNECTED) {
Serial.print("Attempting to connect to SSID: ");
Serial.println(SECRET_SSID);
while (WiFi.status() != WL_CONNECTED) {
WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network.
Serial.print(".");
int counter = 0;
// wait for connection established
while ((WiFi.status() != WL_CONNECTED ) && (counter < 10)) {
delay(1000);
counter++;
}
}
Serial.println("\nConnected.");
}
}
向 ThingSpeak 發(fā)送數(shù)據(jù):
/*
* Sends sensor data to Thing speak
*
* @params sensor data record reference
* @retun void
*/
void sendDataToThingSpeak(DHT11::Dht11_data_type *sensorData) {
// Write to ThingSpeak. There are up to 8 fields in a channel, allowing you to store up to 8 different
// pieces of information in a channel. Here, we write to field 1.
ThingSpeak.setField(1, sensorData->temperature);
ThingSpeak.setField(2, sensorData->humidity);
int x = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);
if (x == 200) {
Serial.println("Temp Channel update successful.");
}
else {
Serial.println("Problem updating temp channel. HTTP error code " + String(x));
}
}
日志記錄
?
- 如何使用Blynk從DHT11讀取溫度和濕度
- 用Arduino讀取DHT22(或DHT11)
- DHT11數(shù)字濕溫度傳感器的原理和應(yīng)用 3次下載
- 數(shù)字溫濕度傳感器DHT11產(chǎn)品手冊(cè) 77次下載
- 使用Arduino IDE在NodeMCU上使用DHT11溫度和濕度傳感器
- DHT11溫濕度傳感器(詳細(xì))
- 溫濕度傳感器DHT11資料匯總 35次下載
- DHT11數(shù)字濕溫度傳感器的原理和應(yīng)用范例 13次下載
- Arduino的實(shí)驗(yàn)例程之溫濕度傳感器DHT11實(shí)驗(yàn) 30次下載
- DHT11單片機(jī)溫度濕度傳感器原理圖和C語言免費(fèi)下載 136次下載
- DHT11的庫文件免費(fèi)下載 313次下載
- DHT11數(shù)字濕溫度傳感器的數(shù)據(jù)和原理及應(yīng)用說明及源代碼免費(fèi)下載 16次下載
- DHT11溫濕度傳感器的庫文件 9次下載
- DHT11數(shù)據(jù)手冊(cè)溫濕度傳感器的庫文件免費(fèi)下載 24次下載
- 數(shù)字溫濕度傳感器 DHT11 4次下載
- DHT11數(shù)字溫濕度傳感器主要參數(shù) 1.4w次閱讀
- 基于STM32的DHT11溫濕度數(shù)據(jù)采集仿真設(shè)計(jì) 1643次閱讀
- 基于STM32大棚DHT11溫濕度監(jiān)測(cè)protues仿真設(shè)計(jì) 1658次閱讀
- 【Renesas RA6M4開發(fā)板之DHT11溫濕度讀取】 1495次閱讀
- FPGA在OLED上顯示DHT11數(shù)據(jù) 1607次閱讀
- 溫濕度傳感器采集報(bào)警系統(tǒng)設(shè)計(jì)方案 1714次閱讀
- dfrobotDHT11溫濕度傳感器簡介 5073次閱讀
- 如何才能在樹莓派上讀取DHT11的溫濕度詳細(xì)方法實(shí)例說明 1.2w次閱讀
- STM32F103試用體驗(yàn):LCD顯示與DHT11測(cè)量實(shí)驗(yàn) 1.1w次閱讀
- dht11溫濕度傳感器中文資料(dht11工作原理特性參數(shù)及應(yīng)用電路) 39.2w次閱讀
- DHT11的使用注意事項(xiàng) 6.1w次閱讀
- dht11和ds18b20區(qū)別_dht11與ds18b20哪個(gè)測(cè)溫度更精確 8.6w次閱讀
- 溫濕度傳感器DHT11驅(qū)動(dòng)程序 5.3w次閱讀
- dht11的工作原理_dht11接線圖 23.5w次閱讀
- 基于arduino的dht11溫濕度傳感器的使用 4.4w次閱讀
下載排行
本周
- 1山景DSP芯片AP8248A2數(shù)據(jù)手冊(cè)
- 1.06 MB | 532次下載 | 免費(fèi)
- 2RK3399完整板原理圖(支持平板,盒子VR)
- 3.28 MB | 339次下載 | 免費(fèi)
- 3TC358743XBG評(píng)估板參考手冊(cè)
- 1.36 MB | 330次下載 | 免費(fèi)
- 4DFM軟件使用教程
- 0.84 MB | 295次下載 | 免費(fèi)
- 5元宇宙深度解析—未來的未來-風(fēng)口還是泡沫
- 6.40 MB | 227次下載 | 免費(fèi)
- 6迪文DGUS開發(fā)指南
- 31.67 MB | 194次下載 | 免費(fèi)
- 7元宇宙底層硬件系列報(bào)告
- 13.42 MB | 182次下載 | 免費(fèi)
- 8FP5207XR-G1中文應(yīng)用手冊(cè)
- 1.09 MB | 178次下載 | 免費(fèi)
本月
- 1OrCAD10.5下載OrCAD10.5中文版軟件
- 0.00 MB | 234315次下載 | 免費(fèi)
- 2555集成電路應(yīng)用800例(新編版)
- 0.00 MB | 33566次下載 | 免費(fèi)
- 3接口電路圖大全
- 未知 | 30323次下載 | 免費(fèi)
- 4開關(guān)電源設(shè)計(jì)實(shí)例指南
- 未知 | 21549次下載 | 免費(fèi)
- 5電氣工程師手冊(cè)免費(fèi)下載(新編第二版pdf電子書)
- 0.00 MB | 15349次下載 | 免費(fèi)
- 6數(shù)字電路基礎(chǔ)pdf(下載)
- 未知 | 13750次下載 | 免費(fèi)
- 7電子制作實(shí)例集錦 下載
- 未知 | 8113次下載 | 免費(fèi)
- 8《LED驅(qū)動(dòng)電路設(shè)計(jì)》 溫德爾著
- 0.00 MB | 6656次下載 | 免費(fèi)
總榜
- 1matlab軟件下載入口
- 未知 | 935054次下載 | 免費(fèi)
- 2protel99se軟件下載(可英文版轉(zhuǎn)中文版)
- 78.1 MB | 537798次下載 | 免費(fèi)
- 3MATLAB 7.1 下載 (含軟件介紹)
- 未知 | 420027次下載 | 免費(fèi)
- 4OrCAD10.5下載OrCAD10.5中文版軟件
- 0.00 MB | 234315次下載 | 免費(fèi)
- 5Altium DXP2002下載入口
- 未知 | 233046次下載 | 免費(fèi)
- 6電路仿真軟件multisim 10.0免費(fèi)下載
- 340992 | 191187次下載 | 免費(fèi)
- 7十天學(xué)會(huì)AVR單片機(jī)與C語言視頻教程 下載
- 158M | 183279次下載 | 免費(fèi)
- 8proe5.0野火版下載(中文版免費(fèi)下載)
- 未知 | 138040次下載 | 免費(fèi)
評(píng)論
查看更多