Raspberry Pi 電子工作 04:LCDディスプレイ(I2C接続)

前回に引き続き、Raspberry Piに「I2C」規格に対応したLCDディスプレイを接続、制御します。

I2C規格対応のデバイスであれば、同時に接続できます。

ですので、前回の温度・湿度センサーと、今回のLCDディスプレイを同時に接続することができます。

 

 

1. LCDディスプレイ

セットに付属するLCDディスプレイはこれにあたると思います。

1行あたり16文字、2行表示できるものを使用しています。

[商品価格に関しましては、リンクが作成された時点と現時点で情報が変更されている場合がございます。]

Adeept Raspberry Pi用 LCD1602 スタータキット
価格:2294円(税込、送料別) (2021/1/11時点)

楽天で購入

 


 

 

2. 配線

前回の温度、湿度センサーと配線は同じです。

手元にあったものは「vcc」「gnd」が温度、湿度センサーと並びが逆でしたので注意。

 

3. I2C接続の確認

配線ができたら、以下のコマンドで接続、アドレスの確認を行います。

i2cdetect -y 1

手元にあったものは、「27」となっていました。

 

4. Pythonソースコード

今回は、1行目に年月日、2行目に時分秒を1秒間隔で表示するプログラムです。

ただの時計です。

 

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

# 使用するライブラリのインポート
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秒間隔で表示
    while True:
        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)
        sleep(1)
finally:
    lcd_byte(0x01, LCD_CMD)