niszetの日記

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

キャラクタLCDで文字列をスクロールするやつの解説(3回目)

ようやくハードウェアの階層まで降りてこれそう。

前回の記事

niszet.hatenablog.com

ある程度背景を説明したので、ようやくハードウェアレベルの話が始められそうです。

が、その前に…。

まえがき(いまさら?)

本シリーズの内容はPLCD1602以外にも当てはまる話も含まれますが、話が発散するので以降はPLCD1602の~みたいな書き方をします。 が、そこは適宜読み替えてください(仕様が共通しているものは他のものにも置き換えられるという話です。しかし、適宜読み替えられる人には別にこの情報必要なくない?というツラミ)

また、用語もPLCD1602/AQM1602Y-RN-GBW/ST7032i固有の名称を使うことがありますが、これも適宜読み替えてください。

あと、それなりにカッチリ書くつもりですがある程度表記ゆれや曖昧な点があるところはご容赦を。 実行の際には自己責任でよろしくお願いしますね(いつものやつ)

文字コードと字形の対応

さて、外部から字形を8つまで登録できる(外字)という話までは書きました。が、そもそもこの液晶ディスプレイはどうやってあらかじめ登録されている文字(プリセットの文字)と外字を区別しているの?という話をしていきます。

実際には、液晶の表示領域の16x2文字のそれぞれに対してどの文字コードを指定するかという観点では両者に差異はなく、「違う文字なのでアドレスが違う」というだけです(後で説明します)

登録した字とプリセットの字は文字コードとして連続した領域にあるので、登録した字を使いたいなという時はそのアドレスを指定すればプリセットの文字列と同じように使えるのです。

実は公開されているサンプルコードにヒント/答えが載っている

書きそびれていましたが、実は(?)製造元のクレイン電子さんのページにはArduino UNOでそのまま動かせるサンプルコードが載っています。

crane-elec.co.jp

コードを実行したときのPLCDの表示例の写真が載っていますが、これの上段は登録された外字が使われていていろんな記号が表示されています。

これらの文字についてはサンプルコード中段のsetup CGRAMで字形を登録して、それを表示しています。

このサンプルコードを実行するとわかりますが、右下の文字がぐるぐると順に変わっていきます。これはloop()の中のfor文の処理で登録されている字形を順に表示しています。

これが、先の「プリセットの文字と外字については文字の表示について扱い上の差異はない」ということです。

ところでこのサンプルコードですが、MITでライセンス付与されているので使いまわしがきくのも何気にありがたいですね。

…ということで、これを下地にコードを書いていくと良いのではないかと思います。ただし、データシートはちゃんと読んで各コードの意味が何かは把握しておきましょう(自戒)

え、それも書けばいい…?じゃあいずれ書きます…。

各ROM/RAMについて

さて、サンプルコードは「同じ座標で表示する文字を置き換える」ことは出来ますが、これだと動画のように1dotずつ横に文字をスクロールすることはできませんね。

しかし、次のようにやれば文字を1文字ずつ横にシフトしていくのは可能そうです。

  1. 文字座標を指定(サンプルコードの//Set Cursorの部分)して文字を書く(plcd_data()
  2. 同じ文字を文字座標を左にずらして再度文字を書く

これを繰り返せば、1文字単位ですが文字がスクロールして見えるはずです。これらの関数についてはI2Cとは何ぞやという話が必要なので、これもまたいずれ書きますか…。

では、動画のように1dotずつシフトするにはどうすればよいでしょうか?そのためには外字として登録している字形情報がPLCD(正確にはコントローラ)内でどのように扱われているのかを知る必要があります。

ようやく、ハードウェアの話っぽくなってきました(ワクワク

と、その前に写真を一枚。これがPLCDの実物で、すべてのdotを■に表示するようにしています。2段構成で横に16字分の領域、各字の間には1dotくらいの領域があり(上下はもうちょっと広い)、各字の領域は横に5dot、縦に8dotの領域があります。文字単位といった場合はこの5x8dotの領域1つ、列といった場合は2つに分かれた上下のそれぞれの単位、を指します。あとは雰囲気で…。

f:id:niszet:20210419183432j:plain

CGROM

ST7032のデータシートをご覧ください(いきなりセミナー形式かな?) なお、データシートは秋月の液晶のページからダウンロードできます。

このページにはブロック図(Block Diagram)が載っていますが、この中にCGROMとうブロックが見つかります。

ブロック図というのはこの場合、コントローラチップ(ST7032)の中の機能毎にまとまった部分をブロック(□)であらわし、データのやり取りがどの機能ブロック間で行われているかということを図示しているものです。といっても見てもよくわからんな…。

CGROMについてはp.16に字を生成するROMであることが記されています。ROMとはRead Only Memoryの略で読み取りのみの記憶領域なので、ここに登録された文字の字形は変更できません。

もう一つ、ブロック図には似た名称のCGRAMというのがあります。

CGRAM

これがつまるところ外字登録領域です。ユーザが作った字形はCGRAMというRAM(書き換え可能なメモリ)領域に書き込まれます。 これはCGROMの領域を一部間借りして使っているため、元々そこのCGROMのアドレスに登録されている字は使えません(代わりにCGRAMで作った字形が使われます)

このCGROMとCGRAMの領域についてはOPR1,2の設定に依存します(データシートのAppendix. のTable A2)が、秋月電子通商 AQM1602Y-RN-GBWのFAQを見ると、

OPR1=0、OPR2=0固定で出荷されており変更できません。

との記載があります。

akizukidenshi.com

データシートのp.57などを見るとこれらは端子としては出ているようで、それを秋月の方でGNDにつないでいるということでしょうから、他の型番の液晶を使う場合はこの設定にも注意しましょう。

DDRAM

さて、CGRAMとCGROMはひとまとまりになっているので、文字を指定する場合は文字コードにてそれらを区別することなく連続的に指定できます(PLCD1602のサンプルコード、右下で文字が変化する部分もそうなっていますね)

液晶の各文字領域に対してどの字形を表示するかを指定にするには、

  1. どの文字座標か?
  2. どの文字コードか?

をそれぞれ指定する必要があります。

画面の文字座標それぞれに対して、文字コードを保持するDisplay data RAM(DDRAM)のアドレスを紐づけることで、ある画面の座標の文字を更新したければ対応するDDRAMが持っている文字コードを変更すればよいわけで、実際にとあるDDRAMを更新すれば、それに対応した画面の文字座標の文字図形が更新されます。

画面上の文字を置き換える場合はその文字座標を指定しますが、これはアドレスカウンタ(AC)が持ちます。ACは文字を書きこむと1つ後ろにずれます。サンプルコードのfor文中で文字書き込みの前にカーソル位置を設定していますが、その座標にデータを書き込むとカーソルが隣に移動してしまうので、元の座標を指定しなおす必要があったわけですね。

余談ですが、コントローラはカーソル位置を点滅させる機能もあります(動画では非表示にしています)

画面の文字座標とDDRAMのアドレスの対応関係はデータシートのp.14以降にありますが、左上がアドレス0となっています。

さらに余談ですが、液晶自体の表示領域は2x16文字が最大ですが、コントローラとしてはもっと広い領域までもつことが出来るようで最大で80文字分をカバーします。ただしモードによってどの文字座標がどのアドレスコードになるかは変わりますので、実際に使用するモードでどのアドレスコードとなるかはデータシートを確認しましょう。これもまたサンプルコードをより詳細に説明する際にやりましょうか…。

ICON

ちなみに、ICONという領域もありますが、これは液晶画面に既にアイコン形状の表示領域があるタイプにのみ使用でき、PLCD1602にはその表示領域がない(16x2の文字表示領域しかない)のでここの値をいじっても何も起こりません(この領域は他に使えないのかと試行錯誤して無理だったので多分使いまわしできない…モッタイナイなぁ)

これの使用例は"ST7032i ICON" で検索エンジンで検索するとでてきますね。

また長くなってきたので今回はこの辺で。次回はようやく文字を1dotずつ移動させる話です。

次の記事

niszet.hatenablog.com

キャラクタLCDで文字列をスクロールするやつの解説(2回目)

フォント/字形周りの話です。

前回の記事

niszet.hatenablog.com

HWの話を先に書こうと思ったのですが、ちょっと書き出したら深みにはまって初見だと難しい話になってきたので、先にフォント/字形周りの話をします。HWの話も次回以降に。

とりあえず難しいことはさておいて、キャラクタ液晶というのは基本的にROM(読み取り専用の領域)に書かれている文字を使い、もしそこにないのであればRAM領域に字形データを登録してそれを使うということでした。

実際に文字として認識されるdotの並び、つまり字形(フォント)を全部自作しても良いのですが、それでは大変です。

なので、今回は公開されているフォントとArduinoで使用できるライブラリがないかを探し、それぞれ見つけたのでほぼそのまま利用しています。

使用したフォントとライブラリについて

フォントの話も深みにはまりそうなので、ここでは単にその字形データを扱いたいなという話に留めましょう。

フォントデータについて、個人の趣味で使うだけならあまり気にしなくても良いかもしれませんが、ライセンスまわり(利用条件)が結構ややこしいのでフリーで使えるもので、出来れば字形が高さ8bot分で収まっているもの(PLCDの液晶の文字表示領域は幅5高さ8です)がないかを探しました。

この条件に該当するのが美咲フォントでした。

littlelimit.net

私は名前は聞いたことがあるレベルでしたが、界隈?ではポケコン(ポケットコンピュータ)向けのフォントとして有名らしいですね。 なお、8x8の美咲フォント以外にもバリエーションがあり、表示領域の条件によっては他のフォントが選択肢に入るかもしれませんので見ておくと良いでしょう。今回は高さ8で良いので美咲フォントを選択します。

このフォントデータからArduino上で扱うために字形情報を取り出せば良いわけですが、これについては既にTamakichiさんのArduino向けの実装がありましたので今回はこちらを使わせていただいています。

github.com

文字データについては文字コードに対していくつか実装パタンがあるので、詳しくはGitHubリポジトリやTamakichiさんのブログを読みましょう。

nuneno.cocolog-nifty.com

注意点としては全ての字形が登録されているわけではないので所望の文字が出ない場合があります(トーフになるとのことだけど手元ではなっていない)JISの字形全部入れるとArduinoには入れられないので、他のコトもするとなるとバランスが取れている実装だなと思います。

美咲フォントは1文字あたり8x8領域を使用しますが、実際には縦横外周1行1列が真っ白なので連続して文字を表示したときにくっつかないようになっています。Tamakichiさんの実装では上1行分のデータを取り除いて読み出し時に補完しています。8x8 bitなので、ちょうどchar型で収まるというのも取り回し的には便利ですね。

が、PLCD1602は文字領域の横幅が5dotしかありません。そのため、この文字データを1文字が1文字の表示領域にそのまま送り出すと3bit分表示が出来ません。これについてはST7032iがどのように字形データを取り扱っているか?という話になるので、次回に回します。

ここではとりあえず、丁度良いフォントデータとそれをArduinoで読むライブラリがあり、入力した文字に対して対応する字形データを出すことができそうだぞ、というところまでわかればよいでしょう。

なお一応書いておきますが、今回の私の実装に関連する問い合わせについてはそれぞれの作者様ではなく私にお願いします。

余談:文字コードのツラミ

ArduinoではUTF8で文字列を扱いますが、なんと日本語の処理についてはArduinoのString等ではうまく扱えません(文字列長とか) また、文字データも連番で入っているわけではないので、ここからここまでの文字コードで対応しているよ~という処理で弾くことも出来ません。上記のライブラリは登録済みデータかどうかを文字のコードがindexに入っているかというチェックをしているため、字形データ+登録済み文字コードのデータ領域が使用されます。 手元で少しずつチェック用のコードを書いていますが、とても面倒くさい…。既に実装があれば使いたいなぁ…というお気持ち(お気持ち表明文)

ようやく概略が終わったので、次こそはHWの中の話が出来る・・・はず。

しかし、話の内容が文字のスクロールに一向に近づいている気がしないぞ…?

次の記事

niszet.hatenablog.com

キャラクタLCDで文字列をスクロールするやつの解説(1回目)

Twitterに載せたやつね

先日、Twitterで動画を公開したコレ↓について簡単に解説を書こうかなという日記。仕組みが分かってる人には面白いのだけど、そうじゃないとよくわからないよねということで。

キャラクLCDとは?

呼び名は色々あるぽいですが、文字列を表示するための液晶ディスプレイです。

これは、あらかじめ登録されている文字の字形を表示することに特化した液晶ディスプレイで、いわゆる7セグみたいな物理的に表示領域の形状が決まっているようなものと、普段我々が使っているような画像の表示が出来る液晶の中間にあたるもの、といえそうです。

あらかじめ登録されていると言っても例えばJISの字形が全部登録されているというわけではなく、今回使用したものは英数字+記号+半角カナが登録されています。(内部的には0-255の文字コードを受け取り、対応する字形を表示するというもの。この辺りはキャラクタ液晶の仕様(より正確にはコントローラICの仕様)に依存します) また、字形も変更はできません。好きなフォント(の字形)に変えるというのも出来ないわけです(ROMに書かれているので)

ただし、それでは不便でしょうということなのか、字形を登録して使うことが出来ます。ただし、8種類だけ(これも機種に依存) これによって、登録されていない字形を自分で登録し、それを使用することができる、というわけです。

詳細は、また後程。

今回使用したハードウェア

今回はArduino UNO R3とPLCD1602を使っています。

Arduino Uno R3

www.switch-science.com

PLCD1602 1.8V〜5.0V対応I2C接続LCD www.switch-science.com

HWのちょっとした説明

Arduino…の説明はいいか。PLCDの方ですが、中の液晶は秋月電子通商 AQM1602Y-RN-GBWです。そのため今回はこの仕様に依存しています。

LCDモジュール 16×2行 AQM1602Y-RN-GBW

akizukidenshi.com

なので、コントローラであるST7032iの仕様ともいえます(が、液晶側が対応していない機能があるので注意。詳しくは各データシートと販売ページのFAQなどを読んでください。たとえばこの液晶はITO option(OPR1、OPR2)について固定されています(FAQのページ))

I2Cで制御できるのも良いですね。試していませんが、同じコントローラを使用していれば同様のことがプログラムの移植で簡単にできるはずです。このあたりがI2CやArduinoのプラットフォームの強みですね。

ですが、HWの違いについては設計者がちゃんと考えてその差異をどうするかなど検討することはあります。特に気を付けないといけないのは電圧レベル(後述)ですが、それ以外にも色々…。

PLCD1602を使うメリット

PLCD1602を使ってる理由は中の人が知り合いだから…というのがきっかけですが、この製品、GroveとQwiicというインタフェースでつなげられるうえ、電圧としては1.8V-5.0Vまで対応しているという点があります。

I2C制御で簡単な液晶でも、配線の接続をしないと(当たり前ですが)動きません。コネクタ形状が決まっているGroveとQwiicであれば、つなげれば動くという点が魅力です。 しかし、どちらもコネクタ形状とどの配線が電源/GND/クロック/データかを決めていますが、電源電圧については特にケアされていないので、信号の送信側と受信側で電圧レベルが異なる場合はどちらかが壊れる可能性があります

たとえば、今回の秋月の液晶はページを見ればわかりますが、 3.3Vの対応です。素のモジュールを使う場合は気を付けましょう。

それでもまだ注意… PLCD1602を使う時の注意点

その点、PLCD1602はGrove/Qwiicの接続先を間違えなければ大丈夫です(フラグ) コネクタと配線の接続についてはPLCDの製品ページに回路図があるのでそれを参照して確認しながらつなぎましょう。データがちゃんと載ってるページは良いですね。

あと、Arduinoはピンで刺したいので、こういうケーブルが必要ですね。あるいはGrove/Qwiicに変換できるArduino用のシールドを買うかなど。

www.switch-science.com

www.switch-science.com

www.switch-science.com

長くなってきたな…。分けるか。続きます。結局、文字がスクロールするところまで説明できていない…。

次の記事

niszet.hatenablog.com

(雑記)R MarkdownでWord文書を作ろうを自宅発送に切り替えてBoothに置いています

今更の告知。

年明けくらいだったか、Boothの自宅から発送で送るのでも問題なく送れることに気づいた?ので、対応しました。 ただ、倉庫から発送でウォッチしていた方には通知が行かないと思うのでどうしたものか…。ということで今更ながら告知です。

こちらからお選びください。

niszetkoubou.booth.pm

最新の環境でチェックしていないですが、多分動く…と思う。あと考え方についてはそのまま使えますので、見てみてください。

後わかんなかったらBoothのDMなどで聞いていただければ…。あるいはPandocのSlackとかでも。

(Pandoc) Pandocのtest時に出るエラーメッセージについて(開発者向けメモ)

まずは過去issueを検索しろって言うよね。それね。

Pandoc はstack testでテストが一式走るので、手元でFAILが出ないことを確認してからcommitします(当たり前だ…)

が、test時のlogを見るとこんなメッセージが。

Error: Circular defaults file reference in 'command/defaults7.yaml'

気になったので聞いてみたんですが、ちょっと調べてみると

github.com

github.com

で議論済みの内容でした。ちゃんと調べようね…。

ということでとりあえず無視して良さそうですし、これが出ているからFAILが出るという事もなさそうです(現に7185はテスト追加してもall PASSでマージ済) ビルドに時間かかるけど、ちゃんとtestで全てPASSすることを確認してからcommitしようね。

明日から放送大学

書いてなかったので

そんなわけで、明日から?放送大学で専科履修生としてやっていきます。 やっていきますと言ってもどうやっていくのかまだよくわかってない気がするけども…。

色々あり、情報系の大学院に社会人大学院生として入ろうと思っていた時期があったんですが、基礎的なことが分かってないことがわかり、学部レベルからやるべきだろうと考え直し、一方で放送大学は文系科目も多く自分に足りない分野の知識を吸収する良いタイミングかなということで、特に卒業を目指すわけではなくしかし単位としてはちゃんと取れることを指標としてちゃんと習得していこうということでこのような形にしてみました。

履修登録時にうっかり試験時間が同じ科目を登録したので一個予定より少ないですが…。

まずは勉強の習慣づけからですかね…。

いやその前に生活リズムを規則正しくしないとダメかな。

とにかく、色々と新しい気持ちで明日からやっていこう、そういう決意の日記でした。

(Pandoc) ODT Readerでtabが無視される問題の対応をしています

PRは出した。

元になるissueはこれ。

github.com

これによると、ODTを入力ファイルとしたときにtabが全部無視されてしまうということでした。

コードを読んで対応する場所がわかったのでいじってたら出来たのでPRを出しました。

github.com

年度末なので(なのか?)jgm氏が不在期間なのでマージはしばらく先かなーという感じですが、多分これで問題は解決です。良かったよかった(予定)