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

LCDディスプレイに温度、湿度、日付と時間を表示することはできました。

何か、ほかに表示するものはないかと考え、「CPU温度」も表示してみました。

性能が上がった分、CPU温度も上がりがちなRaspberry Pi 4を使用していますが、ファンがちゃんと回るか、そのファンに効果があるかを確認することもできます。

 

 

1. 配線

  前回までのLCDディスプレイの配線では、ディスプレイが暗く、読みづらかったんです。

  気にはなっていたんですが、こんなもんだろうと思っていましたが、どうやら手元にあるLCDディスプレイでは電圧が足りなかったようです。

f:id:kobatom5278:20210119232330p:plain

07_温度湿度センサーとLCDディスプレイ

2. Pythonプログラミング

  前回のものに、CPU温度を計測するコマンド呼び出しを追加しました。

  前回の「Temperature.py」も使用します。

  コマンド呼び出しはちょっとコストがかかる傾向なのですが、これはどうでしょうか。

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

 

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

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

# 定数の定義
# 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()
    # 無限ループ、「年月日と時分秒」、「温度と湿度」、「CPU温度」を1秒間隔で表示
    dispMode = 0
    while True:
        if (dispMode == 0):
            sleep(1)
            # 「年月日と時分秒」を表示
            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)
            dispMode = 1
        elif (dispMode == 1):
            # 「温度と湿度」を表示
            # 取得時にディレイをかけているので、1秒後に表示される
            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)
            dispMode = 2
        elif (dispMode == 2):
            sleep(1)
            # 現在のcpu温度の取得
            proc = subprocess.run(["vcgencmd", "measure_temp"], stdout = subprocess.PIPE, stderr = subprocess.PIPE)
            proc_tmp = re.split("[=\']", proc.stdout.decode("utf8"))[1]
            lcd_string(f'cpu : {str(proc_tmp)[:4]}\337C', LCD_LINE_1)
            lcd_string(f'    :           ', LCD_LINE_2)
            dispMode = 0
finally:
    lcd_byte(0x01, LCD_CMD)