資料介紹
描述
介紹
在這個項目中,我開發(fā)了一個 Arduino 庫來讀取 DHT11 濕度和溫度傳感器生成的數(shù)據(jù),并使用 AZDelivery ESP8266 ESP-12F NodeMCU Lua Amica V2 將其連續(xù)發(fā)送到 ThingSpeak 云服務。
有許多庫可以用來讀取 DHT11 傳感器數(shù)據(jù)。那么,為什么要重新發(fā)明輪子呢?只是為了了解事物的運作方式并可能改進它們的樂趣。
我使用邏輯分析儀和 DHT11 傳感器數(shù)據(jù)表來了解協(xié)議并為傳感器開發(fā)自己的庫。DHT11 溫度和濕度傳感器
DHT11 溫度和濕度傳感器具有溫度和濕度傳感器復合體,具有校準的數(shù)字信號輸出。采用獨有的數(shù)字信號采集技術和溫濕度傳感技術,確保高可靠性和出色的長期穩(wěn)定性。該傳感器包括一個電阻式濕度測量元件和一個NTC溫度測量元件,并連接到一個高性能8位微控制器,具有卓越的品質、快速的響應、抗干擾能力和成本效益。


PINOUT 和 MCU 連接

MCU 到 DHT11 連接

使用的分線模塊已經(jīng)有一個 10 KOhm 的上拉電阻。

DHT11 數(shù)據(jù)引腳連接到 D1 (GPIO5)

GPIO 0-15 都有一個內(nèi)置的上拉電阻器,如果直接使用 DHT11 而不是分線器,我們可以使用它。
有關如何在我的NodeMCU Amica V2 路試中設置此模塊的更多信息

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 傳感器之間的通信和同步。一個通信過程大約是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ù)傳輸正確,校驗和應該是:
8
bit integral RH data + 8
bit decimal RH data + 8
bit integral T data + 8
bit decimal T data



PulseView 和邏輯分析儀
PulseView 是 libsigrok 和 libsigrok 解碼庫的圖形前端,允許訪問各種設備和協(xié)議解碼器,讓您記錄、分析、處理和導出模擬和邏輯數(shù)據(jù)。
邏輯分析儀
我們正在使用 AZ-Delivery 的這款廉價邏輯分析儀來監(jiān)視 MCU 和 AZ Delivery NodeMCU 8266 Amica 模塊之間的通信。
邏輯分析儀有 8 個并行輸入 (0-5 V),每秒最多允許 2400 萬個測量步驟。對于數(shù)字信號,采樣速度必須比帶寬快 4 倍。這意味著帶寬是采樣率的四分之一。
- 最大數(shù)字采樣率:24 MSPS
- 最大數(shù)字帶寬:6 MHz
這足以監(jiān)視這種簡單的通信所需的 200 Khz。

脈沖視圖
安裝后,您會在開始菜單中找到一個名為 Zadig 的程序。默認情況下,Windows 識別的某些設備將安裝 PulseView 無法使用的驅動程序。Zadig 的目的是讓您更改 Windows 用于特定設備的驅動程序 - 對于大多數(shù)設備,您需要選擇 WinUSB 以將它們與 PulseView 或原始專有 Windows 驅動程序一起使用以將其與您訪問設備的任何其他軟件一起使用和。
新會話
- 打開一個新會話
- 選擇您要使用的設備:
- 點擊“運行”獲取信號數(shù)據(jù)(設置了則等待觸發(fā))
放大直到看到信號,MCU 和 DHT11 之間的通信大約需要 135 毫秒。
這是向傳感器請求數(shù)據(jù)時的位流。

DHT11單線通訊協(xié)議解碼器
Pulseview 帶有一個 DHT11 協(xié)議解碼器。讓我們使用它。
添加解碼器并將其關聯(lián)到串行數(shù)據(jù)線。D1 在我們的例子中。

該解碼器處理傲松 AM230x/DHTxx/RHTxx 系列數(shù)字濕度和溫度傳感器使用的專有單線通信協(xié)議。
采樣率:建議使用至少200 kHz的采樣率來正確檢測協(xié)議的所有元素。
選項:
AM230x 和 DHTxx/RHTxx 數(shù)字濕度和溫度傳感器使用相同的單線協(xié)議,測量值的編碼不同。因此,必須使用選項“設備”來正確解碼各個傳感器的通信。“ dht11 設備類型”用于我們的目的。

縮放以查看解碼數(shù)據(jù)

相對濕度 %
8 位積分 RH 數(shù)據(jù) + 8 位十進制 RH 數(shù)據(jù)

溫度
8位整數(shù)T數(shù)據(jù)+8位十進制T數(shù)據(jù)

校驗和
8 位積分 RH 數(shù)據(jù) + 8 位十進制 RH 數(shù)據(jù) + 8 位積分 T 數(shù)據(jù) + 8 位十進制 T 數(shù)據(jù)

使用 ESP8266 內(nèi)核為 Arduino 讀取傳感器數(shù)據(jù)
我們有幾種方法來讀取數(shù)據(jù)并處理 DHT11 使用的專有單線通信協(xié)議:
- 盲循環(huán):等待固定的時間,并假設 I/O 將在該固定延遲過去之前完成。此方法不適合我們讀取傳感器數(shù)據(jù),因為 0s 和 1s 時序不同,您可能會失去同步,但我們將使用它來啟動信號到 DHT,因為這是使 DHT11 從低電平變化的盲信號-power-consumption mode 到 running-mode。
- 忙等待同步或輪詢。檢查完成狀態(tài)的 I/O 狀態(tài)的軟件循環(huán)。這可能是我們讀取 DHT11 發(fā)送數(shù)據(jù)的第一個候選者,因為系統(tǒng)非常簡單,實時響應并不重要。
- 中斷。使用硬件導致特殊的軟件執(zhí)行。當輸入設備有新數(shù)據(jù)時,硬件將請求并中斷。軟件中斷服務將從輸入設備中讀取并保存在全局 RAM 中。為了簡單起見,我們不會使用這種方法。
開始信號 - 盲循環(huán)
Data Single-bus free 狀態(tài)為高電平。當 MCU 和 DHT11 開始通信時,MCU 程序會將 Data Single-bus 電壓電平從高電平設置為低電平,這個過程必須至少需要 18 ms 才能確保 DHT 檢測到 MCU 的信號,然后 MCU 會拉高電壓并等待 20 -40 我們 DHT 的回應。
/**
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;
}
本項目使用的 DHT11 模塊有一個 10K 的上拉電阻,所以我們不設置 INPUT_PULLUP。
DHT一旦檢測到啟動信號,就會發(fā)出一個低電平響應信號,持續(xù)80us。然后DHT程序將Data Single-bus電壓電平由低到高并保持80us,為DHT發(fā)送數(shù)據(jù)做準備。

忙等待同步
然后我們將使用忙等待同步來檢測以下脈沖沿,從 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;
}
忙于等待啟動信號響應
首先等待啟動信號響應
DHT一旦檢測到啟動信號,就會發(fā)出一個低電平響應信號,持續(xù)80us。所以我們將等待 DHT11 準備好。
/**
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;
}
讀取一個字節(jié)
如果檢測到“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 對象
- 通話設置
- 需要新講座時調(diào)用 readSensor。注意:間隔采樣周期應不少于 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ù)
首先注冊:
使用兩個字段創(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ù)字濕溫度傳感器的原理和應用 3次下載
- 數(shù)字溫濕度傳感器DHT11產(chǎn)品手冊 80次下載
- 使用Arduino IDE在NodeMCU上使用DHT11溫度和濕度傳感器
- DHT11溫濕度傳感器(詳細)
- 溫濕度傳感器DHT11資料匯總 36次下載
- DHT11數(shù)字濕溫度傳感器的原理和應用范例 13次下載
- Arduino的實驗例程之溫濕度傳感器DHT11實驗 30次下載
- DHT11單片機溫度濕度傳感器原理圖和C語言免費下載 138次下載
- DHT11的庫文件免費下載 320次下載
- DHT11數(shù)字濕溫度傳感器的數(shù)據(jù)和原理及應用說明及源代碼免費下載 16次下載
- DHT11溫濕度傳感器的庫文件 9次下載
- DHT11數(shù)據(jù)手冊溫濕度傳感器的庫文件免費下載 25次下載
- 數(shù)字溫濕度傳感器 DHT11 4次下載
- DHT11數(shù)字溫濕度傳感器主要參數(shù) 1.6w次閱讀
- 基于STM32的DHT11溫濕度數(shù)據(jù)采集仿真設計 2110次閱讀
- 基于STM32大棚DHT11溫濕度監(jiān)測protues仿真設計 2136次閱讀
- 【Renesas RA6M4開發(fā)板之DHT11溫濕度讀取】 1722次閱讀
- FPGA在OLED上顯示DHT11數(shù)據(jù) 1807次閱讀
- 溫濕度傳感器采集報警系統(tǒng)設計方案 1856次閱讀
- dfrobotDHT11溫濕度傳感器簡介 5329次閱讀
- 如何才能在樹莓派上讀取DHT11的溫濕度詳細方法實例說明 1.2w次閱讀
- STM32F103試用體驗:LCD顯示與DHT11測量實驗 1.1w次閱讀
- dht11溫濕度傳感器中文資料(dht11工作原理特性參數(shù)及應用電路) 39.3w次閱讀
- DHT11的使用注意事項 6.2w次閱讀
- dht11和ds18b20區(qū)別_dht11與ds18b20哪個測溫度更精確 8.8w次閱讀
- 溫濕度傳感器DHT11驅動程序 5.3w次閱讀
- dht11的工作原理_dht11接線圖 23.6w次閱讀
- 基于arduino的dht11溫濕度傳感器的使用 4.4w次閱讀
下載排行
本周
- 1人形機器人電機驅動和傳感報告
- 4.27 MB | 9次下載 | 免費
- 2Altium Designer元件庫
- 17.11 MB | 6次下載 | 免費
- 324V2A開關電源PCB資料分享
- 0.23 MB | 4次下載 | 1 積分
- 4GD100PIX120C6SNA規(guī)格書
- 0.98 MB | 3次下載 | 免費
- 5Multisim模擬電路仿真教程
- 1.93 MB | 1次下載 | 3 積分
- 6BK7258英文規(guī)格書
- 1.67 MB | 1次下載 | 免費
- 7RA4L1硬件手冊
- 21.89 MB | 1次下載 | 免費
- 8RA4L1_SENSOR-V1原理圖
- 754.36 KB | 1次下載 | 免費
本月
- 1晶體三極管的電流放大作用詳細說明
- 0.77 MB | 32次下載 | 2 積分
- 2雙極型三極管放大電路的三種基本組態(tài)的學習課件免費下載
- 4.03 MB | 25次下載 | 1 積分
- 3AIWA HS-J303 MKⅡ維修手冊
- 22.47 MB | 24次下載 | 10 積分
- 4九陽豆?jié){機高清原理圖
- 2.47 MB | 23次下載 | 1 積分
- 5多級放大電路的學習課件免費下載
- 1.81 MB | 21次下載 | 2 積分
- 6AIWA HS-J202/HS-J202M/HS-J800維修手冊
- 13.60 MB | 16次下載 | 10 積分
- 7東芝彩色電視機29SF6C維修說明書
- 4.86 MB | 9次下載 | 1 積分
- 8人形機器人電機驅動和傳感報告
- 4.27 MB | 9次下載 | 免費
總榜
- 1matlab軟件下載入口
- 未知 | 935127次下載 | 10 積分
- 2開源硬件-PMP21529.1-4 開關降壓/升壓雙向直流/直流轉換器 PCB layout 設計
- 1.48MB | 420063次下載 | 10 積分
- 3Altium DXP2002下載入口
- 未知 | 233089次下載 | 10 積分
- 4電路仿真軟件multisim 10.0免費下載
- 340992 | 191382次下載 | 10 積分
- 5十天學會AVR單片機與C語言視頻教程 下載
- 158M | 183338次下載 | 10 積分
- 6labview8.5下載
- 未知 | 81586次下載 | 10 積分
- 7Keil工具MDK-Arm免費下載
- 0.02 MB | 73814次下載 | 10 積分
- 8LabVIEW 8.6下載
- 未知 | 65988次下載 | 10 積分
評論