コンテンツにスキップ

温湿度センサーモジュール DHT-20

温湿度センサ モジュール DHT20: センサ一般 秋月電子通商-電子部品・ネット通販

ピン配置

Raspberry Pi & Python

pip install smbusを実行しておく。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import time

import smbus


class DHT20:
    """温湿度センサーモジュールDHT20とAHT25の制御クラス

    Raises:
        Exception: 初期化に失敗した

    Returns:
        _type_: None
    """

    def __init__(self, i2c_bus: int, address: int) -> None:
        """コンストラクタ

        Args:
            i2c_bus (int): I2Cバス番号
            address (int): I2Cデバイスのアドレス
        """
        self.__i2c = smbus.SMBus(i2c_bus)
        self.__address = address

    def initialize(self) -> None:
        time.sleep(0.1)
        self.__i2c.write_byte_data(self.__address, 0, 0x71)
        time.sleep(0.1)
        status_word = self.__i2c.read_byte_data(self.__address, 0)
        if status_word & 0x18 != 0x18:
            raise Exception("Failed to initialize")

    def get_data(self) -> None:
        # トリガ測定コマンド送信
        time.sleep(0.01)

        # アドレス0x38から3バイト分、オフセット0で書き込む
        self.__i2c.write_i2c_block_data(
            self.__address, 0x00, [0xAC, 0x33, 0x00])

        # データの読み込みを行う
        time.sleep(0.08)
        # アドレス0x38から7バイト分、オフセット0で読み込む
        data = self.__i2c.read_i2c_block_data(self.__address, 0x00, 0x07)

        # データ変換
        t = ((data[3] & 0x0F) << 16) | data[4] << 8 | data[5]
        h = (data[1] << 12 | data[2] << 4 | ((data[3] & 0xF0) >> 4))

        # 物理量変換
        return {
            "temperature": t / 2**20 * 200 - 50,
            "humidity": h / 2**20 * 100
        }

使用例は以下。

1
2
3
4
5
6
dht20 = DHT20(1, 0x38)
dht20.initialize()

while True:
    print(dht20.get_data())
    time.sleep(1)

I2C バス番号と I2C デバイスのアドレスはi2cdetectコマンドで確認する。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
$ i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:                         -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- 38 -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

Raspberry Pi Pico & CircuitPython

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import time

import board
import busio
import digitalio


class DHT20:
    ADDRESS = 0x38

    def __init__(self, pin_scl: board.Pin, pin_sda: board.Pin):
        """コンストラクタ

        Args:
            pin_scl (int): SCLピン
            pin_sda (int): SDAピン
        """
        self.__then = 0
        self.i2c = busio.I2C(pin_scl, pin_sda)

    def initialize(self):
        """初期化処理

        Raises:
            Exception: 初期化に失敗した
        """
        time.sleep(0.1)
        ret = bytearray(1)
        while not self.i2c.try_lock():
            pass
        self.i2c.writeto_then_readfrom(self.ADDRESS, bytes([0x71]), ret)
        self.i2c.unlock()
        if ret[0] & 0x18 != 0x18:
            raise Exception("Failed to initialize")

    def get_data(self) -> dict:
        """I2Cから値を取得する

        Returns:
            dict: 温度[℃]と湿度[0, 1]
        """
        while not self.i2c.try_lock():
            pass
        # トリガ測定コマンド送信
        time.sleep(0.01)

        # アドレス0x38から3バイト分、オフセット0で書き込む
        self.i2c.writeto(self.ADDRESS, bytes([0xAC, 0x33, 0x00]))

        # データの読み込み
        time.sleep(0.08)
        # アドレス0x38から7バイト分、オフセット0で読み込む
        data = bytearray(7)
        self.i2c.readfrom_into(self.ADDRESS, data)

        # データ変換
        t = ((data[3] & 0x0F) << 16) | data[4] << 8 | data[5]
        h = (data[1] << 12 | data[2] << 4 | ((data[3] & 0xF0) >> 4))

        self.i2c.unlock()

        # 物理量変換
        return {
            "temperature": t / 2**20 * 200 - 50,
            "humidity": h / 2**20
        }