16文字2行のLCDディスプレイ。
これに、以下の情報を1秒ごとに表示します。
・現在の日付、時刻
・温度、湿度
・CPU温度と使用率、メモリの使用量と総量
温度・湿度計とディスプレイのGPIOへの接続は以前の記事を参考にしてください。
1. Pythonプログラミング
以下のコードで実現できます。
CPU温度の取得方法は2種類用意しています使用するのは1種類)
メモリの情報は、「psutil」を使用しています。標準ライブラリです。
「psutil」はいろいろなハードウェア情報を取得できるようですので、掘っていくと面白いかもしれません。
なお、今回は別ファイルに保存していたスクリプトもこちらへ移動しています。
# -*- coding: utf-8 -*- # 日本語コメントをエラーとしないように、UTF-8で保存 # 使用するライブラリのインポート from time import sleep import smbus import datetime import subprocess import re import psutil # 定数の定義 # 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への書き込み2 """ 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) # -*- coding: utf-8 -*- # 日本語コメントをエラーとしないように、UTF-8で保存 # 使用するライブラリのインポート import smbus from time import sleep def 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 def cpu_temp(): """ CPU温度の取得 """ f = open("/sys/class/thermal/thermal_zone0/temp","r") cpu_temp = 0 for t in f: cpu_temp = t[:2] # 小数点以下2桁まで表示する場合 # cpu_temp = t[:2]+"."+t[2:3] f.close() return cpu_temp def cpu_temp_command(): """ CPU温度の取得(コマンドで取得) """ proc = subprocess.run(["vcgencmd", "measure_temp"], stdout = subprocess.PIPE, stderr = subprocess.PIPE) cpu_temp = re.split("[=\']", proc.stdout.decode("utf8"))[1] return float(cpu_temp) def cpu_percent(): """ CPU使用率の取得 """ cpu_percent = psutil.cpu_percent(interval=1) return round(cpu_percent) def memory_info(): """ メモリ情報(使用量[MB]、総量[MB])の取得 """ mem = psutil.virtual_memory() mem_used = round(mem.used / 1024 / 1024) mem_total = round(mem.total / 1024 / 1024) return (mem_used, mem_total) # I2Cの取得 bus = smbus.SMBus(1) try: # LCD初期化 init_lcd() # 無限ループ、各情報を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): # 「温度と湿度」を表示 templature , humidity = 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): # 「CPU温度」「CPU使用率」と「メモリ情報」を表示 mem_info = memory_info() lcd_string(f'cpu : {cpu_temp()}\337C {cpu_percent()}%', LCD_LINE_1) lcd_string(f'mem : {mem_info[0]}/{mem_info[1]}MB', LCD_LINE_2) dispMode = 0 finally: lcd_byte(0x01, LCD_CMD)