2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Nordic nRF52840 で温度湿度センサ DHT11 を使う

Last updated at Posted at 2020-05-05

環境

  • 開発ボード アオノドン2019(Raytac MDBT50Q / Nordic nRF52840 搭載)
  • IDE Segger Enbedid Studio
  • 開発PC Ubuntu 18.04LTS
  • nRF5_SDK_16.0.0_98a08e2

接続

アオノドン2019は、ウラ面に Grove 端子がある。これを使って DHT11 を接続した。
Grove 端子の白が DHT11 のデータ線となる。
アオノドン2019では白ケーブルが GPIO7 に割り当てられている。
アオノドンや Grove 端子を使わなくても GPIO7 にデータ線を接続すれば同じプログラムでデータが取得できる。

DHT11 データ転送手順

訳のわからないデータシートを読んでわかったこと。

1ワイヤの独自プロトコル。DHT11へ送る論理コマンドは無し。ホストからのデータ線の引き下げ→引き上げをトリガとしてセンサからデータが発信される。

センサからのデータは 40bit。

データ形式

  • 8bit:湿度整数データ
  • 8bit:湿度小数点以下第一位データ(常に0)
  • 8bit:温度整数データ
  • 8bit:温度整数データ
  • 8bit:bit0〜7 温度小数点以下第一位データ(0〜9) bit8で零下温度を表す
  • 8bit:チェックビット。

チェックビットデータの定義

8bit湿度整数データ+8bit湿度小数点以下第一位データ+8bit温度整数データ+8bit(零下フラグおよび温度度小数点以下第一位データ)

転送開始シーケンス

  • Startシグナル ホストより SDAラインの引き下げ 18ms 〜 30ms → SDAラインの引き上げ
  • レスポンスシグナル センサよりSDAライン 83μs 引き下げ、 87μs引き上げ
  • データ 40bit がセンサより送信

転送ビットプロトコル

ビットデータ40ビットのうちの任意の1ビットは以下のように構成される

bit sequence
0 50μs Lo + 26〜28μs Hi
1 50μs Lo + 70μs Hi

コード

(Public Domain)



# include <stdbool.h>
# include <stdint.h>
# include <stdio.h>
# include "nrf.h"
# include "nrf_delay.h"
# include "app_error.h"
# include "bsp.h"

# include "nrf_log.h"
# include "nrf_log_ctrl.h"
# include "nrf_log_default_backends.h"


# define DHT11_PIN 7

int DHT11ReadByte(void)
{
  int ByteData=0,i;
  unsigned long int counter=0;
  for(i=0;i<8;i++)
  {
    ByteData = ByteData * 2;
    counter = 0;
    while(0==(nrf_gpio_pin_read(DHT11_PIN))) // may be 50us
    {
      counter++;
      nrf_delay_us(1);
      if ( 200 < counter  ){
        NRF_LOG_INFO("error1\n");
        return -1;
      }
    }
    counter = 0;
    while(1==(nrf_gpio_pin_read(DHT11_PIN)))
    {
      counter++;
      nrf_delay_us(1);
      if ( 200 < counter  ){
        NRF_LOG_INFO("error2\n");
        return -1;
      }
    }
    if(counter<30)  // 40... error
    {
            // 26-28us : Bit data "0"
    } else {
      ByteData = ByteData +1; // 70us : Bit data "1"
    }          	
  }
  return ByteData;
}

void DHT11ReadData()
{	
  int counter,err,humiInt,humiDec,tempInt,tempDec,checkSum,decimal_value1,decimal_value2,decimal_value3;
  nrf_gpio_pin_set(DHT11_PIN);
  nrf_delay_ms(250);
  nrf_gpio_cfg_output(DHT11_PIN);
  nrf_gpio_pin_clear(DHT11_PIN);   // Send Start Signal
  nrf_delay_ms(20);   
  nrf_gpio_pin_set(DHT11_PIN);
  nrf_delay_us(40);                // Send Start Signal end
  nrf_gpio_cfg_input(DHT11_PIN, NRF_GPIO_PIN_PULLUP);
  nrf_delay_us(1);
  counter=0;
  while(nrf_gpio_pin_read(DHT11_PIN)==0) // Receive LOW answer ( 83us)
  {
    nrf_delay_us(1);
    counter++;
    if ( 200 < counter ){
        NRF_LOG_INFO("got wrong start1\n");
        return;
    }
  }
  counter=0;
  while(nrf_gpio_pin_read(DHT11_PIN)==1) // Recieve High answer ( 87us)
  {
    nrf_delay_us(1);
    counter++;
    if ( 200 < counter ){
      NRF_LOG_INFO("got wrong start2\n");
      return;
    }
  }
  humiInt = DHT11ReadByte();
  humiDec = DHT11ReadByte();
  tempInt = DHT11ReadByte();
  tempDec = DHT11ReadByte();
  checkSum = DHT11ReadByte();

  if (((humiInt + humiDec + tempInt + tempDec) & 0xff) != checkSum) 
  {
     NRF_LOG_INFO("got wrong values\n");
     return -1;
  } else {
    if ( 127 < tempDec ){
      tempInt=0-tempInt;
      tempDec=tempDec-128;
    }
    NRF_LOG_INFO("TEMP: %d.%d  HUMI: %d.%d",tempInt,tempDec,humiInt,humiDec);
  }
}


int main(void)
{
    APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
    NRF_LOG_DEFAULT_BACKENDS_INIT();
    NRF_LOG_INFO("Temp/Humi sensor DHT11 example started.");
    nrf_gpio_cfg_input(DHT11_PIN, NRF_GPIO_PIN_PULLUP);
    SEGGER_RTT_WriteString(0, "DHT11 init complete\n");
    while (true)
    {
        DHT11ReadData();
        nrf_delay_ms(3000);
        NRF_LOG_FLUSH();
    }
}


ビルド

sdk_config.h は examples/peripheral/temperature を使います。

このフォルダーをコピーして、DHT11という名前にしました。

「Nordic SDK で printf と NRF_LOG」
https://qiita.com/nanbuwks/items/3673691779b2e6eca89a
に記したように、ログ出力を適宜直します。

main.cの内容を上記のように直し、SES上でDebug and Buildすると
デバッグターミナルに温度湿度が3秒おきに表示されます。
image.png

付記 nRF52840との適合性

センサの電源電圧範囲が、3.3V - 5.5V。 Nordic nRFの特性を活かした電池駆動などの場合には、 3.3V を供給するのはあまり良い選択とは言えない。2V台でも動作するセンサが望ましい。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?