キャラクタLCDモジュール I2C化アダプタ
2014年1月 お馴染みのキャラクタLCDモジュール。操作するには6本のI/Oピンが必要で、ピン数が少ないマイコンで使うには少々不便です。そこで、キャラクタLCDモジュールをI2C化するアダプタを作りました。使用するI/Oピンが2本で済みます。ついでに、I2Cバスの電圧を気にせず使えるようにしました。 |
寄り道開発 | ||
|
I2Cレベル変換の必要性 |
I2Cに限らず一般に、異なる電圧で動作するデバイスを接続するには注意が必要です。そのまま接続すると、低電圧側のデバイスでは受信するHiの信号レベルが許容値以上の電圧かもしれず、デバイスが壊れる可能性があります。高電圧側のデバイスでは受信するHiの信号レベルが足りないかもしれず、Loと判定する可能性があります。 (1) 本アダプタは、I2Cのスレーブデバイスです。図のように、内部的にはマイコン(AVR)がLCDモジュール(以下LCD)を操作したりI2Cバスと接続して通信を行ったりします。LCDは5Vで動作します。マイコンは2.7〜5Vで動作します。 今、3.3Vで動作するマスターデバイスに本アダプタを接続することを考えます。 (2a) マスターデバイスの電圧に合わせ、マイコンを3.3Vで動作させるとします。このときI2Cバスの信号レベルも3.3Vになります。一方、LCDとも3.3Vで通信することになりますが、LCDは5Vで動作しているため信号レベルも5Vが基準となります。ここで電圧の不整合が起こります。 (2b) ではLCDの電圧に合わせ、マイコンを5Vで動作させるとします。それならLCDとの間に信号レベルの問題はありません。しかしマスターデバイスとも5Vで通信することになり、ここで電圧の不整合が起こります。 (3) LCDはいつでも5V動作なのでマイコンをそれに合わせるとすれば、I2Cバスの方で3.3V〜5V間のつじつまを合わせることになります。そのための専用ICがあります。I2Cの信号電圧を双方向に変換するICです。これをI2Cデバイス間に挟めば、電圧の不整合を起こさず通信することができるようになります。 条件付きで… 条件付きですが、I2Cレベル変換なしでデバイスを接続する方法もあります。 上図(2a)において、LCD(5V)からマイコン(3.3V)への出力信号がなければ、マイコンはダメージを受けません。ここで、LCDがHiを受信するときにHiであると認める信号レベル(閾値)は、通常のキャラクターLCDモジュールだと2.2〜2.5Vです(TTLレベル。データシートを確認すること)。マイコンからLCDへ送信するHi(3.3V)がLoと誤認されることはないと考えられます。 この仕組みを利用する場合、マイコン(3.3V)とLCD(5V)の電圧が安定していることが必要です。少なくとも、ノイズや負荷によって電圧が変動することがあったときに、マイコンのHiがLCDのHiの閾値を下回ってはいけません。 |
回路図とプログラム | ||
回路図 動作テスト時にVCCとGNDのワイヤーを逆に挿してI2Cレベル変換モジュールを壊してしまいました。その失敗から電源ラインにSBDを入れています。0.4Vの電圧降下がありました。I2Cレベル変換モジュールは1.7Vから動作することになっていますが、SBDの電圧降下とHT7750の変換効率を考慮し、現実的には2.7Vの回路から利用可といったところです。 動作電圧と通信速度から、I2Cのプルアップ抵抗は2kΩが妥当なようです。実験中、4.7kΩでも問題ありませんでした。 ※工作物にはうっかり1kΩを付けてしまったが問題なく動いている。でも少し後悔。 本アダプタのI2Cスレーブアドレスは 0111100 または 0111101 です。JMPを切り替えてどちらか選べます。これにより、I2Cバスに本アダプタを2個まで接続することができます。また、回路内に同じスレーブアドレスのデバイスがあるときに、こちら側で回避するという使い方もあります。※アドレスの値はI2CのOLED(グラフィックディスプレイ)を参考にした。 本アダプタの中心となるマイコンはAVR ATtiny20です。I2Cのスレーブ機能を内蔵しています(マスター機能はない)。ピン数もLCDを動かすのに十分で、まさにこういった目的のためにあるようなマイコンです。 ATtiny20の性能上、通信速度は100kHzが限度のようです。マスターから400kHzの通信を試みてもエラーにはなりませんが、期待した速さは出ません。※[Application Note] Atmel AVR290: Avoid Clock Stretch with Atmel tinyAVR - (pdf) ATtiny20を基板に取り付けた状態でファームの書き込みができます。 本アダプタはLCDのコントラスト(文字の濃さ)調整の抵抗と、バックライトの明るさ調整の抵抗を含みません。コントラスト調整の抵抗は、LCDモジュールにより取り付け方(配線)が異なることがあるためです。 参考までに… もし本アダプタを5V専用として作るなら、HT7750の昇圧部とI2Cレベル変換部を省略できます。主要な部品がATtiny20とプルアップ抵抗2本だけというシンプルな構成になります。 配線図 完成/動作中の様子 計画変更により、昇圧回路をモジュール化したことに意味が無くなりましたが、せっかくなので使うことにしました。それでこんな形の完成品です。使用しているLCDは「LCDモジュール SC162シリーズ」で紹介したものです。 動作デモは、I2CマスターデバイスとしてATmega88Pが3.3Vで動作しています。LCDは16x2サイズのものに対し、10x2の表示範囲で、2行つながり上書きモード、カーソル表示、を指定しました。右上から左下にかけて「65535」が自動改行されています。また、右下「P4」の次は左上「P5」に続いています。最初に左上に書いてあった文字は上書きされています。「abc」の右側の「P」がぼやけているのは、その位置でカーソルがブリンクしているためです。おかげで、この「P」が画面内で最も古い文字で、手前の「c」が最も新しい(最後に書かれた)文字だということが分かります。カーソルを表示しないモードだと画面上のどこまで上書きされたのか分かりません。 【参考】 |
スレーブ側/マスター側のプログラム | ||
本アダプタ(スレーブデバイス)のファーム、マスターデバイスのサンプルプログラムとAVR用ライブラリを公開します。
ここで公開するプログラムも、後述するプロトコルの説明も、本アダプタを作らない限り役立つことはないでしょう。似たようなものを作ろうとする人には参考になるかもしれません。実際のところ本アダプタのようなデバイスは、自作するより既製品を用意し、Arduinoから使う人が多いのではないかと思います。素(す)のAVR(ATmega48〜328P)向けのライブラリが活用される機会は、ますますないでしょう。 |
通信プロトコル(基本) | ||||||||||||||||||||||||||||||||||
LCDモジュール(以下 LCD)を操作するための、最小限の(低レベルの)通信手順を以下に示します。LCDのコントローラを直接操作する感覚です。コマンド、データの詳細はコントローラのデータシートを参照してください。
P…ストップコンディション(マスターからスレーブへ送信する) A…アクノリッジ(スレーブからマスターへ送信される) I2Cの1回の通信(SからPまで)でマスターから送信する内容は固定長です。 LCDにコマンドを送信するには、コントロールバイトを0x00とし、コマンドの具体値を送信します。 LCDにデータを送信するには、コントロールバイトを0x80とし、目的のデータを送信します。具体例としては文字コードです。仮に8byteのデータを送信する場合、連続8回の通信を行うことになります。 スレーブデバイス(本アダプタ)は基本的にACKを返します。ただし、スレーブアドレス送信時に誤ってリード(R)指定した場合はNACKを返します。その他、通信エラーが発生した場合にNACKを返すことがあります。 コントロールバイトの値(マクロ定義)
【参考】 AVR用ライブラリ内の関数
|
通信プロトコル(拡張) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
LCDモジュール(以下 LCD)を操作するための、拡張された(高レベルの)通信手順を以下に示します。LCDのコントローラに対する複雑な操作なしに、LCD操作/文字表示をすることができます。先述した低レベルの操作も拡張プロトコルの手順に含まれるので、先と同様に使うことができます。
P…ストップコンディション(マスターからスレーブへ送信する) A…アクノリッジ(スレーブからマスターへ送信される) I2Cの1回の通信(SからPまで)でマスターから送信する内容は不定長です。基本プロトコルの形が最小パターンです。 データバイトは通常、1byteか2byteです。文字列を送信する場合、最大32文字(32byte)まで一括して送信できます。1文字ずつ通信するより効率的です。 スレーブデバイス(本アダプタ)は基本的にACKを返します。ただし、スレーブアドレス送信時に誤ってリード(R)指定した場合はNACKを返します。32byteを越えるデータバイトを一度に送信すると、越えた分すべてにNACKを返します。その他、通信エラーが発生した場合にNACKを返すことがあります。 拡張コントロールバイトの値(マクロ定義)
LCD_FUNC_SETLINEMODE の引数(マクロ定義)
【参考】 AVR用ライブラリ内の関数
|
◆ ◆ ◆ |
I2Cのスレーブ側のファームを初めて書きました。どんなものか分かって面白かったです。 I2Cレベル変換モジュールがデリケートで参りました。4個買って2個破損。悔しかったです。 最初に完成したアダプタは想像以上に大きく、作った後で使いにくいことに気付きました。 とりあえず作ってみよう、で失敗。実際に使っている様子(イメージ)をしっかり固めてから 作った方がよいということを、改めて確認することとなりました。 |
(C) 『昼夜逆転』工作室 | [トップページへ戻る] |