2013/08/29

BeagleBoneでI2C液晶を使ってみる

BeagleBoneに温度センサーをつけて温度のログを取るものは作りましたが、現在の温度をリアルタイムで見たいので、何かしら表示器をつけようと思いました。

BeagleBoneにはGPIOがたくさんあるので7セグLEDを駆動しても良いのですが、せっかくI2Cの機能を持っているので、これを使うことにしました。

I2Cはひとつのマスタと複数のスレーブをバスにつなげることができる2線式の通信規格です。
マイコンが使用するポートを減らすために作られたとのこと。

  I2Cの使い方
  I2C@wikpedia

さて、I2Cを利用するにもI2C対応の表示機が無いと実験すら出来ないので、秋月電子でI2C液晶キットを買いました。
I2C接続小型LCDモジュールピッチ変換キット 600円なり。
送料が500円かかるため、この際なので表面実装LED等、他にも部品を買いました。

無印BeagleBone1号機は温度計として運用しているので、2号機にubuntu13.04を載せてI2Cの実験をします。

2号機には2013-08-24のイメージを使用しました。
イメージの取得と書き込み方法については下記ページを参照ください。
 BeagleBoardUbuntu@eLinux.org

Kernel3.8のBeagleBoneはCapeManagerを使用してCapeを積んでいく方式となっているため
仮想Capeファイルが必要になります。I2CのCapeファイルを自作するほどの技量はないので、ファームウェアディレクトリにI2Cがないか探します。

 ubuntu@arm:cd /lib/firmware
 ubuntu@arm:/lib/firmware$ ls | grep -i I2C
 BB-I2C1-00A0.dtbo
 BB-I2C1A1-00A0.dtbo

2個出てきました。

どのピンを使っているのか、dtboファイルをソースに変換して確認します。

 sudo apt-get install device-tree-compiler
 dtc -I dtb -O dts -o BB-I2C1.dts BB-I2C1-00A0.dtbo
 dtc -I dtb -O dts -o BB-I2C1A1.dts BB-I2C1A1-00A0.dtbo

その結果、BB-I2C1-00A0はP9_17,P9_18のMux Mode2、BB-I2C1A1-00A0はP9_24とP9_26のMux Mode3を使うことがわかりました。どちらもI2C1を使うので、同時に登録しないほうが良さそうです。

Capeがあるとわかれば早速CapeManagerに登録します。CapeManagerの番号は環境によって異なるので適宜読み替えてください。

 sudo -s
 cd /sys/devices/bone_capemgr.7
 echo BB-I2C1 > slots

登録できてるか確認します。
 dmesg | grep capemgr
 bone-capemgr bone_capemgr.7:  Baseboard:A335BONE,00A5,0512BB000366'
 bone-capemgr bone_capemgr.7: compatible-baseboard=ti,beaglebone
 bone-capemgr bone_capemgr.7: slot #0: No cape found
 bone-capemgr bone_capemgr.7: slot #1: No cape found
 bone-capemgr bone_capemgr.7: slot #2: No cape found
 bone-capemgr bone_capemgr.7: slot #3: No cape found
 bone-capemgr bone_capemgr.7: initialized OK.
 bone-capemgr bone_capemgr.7: part_number 'BB-I2C1', version 'N/A'
 bone-capemgr bone_capemgr.7: slot #4: generic override
 bone-capemgr bone_capemgr.7: bone: Using override eeprom data at slot 4
 bone-capemgr bone_capemgr.7: slot #4: 'Override Board  Name,00A0,Override Manuf,BB-I2C1'
 bone-capemgr bone_capemgr.7: slot #4: Requesting part number/version based 'BB-I2C1-00A0.dtbo
 bone-capemgr bone_capemgr.7: slot #4: Requesting firmware 'BB-I2C1-00A0.dtbo' for board-name 'Override Board Name', version '00A0'
 bone-capemgr bone_capemgr.7: slot #4: dtbo 'BB-I2C1-00A0.dtbo' loaded; converting to live tree
 bone-capemgr bone_capemgr.7: slot #4: #2 overlays
 bone-capemgr bone_capemgr.7: slot #4: Applied #2 overlays.

登録できているみたいですね。

早速BeagleBoneのP9_17,P9_18にI2C液晶をつないで実験してみましょう。
下記ページを参考にやっていきます。


まずはI2Cバスがいくつあるか確認します。

 sudo -s
 i2cdetect -l
 i2c-0 i2c     OMAP I2C adapter  I2C adapter
 i2c-1 i2c     OMAP I2C adapter  I2C adapter
 i2c-2 i2c     OMAP I2C adapter  I2C adapter

0から2まであります。全部スキャンしてしまいましょう

 root@arm:~# i2cdetect -y -r 0
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
 00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
 20: -- -- -- -- UU -- -- -- -- -- -- -- -- -- -- -- 
 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
 50: UU -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
 70: -- -- -- -- -- -- -- -- 

ハズレ。

 root@arm:~# i2cdetect -y -r 1
      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
 00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
 50: -- -- -- -- UU UU UU UU -- -- -- -- -- -- -- -- 
 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
 70: -- -- -- -- -- -- -- --  

これまたハズレ。
man i2cdetectによると、UUはカーネルドライバーで使用されてるアドレス、--は応答がなかったアドレスとのことです。

 root@arm:~# i2cdetect -y -r 2
      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
 00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- 3e -- 
 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
 70: -- -- -- -- -- -- -- --                         

いた!

バス番号が2、アドレスが0x3eであることがわかりました。

コマンドを打っていきます。

 i2cset -y 2 0x3e 0 0x38 0x39 0x14 0x70 0x56 0x6c i
 i2cset -y 2 0x3e 0 0x38 0x0d 0x01 i
 i2cset -y 2 0x3e 0x40 0x53 0x57 0x49 0x54 0x43 0x48 i
 i2cset -y 2 0x3e 0x00 0xc0 i 
 i2cset -y 2 0x3e 0x40 0x53 0x43 0x49 0x45 0x4e 0x43 0x45 i

表示できた
無事、文字が出ました。
文字は出ましたが、あの命令は何なのでしょうか?

i2csetのオプションをまずは見てみます。

 i2cset [-f] [-y] [-m MASK] I2CBUS CHIP-ADDRESS DATA-ADDRESS [VALUE] ... [MODE]

これを元に解釈すると、最初の -y 2 0x3eは「I2Cバスの2番、アドレス0x3eにユーザの確認なしで書き込む」という意味になります。(-yはインタラクティブモードをOffにするオプション)
最後の i は「I2Cブロックデータを書き込む」となります。
データアドレスの部分は0x00と0x40になっていますが、これはコントロールバイトで、データシートによると、コントロールバイトは
 [CO][RS][0][0] [0][0][0][0]
で構成されており、RSが1の場合はデータ書き込み、RSが0の時は制御コマンド書き込みになるようです。0x00は制御コマンド、0x40はデータ書き込みという事になります。COはよくわかりません。

データシートの初期設定方法を見ると、
  1. 電源をONにする
  2. 40ms以上待つ
  3. 0x38を送って通常コマンドにする
  4. 0x39を送って拡張コマンドにする
  5. 0x14を送って内部オシレータの周波数を設定する(?)
  6. 0x70を送ってコントラストを決める
  7. 0x56を送ってアイコンなどのコントラストを決める
  8. 0x6cを送ってフォロワーコントロールを設定する(?)
  9. 200ms以上待つ
  10. 0x38を送って通常コマンドにする
  11. 0x0Cを送ってディスプレイのON/OFFを設定する
  12. 0x01を送ってディスプレイをクリアする
  13. 初期化終了
となっています。最初の2行がこれにあたりますね。

3行目はASCIIコードで"SWITCH"
4行目がDDRAMのアドレスを0x40に変更(つまり2行目の一番最初)に移動
5行目がACSIIコードで"SCIENCE"

となります。

表示はできるようになりましたが、ACSIIコードを指定するのは面倒なので
pythonでこのLCD用のライブラリを作ってみたいと思います。
あとはこの液晶のコマンドについても調べたいところです。


ではまた。

0 件のコメント:

コメントを投稿