常時稼働のLinuxサーバーを使って音楽を聴いたりするために,以前「USB接続カラーグラフィックLCDによる自宅サーバの活用」(初代)でグラフィックLCDとスイッチでLinuxをコントロールできるようにしましたが,見栄えがいまいちだったので「カラーグラフィックLCDを使用したLinux用小型端末」(二代目)を作りましたが,数年間使用してLCDが故障したのでAndroid Watchに自作のプログラム(三代目)を入れて使っていましたが,それもバッテリーの寿命が来て動かなくなってしまいました.そこで,四代目となるものを作成することにしました.できるだけ長く使えるように未使用時はスリープ状態に入ってLCDの電源をオフにして寿命をのばすようにしました.またこれまで作成した端末はLinux側でフォント情報を持ちビットマップをLCDに転送する構成にしたため,ハードウェアはシンプルである一方でLinux側に専用のドライバが必要でしたが,今回はLinux側からは単純なRS-232C接続(USB CDC)の端末として見えてドライバー等は一切必要のない構成としました.
マイコンには,USB端子を持ちSTM32を搭載したBlue Pillを使いArduinoでファームウェアの開発を行いました.LCDには,ST7789というコントローラーを搭載し1.3インチと小型ながら240x240と解像度の高いものを使いました.このくらい解像度があると16x16ドットの漢字フォントを使いたいですが,フォントをBluepillに乗せるにはフラッシュROMの容量が足りないので,日本語フォントROMのGT20L16J1Yを使いました.回路の構成は簡単なので,回路図は書かずに下記の端子間の結線を空中配線で行いました.
Blue Pill:G | LCD:GND |
Blue Pill:A1 | LCD:VCC |
Blue Pill:A5 (SCK1) | LCD:SCL |
Blue Pill:A7 (MOSI1) | LCD:SDA |
Blue Pill:A3 | LCD:RES |
Blue Pill:A6 (MISO1) | LCD:DUMMY |
Blue Pill:A2 | LCD:DC |
Blue Pill:B13 (SCK2) | ROM:SCLK (1) |
Blue Pill:G | ROM:GND (2) |
Blue Pill:B12 (SS2) | ROM:CS# (3) |
Blue Pill:A8 | ROM:VCC (4) |
Blue Pill:B14 (MISO2) | ROM:SO (5) |
Blue Pill:B15 (MOSI2) | ROM:SI (6) |
Blue Pill:B4 | Switch:0 (右) |
Blue Pill:B5 | Switch:1 |
Blue Pill:B6 | Switch:2 |
Blue Pill:B7 | Switch:3 (左) |
漢字フォントROMの都合のため,この端末の入力文字コードはEUC-JPとしました.Linux側では多くの場合UTF-8を使いたいので,cocotを使ってLinuxのプロセスと端末間で文字コードの変換を行います.この端末は以下のエスケープシーケンスを認識することができます.
エスケープシーケンス | 機能 |
\x01 x | カーソルのx座標を(x - 32)に設定. |
\x02 y | カーソルのy座標を(y - 32)に設定. |
\x03 c | 文字色を(c - 32)に設定. |
\x04 c | 背景色を(c - 32)に設定. |
\x11 k | 1番目のキーが押された時に送信する文字をkに設定(デフォルトは'h'). |
\x12 k | 2番目のキーが押された時に送信する文字をkに設定(デフォルトは'j'). |
\x13 k | 3番目のキーが押された時に送信する文字をkに設定(デフォルトは'k'). |
\x14 k | 4番目のキーが押された時に送信する文字をkに設定(デフォルトは'l'). |
\x07 (^G) | 1行上に移動する(逆ラインフィード) |
\x08 (^H) | 直前に1文字を消す(バックスペース). |
\x0a (^J) | 1行下に移動する(ラインフィード). |
\x0b (^K) | カーソル位置から行末までを削除する. |
\x0d (^M) | 行頭へ移動する(キャリッジリターン). |
\x0e (^N) | カーソル位置から最終行の行末までを削除する. |
今回作った端末は,ボタンを押すと文字コードが出力されて,文字コードが入力されるとそれをLCDに出力するという一般的な端末として動作するので,Linux上ではagettyでこの端末を待ち受けて自作のファイルマネージャーをシェルとして起動するように設定しました.
# systemctl edit 'getty@ttyACM0' [Service] ExecStart= ExecStart=-/sbin/agetty -n -l /usr/local/lib/lcdfm/lcdfm.sh 115200 ttyACM0 # systemctl enable 'getty@ttyACM0.service' # systemctl start 'getty@ttyACM0.service'
このファイルマネージャーは以前作ったものを少し改良しました.ケースは3Dプリンターで作成しました.