ラベル lcd の投稿を表示しています。 すべての投稿を表示
ラベル lcd の投稿を表示しています。 すべての投稿を表示

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'
自動化してあるので、画面数が多くても操作が苦になる事はありません。
また、出力が間違っていても、スクリプトさえ残しておけば後で何度も修正する事ができます。

2012年9月1日土曜日

リアルなLCD画像ファイルが得られるLCD Toolの改良

先日からの改良点

先日適当に作ったLCD Toolですが、なかなか便利に使えそうなので本格的に便利になるように改良しました。
以下に改良点を示します。

機能 改良前 改良後
LCD形状 プログラムにハードコーディング LCDプロファイルで指定可能
LCD描画色 プログラムにハードコーディング LCDプロファイルで指定可能
ドット形状等 プログラムにハードコーディング LCDプロファイルで指定可能
ユーザーフォント プログラムにハードコーディング フォントファイルで指定可能
出力画像サイズ プログラムにハードコーディング プログラム内部で自動計算
非文字コード指定 シェル機能に期待(Windowsでは困難) エスケープ文字による指定が可能
動作プラットフォーム Linuxを前提に実装 LinuxとWindowsで動作確認済み

適当にプログラムでハードコーディングしていた部分を外部から与えられるようにしました。
LCDプロファイルとフォントデータについては後述します。

入力と出力の関係

以下に入力と出力の関係を示します。


LCDプロファイルとは、LCD形状、LCD描画色、ドットサイズ、キャラクタ間隔などを定義したテキストファイルです。
このテキストファイルを編集する事で手持ちのLCDとそっくりの出力を得ることができるようになります。
ファイルの中身は以下のようになっています。
幾つかのLCDに対するサンプルを完備しています。

#
# SC1602BBWB-XA-GB-G
#
CHCNT_X = 16 # Character Count (X)
CHCNT_Y =  2 # Character Count (Y)
CHOFS_X = 16 # Character Offset (X)
CHOFS_Y = 16 # Character Offset (Y)
CHGAP_X =  2 # Character Gap (X)
CHGAP_Y =  2 # Character Gap (Y)
PIXSIZ_X =  4 # Pixel Size (X)
PIXSIZ_Y =  4 # Pixel Size (Y)
PIXGAP_X =  1 # Pixel Gap (X)
PIXGAP_Y =  1 # Pixel Gap (Y)
FGCOL.R = 220 # Foreground Color (Red)
FGCOL.G = 220 # Foreground Color (Green)
FGCOL.B = 220 # Foreground Color (Blue)
BGCOL.R = 120 # Background Color (Red)
BGCOL.G = 120 # Background Color (Green)
BGCOL.B = 230 # Background Color (Blue)
CONTRAST = 96 # Contrast

初版では「ユーザフォントはプログラム中のデータを書き換えてね」という冷たい仕様でした。
実際にユーザフォントを定義しようとすると結構面倒でした。

新しいバージョンでは、フォントファイルを与えるだけで内部のフォントデータを書き換えてくれます。

###########
CODE = 0x00
###########
.....
.o.o.
ooooo
ooooo
ooooo
.ooo.
..o..
.....
###########
CODE = 0x01
###########
.....
.o.o.
ooooo
ooooo
ooooo
.ooo.
..o..
.....
###########
CODE = 0x08
###########
.....
.o.o.
ooooo
ooooo
ooooo
.ooo.
..o..
.....
###########
CODE = 0x09
###########
.....
.o.o.
ooooo
ooooo
ooooo
.ooo.
..o..
.....

プログラム内部のフォントデータは16進数で記述されています。
点灯させたいドットをイメージしながら16進数を操作させるのは不親切です。

上記のように人間がイメージできる形式で記述すれば済むようにしました。

実行例

以下に実行例を示します。

lcdtool ACM0802C-NLW-BBH.lcdprof UserFontSample.lcdfont test1.bmp "ABCDEFGH" "abcdefgh" 



lcdtool SC1602BBWB-XA-GB-G.lcdprof UserFontSample.lcdfont test2.bmp "ABCDEFGHIJKLMNOP" "abcdefghijklmnop" 



lcdtool SC2004CSLB-XA-LB-G.lcdprof UserFontSample.lcdfont test3.bmp "Line 1: LCD Tool" "Line 2: Sample" "Line 3: LCD Tool" "Line 4: Sample"


上記の実行例を見てわかるように、LCDプロファイルとユーザフォント、出力画像ファイル名、メッセージを与えさえすればBMP画像ファイルが得られます。

LCDプロファイルをどんどんカスタマイズしてVFD版を作ったりしても面白そうです。

ユーザフォントを使った出力の指定方法

ユーザフォントを使った出力の指定は、バックスラッシュを使って指定する事ができます。


例えば、上記のCGRAM(3)を表示させたい場合、「\x02」とコマンドラインに与えます。
「\」を表示させたい場合、 「\\」と入力して下さい。
Linuxの端末で与える場合、シェルに解釈させないためにシングルクォートで囲ってから指定する必要があります。

リソースのダウンロード

本記事執筆段階でのスナップショットをこちらからダウンロードできます。
ドキュメントはこちらからダウンロードできます。

Visual C++ 2010 Expressのプロジェクトファイルも同梱してあります。
Windowsでビルドして使用する事もできます。

追記

2012年09月04日追記:v0.0.2にはバグがありました。上記から最新のv0.0.3をダウンロードして下さい。
2012年09月15日追記:http://shinta.main.jp/software/lcdtool/lcdtool_ja.htmlに最新版があります。

AltStyle によって変換されたページ (->オリジナル) /