いわゆる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に上がっている物を利用した。
ドライバと言ってもファイルは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 2 | I2Cバス選択。1の時/dev/i2c-0, 2の時/dev/i2c-1が使われる。 |
第2引数 | デバイスID | I2Cデバイスの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)
すると以下のような出力になる。
バックライトの点灯/消灯
バックライトの点灯/消灯用のメソッドが用意されておらず、以下の手順で行う。
- lcd.LCD_BACKLIGHT変数への値の所定値のセット(0x08で点灯、0x00で消灯)
- 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を使う方法をまとめてみた。
グラフィック型のディスプレイで文字列を出そうとするとフォントを準備したり色々大変なのと対照的で、非常に手軽で簡単に扱えるのが良いなと思う。
コメント