Python
RaspberryPi

Python から I2C 接続のディスプレイを操作する

More than 3 years have passed since last update.

概要

RaspberryPi に I2C 経由で繋いだ LCD を Python から操作する.
今回は,HD44780 に SpikenzieLabs の MPTH を付けた LCD を使用する.

準備

RaspberryPi 側で I2C を利用する準備が必要.
先ずは,/etc/modules に次の2行を追加する.

i2c-bcm2708
i2c-dev

次に,/etc/modprobe.d/raspi-blacklist.conf から次の行を削除 / コメントアウトする.

blacklist i2c-bcm2708

一旦再起動し,その後 i2c-toolspython-smbus をインストールする.

sudo apt-get install i2c-tools python-smbus

I2C バス番号とデバイスアドレスの取得

始めに,使用する LCD のバス番号とアドレスを取得する.
sudo i2cdetect 0sudo i2cdetect 1 を実行し,
エラーの出ない方がバス番号(0 か 1)であり,出力からアドレスを取得する.
例えば,出力が次のような場合,0x20 がアドレスである.

WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will probe file /dev/i2c-1.
I will probe address range 0x03-0x77.
Continue? [Y/n] y
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: 20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- — -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

実際の通信

I2C 通信には smbus ライブラリを利用する.smbus.SMBus(bus_number) にてコネクションオブジェクトを取得しwrite_i2c_block_data にてデータを送信する。このメソッドは、addrcmdvals を取る。addr はデバイスアドレスである。cmdvals は変わっていて、送信データのうち最初の 1バイトを cmd に、残りを vals に入れる。これは最低 1バイトを送る必要があるからだそうだ(参考)。

import smbus

bus = smbus.SMBus(bus_number)
s = "abcde"

bus.write_i2c_block_data(addr, ord(s[0]), ord(s[1:]))

HD44780 はなぜかコントロールシーケンスを読めないので、クリアなどは MPTH が用意しているコマンド利用する。

特殊コマンドは 0x80 に続けて呼び出す。画面クリアは 0x05 0x01 なので、

bus.write_i2c_block_data(addr, 0x80, [0x05, 0x01])

となる。

ライブラリ

これらをまとめたライブラリを作成した。他のプログラムから呼び出すことも,コマンドラインから試してみることも可能.どちらの場合も root 権限で実行する必要がある.

コマンドラインでの利用

書式は次の通り.

sudo ./i2cdisplay.py <bus> <addr> {write|clear|cursor|backlight}

<bus>, <addr> はそれぞれバス番号とデバイスアドレスである.
サブコマンドは,それぞれ文字の出力,画面のクリア,カーソルの表示切り替え,バックライトの調節である.

文字の出力

文字の出力は sudo ./i2cdisplay.py <bus> <addr> write <input>+
<input> にスペース区切りで複数の文字列を渡すと複数行に分けて出力する.
例えば1行目に abc を 2行目に def を表示する場合,

sudo ./i2cdisplay.py <bus> <addr> write "abc" "def"

となる.

画面のクリア

sudo ./i2cdisplay.py <bus> <addr> clear

カーソルの表示切り替え

# カーソルを表示する
sudo ./i2cdisplay.py <bus> <addr> cursor True 
# 非表示にする
sudo ./i2cdisplay.py <bus> <addr> cursor False

バックライトの調節

# 強度は 0-255 から選ぶ(下記の例では 128)
sudo ./i2cdisplay.py <bus> <addr> backlight 128

ライブラリとしての利用

# 初期化
d = MPTHDisplay(<bus>, <addr>)

# 文字の出力
d.write("abc")

# 改行
d.newline()

# クリア
d.clear()

# 複数行の出力
d.writelines("abc", "def")

参考