Raspberry Pi 3に温湿度センサ「SHT21」を接続

Raspberry Pi 3に温湿度センサ「SHT21」を接続し、温湿度データを入力して表示します。プログラム言語はPython3でライブラリ「pigpio」を使用します。Raspberry Pi 3の設定については「pigpioによるI2CとSPIインタフェースの実装」を参考にしてください。

温湿度センサ「SHT21」の接続

温湿度センサ「SHT21」は、I2CでRaspberry Pi 3と接続します。仕様を次に示します。

  • 動作電圧:2.1V~3.6V
  • 測定範囲:-40~+125℃,0~100%RH
  • 精度:温度±0.3℃ 湿度±2%RH
  • 変換時間:温度 85ms 湿度 30ms

温湿度センサ「SHT21」は、ebayから購入しました。

温湿度センサ「SHT21」

次のebayから購入したSOT23のDIP変換基板にSHT21をはんだ付けし、ブレッドボードで使用できるようにしました(裏面のGNDの部分にはんだ付けされないように、DIP変換基板のパターンをカットしています)。

sht2101

Raspberry Pi 3と温湿度センサ「SHT21」間で、I2CのSDAとSCLのそれぞれに接続します。温湿度センサ「SHT21」のVCCにはRaspberry Piの3.3Vを入力します。接続した画像を次に示します。

Raspberry Pi 3とSHT21との接続

温湿度センサ「SHT21」のピン配置を次に示します。

温湿度センサ「SHT21」のピン配置

次のコマンドでRaspberry Pi 3との接続を確認します。

$ i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
  • 温湿度センサ「SHT21」のアドレス - 0×40

温湿度センサ「SHT21」のPythonスクリプト

Python3でライブラリ「pigpio」を使用して、温湿度センサ「SHT21」のPythonスクリプト「mSHT21.py」を作成します。SHT21のデータシートを示します。

  1. 温湿度センサ「SHT21」から温度データを取得するには「Trigger T measurement(no hold master)」コマンド「0xF3」、湿度データを取得するには「Trigger RH measurement(no hold master)」コマンド「0xF5」を使用します。温湿度センサ「SHT21」のコマンド一覧を次に示します。
  2. 温湿度センサ「SHT21」のコマンド

  3. 温湿度センサ「SHT21」からのセンサーデータにより、次の計算式に従って、温度/湿度を計算します。
  4. sht2104

    SRH:センサーからの湿度データ、ST:センサーからの温度データ、2RES:2**16

  5. 温湿度センサ「SHT21」は、通信データの信頼性を確保するため8ビットのCRCが付与されています。
    SHT21のCRC-8演算多項式: x8 + x5 + x4 +1
# -*- coding: utf-8 -*-

import pigpio

import time
import devtemperature

def _calculate_checksum(data, number_of_bytes):
    """5.7 CRC Checksum using the polynomial given in the datasheet"""
    # CRC
    POLYNOMIAL = 0x131  # //P(x)=x^8+x^5+x^4+1 = 100110001
    crc = 0
    # calculates 8-Bit checksum with given polynomial
    for byteCtr in range(number_of_bytes):
        crc ^= ((data[byteCtr]))
        for bit in range(8, 0, -1):
            if crc & 0x80:
                crc = (crc << 1) ^ POLYNOMIAL
            else:
                crc = (crc << 1)
    return crc

def _get_temperature_from_buffer(data):
    """This function reads the first two bytes of data and
    returns the temperature in C by using the following function:
    T = -46.85 + (175.72 * (ST/2^16))
    where ST is the value from the sensor
    """
    unadjusted = ((data[0]) << 8) + (data[1])
    unadjusted &= Sht21._STATUS_BITS_MASK  # zero the status bits
    unadjusted *= 175.72
    unadjusted /= 1 << 16  # divide by 2^16
    unadjusted -= 46.85
    return unadjusted
    
    
def _get_humidity_from_buffer(data):
    """This function reads the first two bytes of data and returns
    the relative humidity in percent by using the following function:
    RH = -6 + (125 * (SRH / 2 ^16))
    where SRH is the value read from the sensor
    """
    unadjusted = ((data[0]) << 8) + (data[1])
    unadjusted &= Sht21._STATUS_BITS_MASK  # zero the status bits
    unadjusted *= 125.0
    unadjusted /= 1 << 16  # divide by 2^16
    unadjusted -= 6
    return unadjusted
    

class Sht21(object):
    # control constants
    _SOFTRESET = 0xFE
    DEFAULT_ADDRESS = 0x40
    _TRIGGER_TEMPERATURE_NO_HOLD = 0xF3
    _TRIGGER_HUMIDITY_NO_HOLD = 0xF5
    _STATUS_BITS_MASK = 0xFFFC
    
    # datasheet (v4), page 9, table 7, thanks to Martin Milata
    # for suggesting the use of these better values
    # code copied from https://github.com/mmilata/growd
    _TEMPERATURE_WAIT_TIME = 0.086  # (datasheet: typ=66, max=85)
    _HUMIDITY_WAIT_TIME = 0.030     # (datasheet: typ=22, max=29)

    
    """コンストラクタ"""

    def __init__(self, pi):
        self.pi = pi
        self._device = pi.i2c_open(1, self.DEFAULT_ADDRESS)
        reg_data = [self._SOFTRESET]
        self.pi.i2c_write_device(self._device,reg_data)
        time.sleep(0.050)

        
    def read_temp(self):
        reg_data = [self._TRIGGER_TEMPERATURE_NO_HOLD]
        self.pi.i2c_write_device(self._device,reg_data)
        time.sleep(self._TEMPERATURE_WAIT_TIME)
        wc, data = self.pi.i2c_read_device(self._device,  3)
        if _calculate_checksum(data, 2) == (data[2]):
            return _get_temperature_from_buffer(data)

    def read_humidity(self):    
        """Reads the humidity from the sensor.  Not that this call blocks 
        for ~30ms to allow the sensor to return the data"""
        
        reg_data = [self._TRIGGER_HUMIDITY_NO_HOLD]
        self.pi.i2c_write_device(self._device,reg_data)
        time.sleep(self._HUMIDITY_WAIT_TIME)
        wc, data = self.pi.i2c_read_device(self._device,  3)
        if _calculate_checksum(data, 2) == (data[2]):
            return _get_humidity_from_buffer(data)

    def cancel(self):
        """
        Cancels the sensor and releases resources.
        """
        if self._device is not None:
            self.pi.i2c_close(self._device)
            self._device = None

if __name__ == "__main__":
    pi = pigpio.pi()
    if not pi.connected:
        exit(0)

    logger = 0
    temp = devtemperature.Sht21(pi)

    while True:
        temperature = temp.read_temp()
        humidity =  temp.read_humidity()
        print("temperature:{:.2f}℃ humidity:{:.2f}% ".format(temperature,humidity))
        time.sleep(2.0)

温湿度センサ「SHT21」のPythonスクリプトの実行

作成したPythonスクリプトを次のコマンドで実行します。2秒ごとに温湿度センサ「SHT21」からの温湿度データを表示します。

$ python3 mSHT21.py
temperature:20.91℃ humidity:52.24%
temperature:20.91℃ humidity:52.24%
temperature:20.91℃ humidity:52.24%
temperature:20.91℃ humidity:52.27%
temperature:20.91℃ humidity:52.24%
temperature:20.91℃ humidity:52.24%
temperature:20.92℃ humidity:52.27%
temperature:20.92℃ humidity:52.27%
temperature:20.92℃ humidity:52.27%
temperature:20.93℃ humidity:52.30%
temperature:20.93℃ humidity:52.30%
temperature:20.93℃ humidity:52.30%
temperature:20.93℃ humidity:52.30%
temperature:20.93℃ humidity:52.30%
temperature:20.94℃ humidity:52.33%
temperature:20.94℃ humidity:52.36%
temperature:20.95℃ humidity:52.36%