Raspberry PiとI2C接続のキャラクタ・ディスプレイ その2 Pythonでプログラム
■I2Cはバイト単位の入出力
前回、i2c-toolsを使って、OLE(有機EL)表示器のSO1602Aの動作を確認しました。アドレスは0x3cでした。smbusのPythonライブラリもインストールしました。smbusはI2Cとほとんど同じ規格ですが、策定はフィリップスではなくインテルです。PCの電源管理や温度管理のために使っています。PCなので、マスタは一つだけという特殊事情があります。I2Cはマルチマスタを考慮したプロトコルです。
●Pythonでプログラミング
次の一覧表が、smbusライブラリのファンクションです。表示器は書き込みだけをします。したがって、単独の書き込みは、次の2種類があります。
- write_byte_data(アドレス, コマンド, 1バイトの値)
- write_word_data(アドレス, コマンド, 1ワードの値)
複数のデータをまとめて書き込みときは、次の二つのいずれかを使います。
- write_block_data(アドレス, コマンド, 1個以上の1バイトの値※)
- write_i2c_block_data(アドレス, コマンド, 1個以上の1バイトの値)
(※最大32バイトまで)
二つの関数で、送っているデータを見たのが次の図です。アドレスを送った後の状態が異なります。SO1602Aは、write_block_data() では、先頭に間違ったキャラクタを表示したので、write_i2c_block_data()を使うことにしました。なお、次回に予定しているAQM1602では、どちらも正しい表示ができました。
ファンクション SMBus |
---|
|
ファンクション I2C |
|
(※)2018/10/27 long[] read_block_data(int addr,char cmd)のパラメータが一つ多かったので削除した。
●画面の初期化
#!usr/bin/env python # 画面初期化 OLED SO1602 |
実行すると、カーソルが左上で点滅します。
画面の初期化は、
i2c.write_i2c_block_data(addr01, _data, [_clear,_home,display_On]) |
でも動作しました。time.sleep()を入れないと正常にコマンドが受け付けられないときは、1命令ずつ書き込みましょう。
●書き込み
左上から"1234"と表示します。
i2c.write_i2c_block_data(addr01, _data, [0x31,0x32,0x33,0x34]) |
つづけて"aX"と表示します。
i2c.write_i2c_block_data(addr01, _data, [ord('a'),ord('X')]) |
2行目の先頭から、"1234"と表示します。
i2c.write_byte_data(addr01, _command, OLED_2ndline) i2c.write_i2c_block_data(addr01, _data, [0x31,0x32,0x33,0x34]) |
文字列”Temp: ”を表示して、下の行に移動後”109”と表示します。
message1="Temp : " i2c.write_byte_data(addr01, _command, OLED_2ndline) i2c.write_i2c_block_data(addr01, _data, [0x31,0x30,0x39]) |
初期設定と上記のプログラムを一つのファイルにして、i2c.pyというファイル名で保存します。sudo chmod 755 i2c.pyで実行権を付けます。python i2c.pyと入力して実行すると次のように表示されました。
コラム I2Cの転送速度
Standard-mode では最大100kbit/s、Fast-mode では最大400kbit/s、Fast-mode Plus では最大 1Mbit/s、High-speedでは最大 3.4Mbit/s のデータ転送が可能です。
SO1602Aのデータシートにはクロックが最小2.5us=400kHzとなっているので、/boot/config.txtに、デフォルトの100kHzから400kHzへ変更しても動作するかもしれません。
dtparam=i2c_baudrate=400000