2012年9月15日土曜日

テキストLCDをグラフィックLCDのように扱うギミック ~テキストLCDでもここまでできる!~

今回はちょっとお遊び休憩ネタです。

Analog Devices社Blackfin BF592搭載オーディオ・プラットフォームBlueTank BF592を使ったお遊び。
まずは動作をご覧下さい。



上記で使用しているテキストLCDは2行8文字の表示が可能なLCDです。

殆どのテキストLCDにはHD44780互換のLCDコントローラが搭載されています。
ユーザ登録可能な文字は8つあります。

しかし、普通に考えるとユーザ登録文字を使って全画面を一度に表示する事はできません。
なぜなら2行x8文字で、16文字のユーザ登録文字が必要になるからです。

では「どうしているのか?」というと簡単で、時分割で細かく切り替えて表示を行なっています。
以下にステップ毎の動作の様子を示します。

1文字目は普通に考えてもいけます。


もちろん2文字目も。


3文字。


4文字。


5文字。


6文字。


7文字。


8文字。

ここで、ユーザ登録文字の8文字を使い切りました。
まだ画面の半分しか描画できていません。


で、どうするのかというと・・・。

新たに描画の必要がある領域のために一番最初に書いた文字を消します。
これなら使っているユーザ登録文字は依然として8文字です。


同様にして。


どんどん上側を消して下側を書きます。


どんどん上側を消して下側を書きます。


どんどん上側を消して下側を書きます。


どんどん上側を消して下側を書きます。


どんどん上側を消して下側を書きます。


これで下側の画面描画が完了しました。


上記を非常に細かい時間で繰り返すと以下のように見えるというのが今回のギミック。
まぁ、飛び越し走査とは違いますが、あえて言うならば「なんちゃってインターレース」でしょうか?


実はこのデモ、48KHzステレオオーディオの処理をしながらの動作です。
先日のFFTスペアナと合わせればもっと楽しい見た目を提供できそう。

動作を見ると実装は複雑なんじゃないか?と思うかもしれません。
でも、きちんと設計すればそんな事はありません。

以下のような定義でざざっと絵を作れるようにしました。


で、実際の描画は下層のglcdモジュールにお任せという具合です。

glcd_clear(&(w->glcd));
for (px = 0; px < GLCD_PX; px++) {
  for (py = 0; py < GLCD_PY; py++) {
    glcd_set_pixel(&(w->glcd), px, py, (img1[py][px + (VOL_MAX - w->volume)] == 'o') ? 1 : 0);
  }
}

gcld_blitを呼ぶと、内部でうまい具合に1シーケンス分の処理をしてくれるという設計です。

glcd_blit(&w->glcd);

上記の画像は「リアルなLCD画像ファイルが得られるLCD Toolの改良」で取り上げたlcdtoolを使って生成しました。
LCDプロファイルとLCDフォントに少し手を入れるだけで好みの出力が得られます。
BMP画像ファイルの生成はスクリプトで一発自動生成。
#!/bin/sh
LCDTOOL=lcdtool
$LCDTOOL  bluetank.lcdprof glcd_demo.lcdfont seq01.bmp '\x00' '        '
$LCDTOOL  bluetank.lcdprof glcd_demo.lcdfont seq02.bmp '\x00\x02' '        '
$LCDTOOL  bluetank.lcdprof glcd_demo.lcdfont seq03.bmp '\x00\x02\x04' '        '
$LCDTOOL  bluetank.lcdprof glcd_demo.lcdfont seq04.bmp '\x00\x02\x04\x06' '        '
$LCDTOOL  bluetank.lcdprof glcd_demo.lcdfont seq05.bmp '\x00\x02\x04\x06\x08' '        '
$LCDTOOL  bluetank.lcdprof glcd_demo.lcdfont seq06.bmp '\x00\x02\x04\x06\x08\x0A' '        '
$LCDTOOL  bluetank.lcdprof glcd_demo.lcdfont seq07.bmp '\x00\x02\x04\x06\x08\x0A\x0C' '        '
$LCDTOOL  bluetank.lcdprof glcd_demo.lcdfont seq08.bmp '\x00\x02\x04\x06\x08\x0A\x0C\x0E' '        '

$LCDTOOL  bluetank.lcdprof glcd_demo.lcdfont seq09.bmp ' \x02\x04\x06\x08\x0A\x0C\x0E' '\x01'
$LCDTOOL  bluetank.lcdprof glcd_demo.lcdfont seq10.bmp '  \x04\x06\x08\x0A\x0C\x0E' '\x01\x03'
$LCDTOOL  bluetank.lcdprof glcd_demo.lcdfont seq11.bmp '   \x06\x08\x0A\x0C\x0E' '\x01\x03\x05'
$LCDTOOL  bluetank.lcdprof glcd_demo.lcdfont seq12.bmp '    \x08\x0A\x0C\x0E' '\x01\x03\x05\x07'
$LCDTOOL  bluetank.lcdprof glcd_demo.lcdfont seq13.bmp '     \x0A\x0C\x0E' '\x01\x03\x05\x07\x09'
$LCDTOOL  bluetank.lcdprof glcd_demo.lcdfont seq14.bmp '      \x0C\x0E' '\x01\x03\x05\x07\x09\x0B'
$LCDTOOL  bluetank.lcdprof glcd_demo.lcdfont seq15.bmp '       \x0E' '\x01\x03\x05\x07\x09\x0B\x0D'
$LCDTOOL  bluetank.lcdprof glcd_demo.lcdfont seq16.bmp '        ' '\x01\x03\x05\x07\x09\x0B\x0D\x0F'

$LCDTOOL  bluetank.lcdprof glcd_demo.lcdfont view.bmp '\x00\x02\x04\x06\x08\x0A\x0C\x0E' '\x01\x03\x05\x07\x09\x0B\x0D\x0F'
自動化してあるので、画面数が多くても操作が苦になる事はありません。
また、出力が間違っていても、スクリプトさえ残しておけば後で何度も修正する事ができます。

0 件のコメント:

コメントを投稿