Raspberry PiとI2C接続のキャラクタ・ディスプレイ その1 OLEDのSO1602A

I2Cはマイコンとデバイスをむすぶシリアル通信規格

 マイコン機器やスマホのプリント基板上で使われるシリアル通信のI2Cは、2本の信号線に複数のセンサなどの表示器を接続できる便利な規格です。タイミングは次のArduinoの記事を参照ください。

   I2Cインターフェースのセンサを接続する(4)I2Cのタイミング

 本連載では、キャラクタ表示器を扱います。電子工作では20文字×2行のLCDキャラクタ・ディスプレイが定番でした。しかし、接続する信号がパラレルなのでI/Oポートが多数必要でした。また、1行に表示する文字数も、今回利用するのでは16文字、少ないのでは8文字とコンパクトな表示器も出てきています。

 1-Wireという信号線1本でシリアル通信を行う規格がありますが、この規格で使える表示器はほとんど見ません。2本で接続できるのがI2Cです。LCDキャラクタ・ディスプレイ内部では古いコントローラを使っているため、処理が遅いです。I2Cは100kHzと遅めの転送周波数ですが、少し待ち時間を入れながら使います。

 電子工作の世界では、8ビットのPICマイコンでパラレル信号を接続するLCDキャラクタ・ディスプレイを使う紹介が古くからあります。現在ではArduinoで利用することも多くなりました。パラレル接続のLCDキャラクタ・ディスプレイはライブラリがありますが、I2C用は用意されていません。本WebではI2C-LCDのライブラリを作っています。

 Arduinoで利用するときには何も問題が発生しなかった表示器が、Raspberry Piではうまく認識、表示ができないことがあります。

チェックとプログラミングに必要なツールをインストール

 i2c-toolsを入れると、シェル・コマンドでI2Cが利用できるようになります。Pythonが使いたいので、いっしょにライブラリもインストールします。本記事は、2016年9月23日版のRaspbianを使っています。smbusはI2Cとほぼ同じ規格です。

sudo apt-get install i2c-tools python-smbus

 もう一つ利用できるツールにWiringPi-Pythonがありますが、I2Cの情報が少ないので省略します。

I2Cに使えるGPIOピンは2系統ある

 ラズパイのGPIOに出ているI2Cのインターフェースは、0、1の二つのバスがあります。通常は'1'を使います。

  • 3番ピン-SDA、5番ピン-SCLは '1'
  • 27番ピン-SDA、28番ピン-SCLは '0'

 '0'はコラムを参照ください。

16文字2行の表示器を接続する

 秋月電子通商のOLED(有機EL)表示器SO1602Aをつなぎます。I2C通信は、マイコン側が主にマスタに、表示器やセンサなどのスレーブ間で通信をします。複数のスレーブがつながっていることが前提なので、それを判別するのにアドレスが使われます。SO1602Aにふられたアドレスのアドレスは2通り選べます。SA0端子をGNDにつなぎ、0x3cに設定します。

 SO1602Aの電源電圧は3.3Vなので、Raspberry Piとそのままつないで使えます。全部の表示が点灯したときの消費電流は約80mAですから、3.3Vの端子から供給できる50mAを超えます。文字を表示しているときの点灯率は半分以下なので、ぎりぎり大丈夫と思われます。確認していません。

 SO1602Aは16文字×2行のキャラクタ表示ができ、明るい表示文字が特徴です。購入後、ピンヘッダをはんだ付けをします。


I2Cツールで確認できること

 最初に使うのは、I2Cのバスに何がつながっているかを知るコマンドです。最後の’1’はバスの番号です。’-y'は、実行時にYes/Noを聞かれるときにYesで答えるときにいったん動作が止まるのを避けます。ターミナルを立ち上げて、キーボードから打ち込みます。

i2cdetect -y 1

 何も見つからないときは、’--’で表示され、デバイスが存在するときは、そのアドレスが表示されます。接続を間違えたときは全面--になります。プルアップ抵抗が適切でないときなどは、表示がとてもゆっくりです。接続が正しいときは、数秒で表示が完了します。

 次回利用する予定の表示器もI2Cにつなぎました。i2cdetectの結果です。二つのデバイスを見つけました。次回利用する予定のSO1602Aではないほうを抜くと「3c」だけが表示されたので、この表示器は0x3cのアドレスだとわかります。

i2cdetect -y 1

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

 I2Cツールでコマンドを出します。コマンドの構成は次のようになります。

 

i2cset アドレス  コマンドもしくはデータ コード

  • アドレスはx03c
  • コマンドを送るときは0x00、データを送るときは0x40

 コマンドとは、表示器を初期化をするとか、カーソルの位置を移動したいときなどに使います。データを選んだとき、コードは表示する文字です。次のようなASCIIコードで指定します。0xと最初についているのは、16進を表すためです。

  • 数字の1は0x31、2は0x32...
  • アルファベットの小文字aは0x41、bは0x42...
  • アルファベットの大文字Aは0x61、Bは0x62...

 初期化の作業は表示器によって大きく異なります。SO1602Aの初期化コードは短いです。#以降はコメントなので、打ち込まなくても動きます。

i2cset -y 1 0x3c 0 0x01  #画面クリア
i2cset -y 1 0x3c 0 0x02  #左上隅にカーソルを移動
i2cset -y 1 0x3c 0 0x0f  #表示をON

 'a' (0x61)を表示します。カーソルは、文字を表示するたびに右に移動します。

i2cset -y 1 0x3c 0x40 0x61

 1行に16文字を表示するので、17文字目はどうなるでしょうか。



 18、19、20文字までは何も表示されませんでした。21文字目が2行目の先頭に表示されました。そのまま文字を表示し、右端を過ぎても追加の文字を入れましたが、スクロールはしませんでした。

 2行表示エリアがあり、2行目の先頭に強制的にカーソルを動かすコマンドは次になります。各表示位置はDDRAMアドレスを指定します。DDRAMはLCD内部にある表示用メモリです。

i2cset -y 1 0x3c 0 0xa0  # 00x20+0x80



コラム GPIOでは2種類のI2Cバスが利用できる

 定番の'1'以外に'0'が使えます。

'0'  : 27番ピン-SDA、28番ピン-SCL

  '0'のI2CはOSが立ち上がるときにEEPROMを探しに行った後、通常のI/Oピンに戻ります。利用するときは、/boot/config.txtに追加します。

dtparam=i2c_vc=on

※https://learn.sparkfun.com/tutorials/raspberry-pi-spi-and-i2c-tutorial

 利用するときは、SDA、SCLラインはプルアップされていないので、たとえば10kΩ前後の抵抗で3.3Vへプルアップします。SO1602Aで動作を確認しました。

 速度の変更は、下記のように記述します。

dtparam=i2c_vc_baudrate=50000

 '3'というバスも存在しているようですが、使う方法が見つかりませんでした。

-

 コラム I2Cを有効にする

 ラズパイの初期状態では、シリアル通信のI2Cは有効になっていません。

 設定メニューから変更します。「Preferences」-「Raspberry Pi Configuration」を選びます。

 表示された設定画面で、Interfacesのタブを選びます。I2Cの「Enabled」をチェックしOKを押して有効にします。この後、rebootします。再起動するとI2Cが有効になります。

 2015-05-05バージョンのRaspbianから、I2CとSPIはpiと同じgroupに入っています。