桜のはなびらどっとねっとロゴ

桜のはなびらどっとねっと

Raspberry Pi 2でグラフィック液晶の制御(2) 制御編

この記事は1年以上前に投稿された記事です。 この警告表示について

IMG_4713_20150708

※前回の続きです。

前回、グラフィック液晶のざっくりとした説明と接続をやりました。
今回はその液晶を実際に動かしてみたいと思います。

関連記事リンク

制御方法

制御信号6本+8bitコードなので基本的にはキャラクター液晶とそんなに変わりません。
レジスタ選択信号を切り替えて、イネーブルにした後データを転送するという方法にコントローラを選択する信号を追加するだけです。

初期化方法

この液晶を初期化する手順は以下のとおりです。

tg12864init

電源をGPIOからとった場合、Raspberry Piの電源入力と同時にGPIOの5Vから電源が取れるので、OSが起動している間に30ミリ秒は経つので気にしなくてOK。

後はリセットコネクタを1にしてその後0に、ちょっと待ってまた1に戻せば液晶がリセットされます。
その後にディスプレイスタートラインを0に設定、そしてディスプレイの表示をONにすることで初期化完了。
あとはページと行を指定してデータを送ってあげれば液晶を使うことができます。

コーディング

まず必要なライブラリと定数を定義します。

前回で決定したとおり、データコマンド切り替え(レジスタ選択)を13、イネーブル12 コントローラ切り替えを10/11 リセット信号14としました。

main関数を定義します。

※あとでBMPファイルを読み込む際に引数をつけてファイルを指定するので引数を受け取れるようにしておきます。

次にライブラリと液晶を初期化します。

wiringPi初期化→データbit用ポート初期化→それ以外のポート初期化→リセット信号送信

という手順で初期化を行います。
データ用のbitはGPIO.0~7固定なのでループ関数でループさせています。
ただしループが早過ぎるのかdelayを指定しないと初期化がうまくいかない場合がありました。

次に液晶にデータを転送する関数を作ります。

この関数は

コントローラ選択解除(CS1/CS2に0)→イネーブル信号=0 →コントローラ選択→
イネーブル信号=1 →データ転送→ 今使った全部のポートに0を設定

という制御を指定ます。この関数を使用することによって液晶を

LCD_SET(コントローラ選択,レジスタ選択,データ(8bit));

で制御できます。
例えばCS1に画像データ0xFF(11111111)を転送する場合は以下のように指定します。

LCD_SET(1,1,0xFF);  ※一部記号がみにくいので全角にしています。

この関数を利用してmain関数にて液晶の初期設定を行います。

それぞれのコントローラにスタートライン0指定(0xC0)と表示ON(0x3F)を送信しています。
なお、16進数は分かりづらいという方は以下のとおりに指定することもできます。

main関数にBMP読み込み部分を実装します。

先ほど引数を読み込めるようにしたのでファイルに引数を代入します。
※この代入方法はあまりお勧めできません。きちんとその文字列がディレクトリ名なのかを確認しましょう。今回はpi上の決まった形式で作成したデータを利用するだけですので色々端折っています。

BMPデータを転送する関数を実装します。

この関数は受け渡された[128][8]の2次元配列を後ろから読み込んでLCDにセットします。やっていることは

LCDの表示をオフ→ [横ドットアドレス指定→
[ページアドレスしてい→ページx(0~7)に縦1行分データ転送]x8]x128
→LCD表示オン

という感じです。この液晶は横64ドットでコントローラがわかれていますので、
横ドットのアドレスは63までしかありませんが、ループは128回しています。これでどうやってコントローラをまたいで転送しているのかというと、「0x40+(d%64)」の部分で0x40(横ドットアドレス0)に、繰り返し回数を64で割ったあまり(d%64)を足しています。 そしてコントローラの選択は「1+(d>=64)」の部分で行っています。

この「1+(d>=64)」の(d>=64)の部分は比較演算子で値が64以上なら真になるようになっています。つまりBoolean型のTRUEが数値だと「1」であることを利用して、ループ回数64回以上なら1+TRUE(1)=2になって、CS2が選択されるというわけです。

この関数を使うには…は単に配列をLCD_BMP();の()の中に指定するだけですので省略

以上のコードをコンパイルします。コンパイルはいつもどおり -lwiringPi を指定するだけです。

例えばこのコードを「glcd」というファイル名でコンパイルした場合以下のとおりにすることで使えます。

「./gazou.bmp」が以下の画像だった場合、液晶には以下のように表示されます。

kanji

IMG_4733

以上、グラフィック液晶に画像を表示する事が出来ました。

今回は画像ファイルを読み込んでそれを表示しましたが、この液晶を制御しているコンピュータはRaspberry Pi 2。PICやAVRなんか目じゃないくらいの広大なメモリとストレージ。そして超高速な演算性能を持っていますし、基本LinuxなのでLinuxで出来る処理はすべてこの液晶に適応できるということです。フォントも自在に変更できますし、フレームバッファを利用すればコンソールやGUIを表示することさえできます。(コンソールはともかくGUIは需要あるのかしらないけど)

考えられる使い方は無限大ですね。

ソースコード

上記のコードを完成させたものを以下に貼っておきます。

※液晶の個体によってはこのコードでは表示が乱れることがあります。
表示が乱れる場合で、たまに正常に表示できる場合は「LCD_SET」関数内にある2つの

の数字を大きくしてみてください。 (2015年7月18日追記)

余談

ちなみにこの液晶、結構描画速度が高速なので。例えばGIFアニメみたいなパラパラ漫画を表示することも可能です。試してみた感じ15fps程度なら問題なく表示できますし、なんとか30fpsくらいならいけるみたいなので「動画」を表示しても問題ないくらいの描画性能があるみたいです。白黒ですが。

しかし、残像がひどい。むしろその応答速度の遅さを利用してもっと高速に切り替えて階調表示という手も…。

う~ん…。

改版履歴

2015年7月11日:初版
2015年7月18日:ソースコードの部分に注意書きを追加

“Raspberry Pi 2でグラフィック液晶の制御(2) 制御編” への9件のフィードバック

  1. ふじみ野 より:

    Sakura87 さん
    素早い回答をありがとうございました。
    みごとに表示されました。
    ただ表示がされただけで喜んでいます。
    申し訳ない事ですが中身が何をしているのかは段々に勉強します。

  2. ふじみ野 より:

    Sakura87 さん
    「Raspberry Pi 2でグラフィック液晶の制御(1) 前準備」での質問に回答を頂きありがとうございました。
    何度も結線を確認して実行しました結果、
      横に4列縦に8行に分かれそれぞれのブロックにバラバラの点模様が表示されました。
    各ブロックは濃淡があり32あるブロックは全て模様が異なります。
    何かを描こうとしていると思います。表示は安定しています。

    使用したBMPファイルは貴兄のHPの「./gazou.bmp」を単純に保存したものです。
    この画像をMSペイントの消しゴムで消してモノクロビットマップとして保存して
      sudo ./glcd ./kara.bmp
    で表示させるとLCDは前面が白く表示されました。

    main関数のBMP読み込み部分に
    >// モノクロ2値 1bit 64×128サイズのBMPファイル読み込み
    >// 読み込み ファイル形式が(2bit BMP 64x128px)だと前提して
    と記述がある事に気づきましたがこの意味が分かりません。
    インターネットチェックで調べてみましたが理解ができませんでした。
    (2bit BMP 64x128px)ファイルをどの様に作れば良いのか教えて頂けませんか。

    • Sakura87 より:

      こん○○は。

      > この画像をMSペイントの消しゴムで消してモノクロビットマップとして保存して
      >  sudo ./glcd ./kara.bmp
      > で表示させるとLCDは前面が白く表示されました。

      とありますので、おそらく画像データがおかしいのではと思います。
      ブログにある画像を使わずにそちらで用意したものを試してみて結果がどう変わるかお試しいただけないでしょうか。

      > (2bit BMP 64x128px)ファイルをどの様に作れば良いのか教えて頂けませんか。
      貴方がペイントの消しゴムで消して作ったファイルがその形式のファイルです。
      ペイントでモノクロビットマップとして保存すれば作れます。
      (2bitの部分は1bitの誤りです。訂正しておきます。)

  3. […] 基本的には前回のコードがベースです。ここからBMP制御命令と読み込み命令を削除したものを用意してください。 […]

  4. じゅん より:

    本ページを拝見させていただき、全く同じ構成、部品でグラフィックLCDを組んでみました。
    描画自体はできるのですが、なぜか表示が乱れるときがかなりあります。毎回きれいに表示されていますか?プログラムや回路で何か改善点はありますでしょうか?ご教授いただければ幸いです。

    • Sakura87 より:

      こんにちは。

      私がこの記事を書くまで一週間程度同じ回路で使って動作させていましたが特に表示が乱れるということはありませんでした。

      ただ、表示実験中。以下の様な場合に表示が乱れることがありました。

       ・イネーブル信号を立ち上げてからデータ転送までが早過ぎる
       ・データ転送関数(LCD_SET)を実行する間隔が早すぎる
       ・RESET信号の制御し忘れ *
       ・RW信号のをGNDに接続していない *
       ・Raspberry Piの調子が悪い ←再起動で回復する

         *は記事内に書いてあるもの

      貴方が実際に作成した回路・コードを見てみないとわかりませんが、以上の点が私がこの液晶を買ってから正常に動作できるようになるまでに起きた不具合です。特にこのコードのデータ転送間隔は結構シビアで、転送ディレイ(LCD_SETの delayMicroseconds(2) のところ)は「私が入手した個体で正常に動作する」ギリギリの時間に設定しているので、表示が成功する場合がある場合はおそらくデータを転送している間隔の問題だと思われます。

      試しにこのページ最後にあるコードで90行目と96行目のdelayMicrosecondsの数値を大きくしてみて状況が改善するか確認してみてください。

      • じゅん より:

        いきなりの質問にご丁寧にご回答いただき、誠にありがとうございます。
        ご指摘いただきました90行目と96行目のdelayMicrosecondsの数値を変化させてみたところ、乱れることなく、正常表示が確認できました。(自分の所持している固体はどうやら転送ディレイは4が最適なようです…)
        最近ラズパイを購入し、Sakura87様のHPは非常に丁寧で分かりやすく、いつも参考にさせていただいております。今後も頑張ってください!

コメントを残す

メールアドレスが公開されることはありません。