STM32 + DHT11

DHT11温湿度センサーを手に入れました。 20〜90%の範囲の湿度と0〜50°Cの温度を測定します。 湿度測定の誤差は5%、温度は2°Cです。 キャプチャ時間1秒 通信インターフェース単線( datashit )。 このような控えめなパラメーターは、センサーの範囲を家庭内の部屋の条件にのみ制限します。

画像

HCH1000 + DS18B20とDHT11のデバイスの測定値を比較したかった。



私は、DHT11とDS18B20が同じバスに乗っていると誤って結論付けました。 彼らは非常に異なるプロトコルを持っていることが判明しました。 悪い経験の後、急いでデバイスを組み立てて真実を確立しました。

画像

STM32用の完成したDHT11ライブラリが見つかりませんでした。 Arduinoについてはこちら 。 単線通信プロトコルは1線とは関係ありません。 0と1の差は、パルス幅の差から得られます。

画像

まず、バスレベルを約20ミリ秒間低レベルに保ち、その後解放します.20ミリ秒後、センサーはそれ自体を0にクランプし、80μsを保持し、その後80μsを解放し(プレゼンス信号を生成します)、その後に40ビットのデータが続き、同じスタートでバスを保持します50μsおよびビット。 ビット0は約28μs、ビット1は70μsです。 さて、別れの際に、センサーはバスをクランプして解放します。 40データビットは5バイトで、最初の2つは湿度で、次の2つは温度とパリティバイトです。 パリティバイトは、前のバイトの合計です。 私が理解するように、1バイト目と3バイト目の送信値2と4は10分の1に予約されています。

パルスの持続時間を読み取り、アレイに書き込む最も簡単な方法。 次に、この配列をバイト配列に変換すると、dht11.cライブラリが誕生しました。

uint16_t read_cycle(uint16_t cur_tics, uint8_t neg_tic){ uint16_t cnt_tics; if (cur_tics < MAX_TICS) cnt_tics = 0; if (neg_tic) { while (!GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_3)&&(cnt_tics<MAX_TICS)){ cnt_tics++; } } else { while (GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_3)&&(cnt_tics<MAX_TICS)){ cnt_tics++; } } return cnt_tics; } uint8_t read_DHT11(uint8_t *buf){ uint16_t dt[42]; uint16_t cnt; uint8_t i, check_sum; //reset DHT11 Delay(500); GPIO_LOW(GPIOA,GPIO_Pin_2); Delay(20); GPIO_HIGH(GPIOA,GPIO_Pin_2); //start reading cnt = 0; for(i=0;i<83 && cnt<MAX_TICS;i++){ if (i & 1){ cnt = read_cycle(cnt, 1); } else { cnt = read_cycle(cnt, 0); dt[i/2]= cnt; } } //release line GPIO_HIGH(GPIOA,GPIO_Pin_2); if (cnt>=MAX_TICS) return DHT11_NO_CONN; //convert data for(i=2;i<42;i++){ (*buf) <<= 1; if (dt[i]>20) (*buf)++; if (!((i-1)%8) && (i>2)) buf++; } //calculate checksum buf -= 5; check_sum = 0; for(i=0;i<4;i++){ check_sum += *buf; buf++; } if (*buf != check_sum) return DHT11_CS_ERROR; return DHT11_OK; }
      
      





dht11.cライブラリを含むプロジェクトはこちらです。



All Articles