Raspberry Pi 電子工作 06:温度・湿度センサーとLCDディスプレイ(I2C接続)

以前取り上げた、温度・湿度センサーとLCDディスプレイを同時に接続します。

そのうえで、LCDディレクトリに「温度・湿度」と「年月日、時間」を交互に表示します。

合わせ技です。

 

 

1. 配線

  同時に接続するだけです。

  電源容量が少し心配だったんですが、問題なさそうです。

f:id:kobatom5278:20210112230923p:plain

06_温度湿度センサー+ディスプレイ

 

2. Pythonプログラミング

  今回は、温度と湿度を取得する処理をクラス化(別ファイル)にし、表示プログラムから呼び出してみます。

  内容は、以前のものとあまり変わりません。

 

  まず、以下のコードを「Temperature.py」というファイル名で保存します。ファイル名を間違えてはいけません。

# -*- coding: utf-8 -*-
# 日本語コメントをエラーとしないように、UTF-8で保存

# 使用するライブラリのインポート
import smbus
from time import sleep

def get_tempelature_humidity():
    """
    温度と湿度を取得する
    """

    ADR = 0x44
    # I2Cの取得
    ic2 = smbus.SMBus(1)

    # 測定頻度の設定
    ic2.write_byte_data(ADR, 0x23, 0x34)
    sleep(0.5)
    # 測定値の読出し
    ic2.write_byte_data(ADR, 0xe0, 0x0)
    sleep(0.5)

    # 6バイト取得
    d = ic2.read_i2c_block_data(ADR, 0x0, 6)

    # 0~1バイトが温度
    # 測定データ(生データ)を取得
    t = ((d[0]) << 8) | (d[1])
    # 換算する
    t = -45 + (175 * t / 65535)

    # 3~4バイトが湿度
    # 測定データ(生データ)を取得
    h = ((d[3]) << 8) | (d[4])
    # 換算する
    h = 100 * h / 65535

    # 結果を返却
    return t, h

 

  次に、「Temperature.py」と同じフォルダに以下のプログラムファイルを配置します。

  こちらのファイル名はなんでもよいです。

  実行すると、1秒間隔で「年月日と時分秒」、「温度と湿度」が表示されます。

# -*- coding: utf-8 -*-
# 日本語コメントをエラーとしないように、UTF-8で保存

# 使用するライブラリのインポート
import Temperature
from time import sleep
import smbus
import datetime

# 定数の定義
# LCDディスプレイのI2Cのアドレス
LCD_I2C_ADDR = 0x27
# LCDの1行目のアドレス
LCD_LINE_1 = 0x80
# LCDの2行目のアドレス
LCD_LINE_2 = 0xC0
# 1行あたりの文字数
LCD_WIDTH = 16
# バックライトのON/OFF(ON:0X08, OFF:0X00を指定)
LCD_BACKLIGHT = 0X08
LCD_CHR = 1
LCD_CMD = 0
ENABLE = 0b00000100
E_PULSE = 0.0005
E_DELAY = 0.0005

def init_lcd():
    """
    LCDの初期化処理
    """
    lcd_byte(0x33, LCD_CMD)
    lcd_byte(0x32, LCD_CMD)
    lcd_byte(0x06, LCD_CMD)
    lcd_byte(0x0C, LCD_CMD)
    lcd_byte(0x28, LCD_CMD)
    lcd_byte(0x01, LCD_CMD)
    sleep(E_DELAY)

def lcd_byte(bits, mode):
    """
    LCDへの書き込み
    """
    bits_high = mode | (bits & 0xF0) | LCD_BACKLIGHT
    bits_low =  mode | ((bits << 4) & 0xF0) | LCD_BACKLIGHT

    bus.write_byte(LCD_I2C_ADDR, bits_high)
    lcd_toggle_enable(bits_high)

    bus.write_byte(LCD_I2C_ADDR, bits_low)
    lcd_toggle_enable(bits_low)

def lcd_toggle_enable(bits):
    """
    LCDへの書き込みサブ
    """
    sleep(E_DELAY)
    bus.write_byte(LCD_I2C_ADDR, (bits | ENABLE))
    sleep(E_PULSE)
    bus.write_byte(LCD_I2C_ADDR, (bits & ~ENABLE))
    sleep(E_DELAY)

def lcd_string(message: str, dispLine):
    """
    LCDへの文字の表示(半角文字列のみ)
    """

    # 表示対象行の初期化
    lcd_byte(dispLine, LCD_CMD)

    # 文字列を1行あたりの文字数に調整
    message = message.ljust(LCD_WIDTH)

    # 表示処理
    for dispIndex in range(LCD_WIDTH):
        lcd_byte(ord(message[dispIndex]), LCD_CHR)

# I2Cの取得
bus = smbus.SMBus(1)

try:
    # 初期化
    init_lcd()
    # 無限ループ、「年月日と時分秒」、「温度と湿度」を1秒間隔で表示
    isTime = True
    while True:
        if isTime:
            # 「年月日と時分秒」を表示
            now = datetime.datetime.now()
            lcd_string(f'date: {now.strftime("%Y/%m/%d")}' , LCD_LINE_1)
            lcd_string(f'time: {now.strftime("%H:%M:%S")}', LCD_LINE_2)
            isTime = False
        else:
            # 「温度と湿度」を表示
            templature , humidity = Temperature.get_tempelature_humidity()
            lcd_string(f'temp: {str(templature)[:4]}\337C', LCD_LINE_1)
            lcd_string(f'hum : {str(humidity)[:4]}%', LCD_LINE_2)
            isTime = True
            # 温度・湿度情報取得時に計1秒ほどウェイトをかけているので、
            # 「年月日と時分秒」は1秒表示される。
            # ここで1秒ウェイト、「温度と湿度」を1秒する表示する。
            sleep(1)
finally:
    lcd_byte(0x01, LCD_CMD)