SBC LinuxのPythonで1602LCDを使う

いわゆる16文字×2行のキャラクタ用LCDをSBC Linux上のPythonで動かす方法のメモを残しておく。

1602LCDのモノ自体は随分前にArduinoやMicroPythonで動かして当ブログ記事にしたのと同一。

スポンサーリンク

使ったSBCのハードウエアとLinux

SBCのハードはLicheePiZeroを使った。

写真

LinuxはBuildrootで作成した物を利用。Buildrootのバージョンは2022.02で、Mainlineのカーネルを選択した。

Buildrootのパッケージとしては以下の2つを入れさえすれば特殊な物は不要かと思う。

  • Python3(BR2_PACKAGE_PYTHON3)
  • i2c tools(BR2_PACKAGE_I2C_TOOLS)

Armbianやラズパイの場合はi2c-toolsの他、Pythonのsmbusモジュールが必要のようだ。

sudo apt install i2c-tools
sudo apt install python-smbus

ドライバの準備

1602LCDのPythonドライバはラズパイ用としてGitHubに上がっている物を利用した。

GitHub - sterlingbeason/LCD-1602-I2C: A simple Python library for displaying text on the LCD 1602 w/ I2C. Implemented on the Raspberry Pi 3 B.
A simple Python library for displaying text on the LCD 1602 w/ I2C. Implemented on the Raspberry Pi 3 B. - GitHub - ster...

ドライバと言ってもファイルは1つでLCD.pyにまとまっており、LCD.pyをダウンロードしてカレントディレクトリかパスの通った場所に置けばOK。

i2cデバイスの検出

ハードウエアは、SBCのI2Cポート0(/dev/i2c-0)にPCF8574(I2Cアドレス0x27)が繋がり、PCF8574に1602LCDがパラレル接続されている。

i2cキャラクタデバイスのパーミッションに注意。

$ ls -l /dev/i2c-0 
crw-rw----    1 root     wheel      89,   0 Jan  1 03:27 /dev/i2c-0

i2cdetectコマンドを使ってi2cデバイスの検出。アドレス0x27に反応がある。

$ i2cdetect -y 0
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:                         -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- 27 -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- 48 -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --                         

Pythonコマンドラインから動作チェック

オブジェクトの生成

LCDオブジェクトのコンストラクタの引数は以下の通り。

説明
第1引数1 or 2I2Cバス選択。1の時/dev/i2c-0, 2の時/dev/i2c-1が使われる。
第2引数デバイスIDI2CデバイスのIDを指定する

以下のようなコードでコンストラクタを呼び出すと、/dev/i2c-0にぶら下がったデバイスID0x27の1602LCDのオブジェクトが変数lcdに作成される。

from LCD import LCD

lcd = LCD(1, 0x27)

以降、変数lcd経由でデバイスを操作出来る。

文字列の出力

messageメソッドの呼び出しで文字列を出力出来る。
第1引数に文字列、第2引数に行番号を指定する。

lcd.message("Hello World!", 1)

上記は1行目を指定しており、実行結果は以下のような出力になる。

写真

続けて2行目を指定してmessageメソッドを実行。

lcd.message("drawing 2nd line", 2)

すると以下のような出力になる。

写真

バックライトの点灯/消灯

バックライトの点灯/消灯用のメソッドが用意されておらず、以下の手順で行う。

  1. lcd.LCD_BACKLIGHT変数への値の所定値のセット(0x08で点灯、0x00で消灯)
  2. lcd.messageメソッドの呼び出し

以下のコード例のように単に消灯したいだけの時もmessageメソッドが必要。

lcd.LCD_BACKLIGHT=0
lcd.message("",1)                 

LCDクロックにしてみる

久しぶりに昔のMicroPythonの記事を見たら同じ事をしてみたくなったので、MicroPythonのプログラムをベースにプログラム作成。LicheePiZeroはRTCを持ってないので、何らかの方法で時計を合わせる必要があるのに気づいたが、とりあえずプログラムは動作した。

from LCD import LCD
from time import sleep, localtime, mktime

# The PCF8574 has a jumper selectable address: 0x20 - 0x27
DEFAULT_I2C_ADDR = 0x27

# JST(日本標準時)はUTC+9時間
UTC_OFFSET = 9

# 曜日
daysOfTheWeek = "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"

def lcdclock_main():
    lcd = LCD(1, DEFAULT_I2C_ADDR)

    lcd.message("LCD Clock\nNow Booting...", 1)
    sleep(1)

    lcd.message("", 1)
    while True:
        tm = localtime(mktime(localtime())+UTC_OFFSET*3600)

        datestr = "%4d/%02d/%02d" % (tm[0:3])
        datestr += "(" + daysOfTheWeek[tm[6]] + ")"
        lcd.message(datestr)
        lcd.message("%2d:%02d:%02d" % (tm[3:6]), 2)
        sleep(1)


if __name__ == "__main__":
    lcdclock_main()

まとめ

Linuxでキャラクタ型のLCDを使う方法をまとめてみた。
グラフィック型のディスプレイで文字列を出そうとするとフォントを準備したり色々大変なのと対照的で、非常に手軽で簡単に扱えるのが良いなと思う。

コメント