RM新时代网站-首页

電子發(fā)燒友App

硬聲App

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示
創(chuàng)作
電子發(fā)燒友網(wǎng)>電子資料下載>電子資料>用Arduino庫來讀取DHT11濕度和溫度傳感器數(shù)據(jù)

用Arduino庫來讀取DHT11濕度和溫度傳感器數(shù)據(jù)

2022-11-22 | zip | 0.28 MB | 次下載 | 免費(fèi)

資料介紹

描述

介紹

在這個(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)、抗干擾能力和成本效益。

pYYBAGN6Xe-AY0PMAADaEY3sW2E139.png
?
poYBAGN6XfKAG56UAAHYq6B4Uh0186.png
?

PINOUT 和 MCU 連接

pYYBAGN6XfWAaOFwAADEYjqPc5g887.png
帶 10KOhm 上拉電阻和 DHT11 引腳的 DHT11 分線模塊
?

MCU 到 DHT11 連接

poYBAGN6XfiAOLT-AAEAJt1Mu5E855.png
?

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

poYBAGN6Xf6AIGKwAAsvUTfh1rg013.jpg
NodeMCU ESP-8266 Amica 連接到 DHT11 分支
?

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

pYYBAGN6XgGAU2JYAAChtgNoAhs954.png
?

GPIO 0-15 都有一個(gè)內(nèi)置的上拉電阻器,如果直接使用 DHT11 而不是分線器,我們可以使用它。

有關(guān)如何在我的NodeMCU Amica V2 路試中設(shè)置此模塊的更多信息

poYBAGN6XgOAFgo7AACDUMA5yOM453.png
?

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

poYBAGN6XgaAPJUaAAIa8AZ27fY398.png
使用 PulseView 解碼通信
?
pYYBAGN6XgiAEvAJAADrvbClMQc057.png
來自 DHT11 數(shù)據(jù)表
?
pYYBAGN6XguAM80BAADF7foSwnw843.png
來自 DHT11 數(shù)據(jù)表
?

PulseView 和邏輯分析儀

PulseView 是 libsigrok 和 libsigrok 解碼庫的圖形前端,允許訪問各種設(shè)備和協(xié)議解碼器,讓您記錄、分析、處理和導(dǎo)出模擬和邏輯數(shù)據(jù)。

https://sigrok.org/

邏輯分析儀

我們正在使用 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。

poYBAGN6XhSAVXjXABftNs9Y3iU406.jpg
?

脈沖視圖

安裝后,您會(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í)的位流。

poYBAGN6XhaAI7RpAACYHxXBDTE905.png
?

DHT11單線通訊協(xié)議解碼器

Pulseview 帶有一個(gè) DHT11 協(xié)議解碼器。讓我們使用它。

添加解碼器并將其關(guān)聯(lián)到串行數(shù)據(jù)線。D1 在我們的例子中。

pYYBAGN6XhmAZiwUAADHxlqg-Hc682.png
?

該解碼器處理傲松 AM230x/DHTxx/RHTxx 系列數(shù)字濕度和溫度傳感器使用的專有單線通信協(xié)議。

采樣率:建議使用至少200 kHz的采樣率來正確檢測(cè)協(xié)議的所有元素。

選項(xiàng):

AM230x 和 DHTxx/RHTxx 數(shù)字濕度和溫度傳感器使用相同的單線協(xié)議,測(cè)量值的編碼不同。因此,必須使用選項(xiàng)“設(shè)備”來正確解碼各個(gè)傳感器的通信。dht11 設(shè)備類型”用于我們的目的。

pYYBAGN6XhyASLU0AAJlD3nKmwc187.png
?

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

poYBAGN6XgaAPJUaAAIa8AZ27fY398.png
?

相對(duì)濕度 %

8 位積分 RH 數(shù)據(jù) + 8 位十進(jìn)制 RH 數(shù)據(jù)

poYBAGN6XiGAMEpUAAErcgYIds0314.png
?

溫度

8位整數(shù)T數(shù)據(jù)+8位十進(jìn)制T數(shù)據(jù)

pYYBAGN6XiSAaOGUAAHU828aLFQ992.png
?

校驗(yàn)和

8 位積分 RH 數(shù)據(jù) + 8 位十進(jìn)制 RH 數(shù)據(jù) + 8 位積分 T 數(shù)據(jù) + 8 位十進(jìn)制 T 數(shù)據(jù)

poYBAGN6XieAfB72AAH2LcZd_Ew578.png
?

使用 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)備。

pYYBAGN6XimAUP-OAADFASMgtZE819.png
?

忙等待同步

然后我們將使用忙等待同步來檢測(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ù)。

poYBAGN6XiyAYYq1AACzSKkDDmg581.png
?

向 ThinkSpeak 發(fā)送數(shù)據(jù)

首先注冊(cè):

https://thingspeak.com/

使用兩個(gè)字段創(chuàng)建通道:

  • 濕度
  • 溫度
pYYBAGN6Xi-AWRZkAALWmYGxlvQ301.png
?

在文件 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
poYBAGN6XjOABYRhAAN5d-_T5A8793.png
?

最終代碼

主要代碼:

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));
  }
}

日志記錄

pYYBAGN6XjWAERYxAAGKoJzQql8676.png
?
poYBAGN6XjiAcOOhAAK4o1Da6ho776.png
?

?


下載該資料的人也在下載 下載該資料的人還在閱讀
更多 >

評(píng)論

查看更多

下載排行

本周

  1. 1山景DSP芯片AP8248A2數(shù)據(jù)手冊(cè)
  2. 1.06 MB  |  532次下載  |  免費(fèi)
  3. 2RK3399完整板原理圖(支持平板,盒子VR)
  4. 3.28 MB  |  339次下載  |  免費(fèi)
  5. 3TC358743XBG評(píng)估板參考手冊(cè)
  6. 1.36 MB  |  330次下載  |  免費(fèi)
  7. 4DFM軟件使用教程
  8. 0.84 MB  |  295次下載  |  免費(fèi)
  9. 5元宇宙深度解析—未來的未來-風(fēng)口還是泡沫
  10. 6.40 MB  |  227次下載  |  免費(fèi)
  11. 6迪文DGUS開發(fā)指南
  12. 31.67 MB  |  194次下載  |  免費(fèi)
  13. 7元宇宙底層硬件系列報(bào)告
  14. 13.42 MB  |  182次下載  |  免費(fèi)
  15. 8FP5207XR-G1中文應(yīng)用手冊(cè)
  16. 1.09 MB  |  178次下載  |  免費(fèi)

本月

  1. 1OrCAD10.5下載OrCAD10.5中文版軟件
  2. 0.00 MB  |  234315次下載  |  免費(fèi)
  3. 2555集成電路應(yīng)用800例(新編版)
  4. 0.00 MB  |  33566次下載  |  免費(fèi)
  5. 3接口電路圖大全
  6. 未知  |  30323次下載  |  免費(fèi)
  7. 4開關(guān)電源設(shè)計(jì)實(shí)例指南
  8. 未知  |  21549次下載  |  免費(fèi)
  9. 5電氣工程師手冊(cè)免費(fèi)下載(新編第二版pdf電子書)
  10. 0.00 MB  |  15349次下載  |  免費(fèi)
  11. 6數(shù)字電路基礎(chǔ)pdf(下載)
  12. 未知  |  13750次下載  |  免費(fèi)
  13. 7電子制作實(shí)例集錦 下載
  14. 未知  |  8113次下載  |  免費(fèi)
  15. 8《LED驅(qū)動(dòng)電路設(shè)計(jì)》 溫德爾著
  16. 0.00 MB  |  6656次下載  |  免費(fèi)

總榜

  1. 1matlab軟件下載入口
  2. 未知  |  935054次下載  |  免費(fèi)
  3. 2protel99se軟件下載(可英文版轉(zhuǎn)中文版)
  4. 78.1 MB  |  537798次下載  |  免費(fèi)
  5. 3MATLAB 7.1 下載 (含軟件介紹)
  6. 未知  |  420027次下載  |  免費(fèi)
  7. 4OrCAD10.5下載OrCAD10.5中文版軟件
  8. 0.00 MB  |  234315次下載  |  免費(fèi)
  9. 5Altium DXP2002下載入口
  10. 未知  |  233046次下載  |  免費(fèi)
  11. 6電路仿真軟件multisim 10.0免費(fèi)下載
  12. 340992  |  191187次下載  |  免費(fèi)
  13. 7十天學(xué)會(huì)AVR單片機(jī)與C語言視頻教程 下載
  14. 158M  |  183279次下載  |  免費(fèi)
  15. 8proe5.0野火版下載(中文版免費(fèi)下載)
  16. 未知  |  138040次下載  |  免費(fèi)
RM新时代网站-首页