とある事情でキャラクタ LCD モジュールを PC に繋げたいと考えました. 当初は FT232R 等のUSB-シリアル変換デバイスを使って, PIC で LCD を制御しようかと考えました. しかし PIC のプログラムを組むのは面倒なので誰か製作記をあげてないかなと ネットをさまよってみると, こんなページを発見しました. すばらしい! 早速該当するモジュールを買って改造を試みてみました.
人間ここまで上手くいくと少し贅沢になります. 該当モジュールは 16 文字 2 行と沢山表示できる反面少しごつくかつ高価です. 当方が出したい文字はそこまで多くないのです. 秋月を覗くと もう少し小さくて安い液晶モジュールが転がっています. I2C 接続ですが...
そんなにスピード要らないんだから 以前開拓した FT232R の CBUS を IO ピンに 見立て直接 PC から制御すればいいんじゃないかと思い立ちました. で, 実行に移す前に似たようなこと誰かやってないか探してみると こちら (音が出るページです, 注意!) に先人がいました. しかもタイミングは Asynchronous Bit Bang mode というのを使えば FT232R の方で勝手にやってくれるので PC 側は気にかけなくていいようです.
早速それらの情報を使って実験用回路を組みと C++ の ライブラリにしてみました。 実験回路の配線は次のようなものです. 気をつけないといけないのは SCL および SDA をプルアップしないことです.
一方ライブラリは使用にあたって別途 ftd2xx.h と ftd2xx.lib が必要です. その辺の情報はこちらを参照ください. 使い方は
デバイスを開くする. 成功すると零を返す. 非零の場合, 理由が値で示されているが 説明は省略, ソース参考されたし. 引数が無いもしくは null の場合, 最初に発見された FTDI デバイスを開く. 引数でシリアルナンバを指定して特定の FTDI デバイスを指定することもできる. シリアルナンバの取得や設定は こちらにある ft232rconf を使えば可能.
デバイスを閉じる.
スタートコンディションを送る
ストップコンディションを送る
1byte のデータを送る. ack があると true を返す.
1byte のデータを受信する. 第二引数が true だと ack を返す.
実際の使い方は例えば 24C256 (A0,A1,A2,WP,Vss⇒GND, Vcc⇒Vdd) なら
char word[64] = "This is I2C writing test by FT232R Asynchronous bit bang mode. "; ftdiI2Clib lib; if (!lib.OpenDevice()){ #ifdef WRITE lib.SendStart(); printf("%c\n", lib.SendByte(0xa0) ? 'o' : 'x'); printf("%c\n", lib.SendByte(0x00) ? 'o' : 'x'); printf("%c\n", lib.SendByte(0x00) ? 'o' : 'x'); for (int i=0;i < 64;i++) printf("%c", lib.SendByte((byte)word[i]) ? 'o' : 'x'); printf("\n"); lib.SendStop(); #else byte k; lib.SendStart(); printf("%c\n", lib.SendByte(0xa0) ? 'o' : 'x'); printf("%c\n", lib.SendByte(0x00) ? 'o' : 'x'); printf("%c\n", lib.SendByte(0x00) ? 'o' : 'x'); lib.SendStart(); printf("%c\n", lib.SendByte(0xa1) ? 'o' : 'x'); for (int i=0;i < 63;i++){ lib.RecvByte(&k, true); printf("%c", k); } lib.RecvByte(&k, false); printf("\n"); printf("%c", k); lib.SendStop(); #endif lib.CloseDevice(); } else { fprintf(stderr, "Open Error\n"); } |
一方 kxp84-2050 (GND,ADDR0⇒GND, VDD,IO_VDD,CS⇒Vdd, RESET⇒電源投入後一瞬だけ High) なら
if (!lib.OpenDevice()){ byte k[6]; int x,y,z; while (!kbhit()){ lib.SendStart(); lib.SendByte(0x30); lib.SendByte(0x00); lib.SendStart(); lib.SendByte(0x31); for (int i=0;i < 5;i++) lib.RecvByte(&k[i], true); lib.RecvByte(&k[5], false); lib.SendStop(); x = (k[0] << 4) + (k[1] >> 4) - 2048; y = (k[2] << 4) + (k[3] >> 4) - 2048; z = (k[4] << 4) + (k[5] >> 4) - 2048; printf("%d %d %d\n", x,y,z); Sleep(20); } lib.CloseDevice(); } else { fprintf(stderr, "Open Error\n"); } |
なお速度はありません. もともと液晶を表示させようともくろんでいる ものですから.
で, 肝心の液晶は完成品の見た目も重要な要素となることもあり まだ試していません. 上手くいけばまた公開します. 一方で冒頭で述べたシリアル化した液晶モジュールは ちょっとした電子回路の動作確認といった用途に使っていくつもりです.
【追記】: なんとか出来ました