niszetの日記

細かい情報を載せていくブログ

キャラクタLCDで高速で文字列をスクロールする技術

まずは文字表示領域の話からはじめよう。

新章突入です。これまでの話を踏まえて書いていますので、よくわからんところあるな?という場合は前の章の1話からご覧ください(↓こちらから)

niszet.hatenablog.com

なんの話?

今回は、キャラクLCDで文字をスクロールさせる動画の第二弾、こちらのtweetに貼った動画の内容の解説です。

前回の動画、

と比べると、かなり高速でスクロールさせているのに文字が見えることが分かると思います(残像が気になりはじめる速度なので、ちょっと読みづらいですが)

では、はじめます。

ひとつひとつ見ていく

今回使用しているキャラクLCD、PLCD1602(クレイン電子)は16x2の文字表示領域を持つ液晶ですが、液晶(コントローラ)の表示モードを切り替えることで上下の文字表示領域をまとめて1つの文字表示領域として使うことが出来ます。

言葉だけだとわかりづらいので図で見ていきましょう。サンプルコードにあった図形の例を使うと、2列で表示する場合に次のように表示されている記号が、

f:id:niszet:20210420162523p:plain

次のように上下の表示領域を使うイメージです。

f:id:niszet:20210421185254p:plain

このように、各ドットが上下2マス使うように引き延ばされて表示されます。これはCGRAM(あるいはDDROM)に入っている字形データそのものには変更なく、このモードに入るとこのように引き延ばされて表示されます。なので、上下に連続しないように表示ということは出来なさそうです(データシートの内容完全に理解した!とまでは言えないので、あったらすみません)

字形が縦に伸ばされているのは動画の右側、niszet0の文字列を確認すると分かりやすいでしょう(スクロールしないので) 余談ですが、文字単位ならDDRAMにどの文字を表示するのかの指定を変えていけばいいので、niszet0の文字列もスクロールさせることは可能のはずです(未確認)

さらに余談ですが、この使い方ではカーソルが表示できませんでした。これはまたいつか書きましょうかね…。

ちなみに、1列表示にしたとき、2列表示のときに下段に表示されていた文字列は表示されなくなります。2列のデータが1列に引き延ばされるイメージで、もし液晶の表示領域が右にずーっとのびているものであれば、20文字目に出てくるのかなと思います。結局、ここにデータがあっても表示されないだけなので、適当な文字を入れても動作には問題ありません。

話を戻しましょう。

美咲フォントを使った場合です。美咲フォントは8x8の領域を使うので、char型の8つ要素を持つ配列であらわせるのでした。このときの変数名cg0として(宣言時はcg0[8])、このデータを普通に変数cg0にデータを入れた場合、

f:id:niszet:20210421185353p:plain

のようになります。

一方、液晶ディスプレイの方を考えると、文字表示領域には横5ドットしかないため、美咲フォントの1文字は液晶の1つの文字表示領域には収まりません。

表示のさせ方として、今回は文字表示領域間に1マス文字が見えなくなる柱があると思うこととして、となりの文字領域にまたがる場合にその柱の分を加味することとします。ここで、見えないドットを灰色ドットで示すとすると、2列表示モードで一番上の文字表示領域にこの文字を表示する場合は

f:id:niszet:20210421185523p:plain

のようになります。これを、1列モードで表示する場合は、縦に引き延ばしたものを考えれば良いわけですから、次のようになるわけですね。

f:id:niszet:20210421191351p:plain

さて、動画では単純に1列モードで表示するのではなく、字形としてはもう一つ工夫を入れています。それが、横方向への引き延ばしです。

あんまり詳しくないのでふわっとした話ですが、横方向に文字がスクロールするため、液晶の応答(ON->OFFもOFF->ONも)と目が感じる残像(感じるのは脳?)の影響で、この文字が1文字幅だと速度を上げていくと段々見づらくなっていきます。

あと単純に字形も縦長で美しくないですね。元の字形を保ちたいという気持ちがわいてきます。

そこで、元々の字形(再掲)

f:id:niszet:20210421191740p:plain

を横方向に引き延ばした字形として以下のようなデータを作成します。

f:id:niszet:20210421191750p:plain

これは縦方向の引き延ばしと同じように、横方向にも2マス使うようにデータを入れていけば良いわけです。

一点、注意しないといけないのは、一番上に番号を振ったとおり、幅8だったものが幅16になるので、もはやchar型ではデータを持つことが出来ないという点です。char型の変数2つで表現しても良いですが、ここは素直にint型などのより多くのデータ量を持てる型を使いましょう(機種(正確にはコンパイラ依存のはず)によってバイト数が違うとかある気がするのですが、今は16bit=2byte持つことが出来ればよいので、ここは最低限保証されているはず、です)

これを液晶画面に表示するときは、こちらで横に伸ばしたこの字形がさらに縦に引き延ばされ、結果として次のような字形になることが期待できます。

f:id:niszet:20210421192146p:plain

実際には横方向には柱があるという工夫が出来ますが、縦方向の上下に切れる部分はLCDコントローラが勝手にやるので上下にぶった切られてちょっとだけ縦長のバランスになります。ここは妥協するポイントですね。表示しないドットを灰色で示すと、最終的には次のようになります。

f:id:niszet:20210421192851p:plain

ということで、モードの設定と前処理によって表示する字形を制御し、結果として視認性が向上、スクロール速度を上げてもみやすくできる、というお話しでした。

実際にはこれにコントラストやリフレッシュレートなどちょっと細工があるのですが、文字を大きく表示した点が見た目で一番インパクトが出るので、まずはここを押さえると良いでしょう(そう?)

ということで、動画第二弾のための要素技術の話でした。