カテゴリー
IchigoJam

I2C接続の20桁x4行の液晶にIchigoJamを接続する

IchigoJamからI2C接続の20桁x4行キャラクタ液晶へ文字を表示する実験に成功しました。この先も少し道のりがあるのと、私は未だこの液晶を入手していないので、備忘録として記しておきます。
なお、掲載写真は全て、この実験に取り組んでいただいたFacebook IchigoJam-FANグループの松永義幸さん(JR3KQF)によるものです。
写真=Facebook IchigoJam-FANグループの松永さん

I2C-GPIOエキスパンダPCF8574T PCF8574A

この液晶モジュールにはI2Cインタフェースを搭載していません。モジュールの裏側にI2CからGPIO(パラレル)変換のインタフェース基板が搭載されているタイプになります。変換基板にはNXP社の PCF8574T PCF8574A もしくは互換品が搭載されています。I2Cを8本のGPIOに変換するICです。
さて、こういったI2C液晶モジュールは、通常のI2C液晶と大きく異なる点があります。それは液晶ドライバIC(日立HD44780互換品)とのインタフェースが4ビット接続になっていることです。8本のGPIOのうち4本をデータ用に使用し、残るGPIOのうち3本~4本を、信号制御用に使用しています。
そこで、今回、このような4ビット接続用のI2C液晶を制御してみようと思いました。

PCF8574TとHD44780の結線方法

私も類似の液晶を注文しましたが、入荷まで2~3週間。まだ入手できていません。そこで、先行してプログラムだけを作成しようと、このI2Cインタフェース基板の回路(PCF8574TとHD44780との接続方法)を調べてみました。すると、結線方法には様々な方法があることがわかり、また、松永さんが購入したものと、私が購入したものでも異なることが分かりました。
結線内容の具体例(PCF8574T -> HD44780)
例①      例②
P0 -> DB4  P0 -> RS
P1 -> DB5  P1 -> R/W
P2 -> DB6  P2 -> E
P3 -> DB7  P3 -> BL
P4 -> E    P4 -> DB4
P5 -> R/W  P5 -> DB5
P6 -> RS   P6 -> DB6
P7 -> BL   P7 -> DB7
例①は、Arduino公式ブログ内で配布されているライブラリに対応した結線例です。例②は、今回、松永さんが購入した液晶に搭載されていたI2Cインタフェース基板の結線例です。同氏に下図の結線図も作成していただきました。下図に数字が書かれているのが液晶(HD44780)側です。なお、バックライト(BL)の接続の有無等もI2Cインタフェース基板によって異なります。

I2Cアドレスの検索

下記はI2Cアドレスの検索ツールです。Read 0コマンドに対して応答があるかどうかを検索するだけのものです。応答しないデバイスもあるかもしれません。
1 CLS:?”I2C Detector by W.Kunino”
10 Q=0:clt
20 for I=8 to 119
30 D=i2cr(I,#8EC,1,#8ED,0)
40 if TICK()>240 ?”ERR”:end
50 if D ?”– “; else ? hex$(I,2);” “;
60 if I%8=7 ?
70 next:end
実行例

I2C Detector by W.Kunino
— — — — — — — —
— — — — — — — —
— — — — — — — —
— — — — — — — —
— — — — — — — —
— — — — — — — —
— — — — 3C — 3E —
— — — — — — — —
— — — — — — — —
50 — — — 54 — — —
— — — — — — — —
— — — — — — — —
— — — — — — — —
— — — — — — — —
OK

実験用プログラム

下図は表示を確認するための実験用プログラムです。緑色の部分はデバッグ用橙色の部分は明らかに最適化による効果が見込める部分赤色は省略により高速化が図れるかもしれない部分です。
ほぼこのプログラムだけでIchigoJamのプログラム用メモリを占有してしまうで、実用に向けての改良が必要です。
‘ P4~P7にDB4~DB5が接続されているタイプ用
‘ PCF8574T + HD44780 TEST
new
1 CLS:?”LCD TEST”:?”W.Kunino”
100 ?”Init”
110 poke#700,#3C:gsb800
120 gsb800
130 gsb800

140 poke#700,#2C:gsb800
150 gsb800
160 poke#700,#8C:gsb800
170 poke#700,
#0C:gsb800
180 poke#700,
#CC:gsb800
190 poke#700,#0C:gsb800
200 poke#700,
#1C:gsb800
210 poke#700,#0C:gsb800
220 poke#700,
#6C:gsb800
300 ?:?”Print”
310 gsb900
399 end
800 ‘I2C
810 poke#701,(peek(#700) & #FB)
820 ifi2cw(#27,#700,1,#701,1)?”E”

830 ?hex$(peek(#700),2);hex$(peek(#701),2);” “;:wait 5
840 rtn
900 ‘LCD OUT
910 forZ=#900to#913:gsb960:next
912 poke#700,#CC:gsb800
914 poke#700,#0C:gsb800
920 forZ=#920to#933:gsb960:next
922 poke#700,#9C:gsb800
924 poke#700,#4C:gsb800
930 forZ=#940to#953:gsb960:next
932 poke#700,#DC:gsb800
934 poke#700,#4C:gsb800
940 forZ=#960to#973:gsb960:next
950 rtn
960 ifpeek(Z)poke#700,peek(Z)&#F0+#0D:gsb800
970 ifpeek(Z)poke#700,peek(Z)<<4+#0D:gsb800
980 rtn

容量節約バージョン(512バイト)

変数に保持する方法を用いることでコードを大幅に抑えることも出来ます(Ruria Amanagi さんからのアドバイス)。
a=#93:a=a+#EF&a<<8
OK
?hex$(peek(#8CC),2),hex$(peek(#8CD),2)
93 83
OK
以下に修正版を示します。512バイトまで削減することが出来ました。
2行の液晶サイズに対応しています。930行目と940行目の「’」を消すと4行サイズに対応できます。
また980行目の20は文字数です。16桁の液晶の場合は16に変更することで、若干、早くなります。
I2Cアドレスは990行目です。
new
1 CLS:?”LCD”:gsb800:end
800 ‘INI
810 Q=60:gsb990:gsb990:gsb990
820 Q=44:gsb990:gsb990
830 Q=#8C:gsb990:Q=12:gsb990
840 Q=#CC:gsb990:Q=12:gsb990
850 Q=28:gsb990:Q=12:gsb990
860 Q=#6C:gsb990
900 ‘LCD
910 Z=#900:gsb960:Q=#CC:gsb990
920 Q=12:gsb990:Z=#920:gsb960
930 ‘Q=#9C:gsb990:Q=76:gsb990:Z=#940:gsb960
940 ‘Q=#DC:gsb990:Q=76:gsb990:Z=#960:gsb960

950 rtn
960 Q=peek(Z):ifQQ=Q&#F0|13:gsb990elsegoto980
970 Q=peek(Z)<<4|13:gsb990
980 Z=Z+1:ifZ&31=20rtnelsegoto960
990 poke#8ED,#FB&Q:ifi2cw(#27,#8EC,1,#8ED,1)?”E”elsertn
 

Amazonで扱われています

ご購入はこちら
または
https://www.amazon.co.jp/dp/B00HTTZO9C/(アフィリエイトタグなし)
なお、販売元のページでは、I2C用のアドレスが0x20であることが書かれていますが、実際には0x27でした。これだけでも、若干の混乱がありました。
一般的にも、初期値に0x27が設定されているものが多いようです。

ご注意

本ブログでの説明の通り、I2Cインタフェース基板の仕様によってプログラムの修正が必要です。上記の商品以外では動作しない場合があるのでご注意ください。
例えば、前述の例①用には以下のように修正すれば動くと思いますが、動作確認は行っておりません。
‘ P0~P3にDB4~DB5が接続されているタイプ用
‘ PCF8574T + HD44780 TEST
new
1 CLS:?”LCD TEST”:?”W.Kunino”
100 ?”Init”
110 poke#700,#93:gsb800
120 gsb800
130 gsb800
140 poke#700,#92:gsb800
150 gsb800
160 poke#700,#98:gsb800
170 poke#700,#90:gsb800
180 poke#700,#9C:gsb800
190 poke#700,#90:gsb800
200 poke#700,#91:gsb800
210 poke#700,#90:gsb800
220 poke#700,#96:gsb800
300 ?:?”Print”
310 gsb900
399 end
800 ‘I2C
810 poke#701,(peek(#700) & #EF)
820 ifi2cw(#27,#700,1,#701,1)?”E”
830 ?hex$(peek(#700),2);hex$(peek(#701),2);” “;:wait 5
840 rtn
900 ‘LCD OUT
910 forZ=#900to#913:gsb960:next
912 poke#700,#9C:gsb800
914 poke#700,#90:gsb800
920 forZ=#920to#933:gsb960:next
922 poke#700,#99:gsb800
924 poke#700,#94:gsb800
930 forZ=#940to#953:gsb960:next
932 poke#700,#9D:gsb800
934 poke#700,#94:gsb800
940 forZ=#960to#973:gsb960:next
950 rtn
960 ifpeek(Z)poke#700,peek(Z)>>4+#D0:gsb800
970 ifpeek(Z)poke#700,peek(Z)&15+#D0:gsb800
980 rtn

by ボクにもわかるIchigoJam用マイコンボード

ボクにもわかる I2C インタフェース方式

以下にI2C温度センサを使ったI2Cインタフェースについての説明ページを作成しました。
 - 
Chinese (Simplified)
 - 
zh-CN
Chinese (Traditional)
 - 
zh-TW
English
 - 
en
French
 - 
fr
German
 - 
de
Italian
 - 
it
Japanese
 - 
ja
Korean
 - 
ko
Russian
 - 
ru
Spanish
 - 
es