arduinoで憧れのGUI表示(表示のみ)を試してみた。
arduinoを今風のPCみたいに
GUI表示させたい。と思い、
今までいろいろな記事を書いてきました。
FONTX2形式をESP32のmicropythonで扱う
https://miha.jugem.cc/?eid=367
arduinoで漢字を扱う準備
https://miha.jugem.jp/?eid=396
SJIS変換テーブルの記事
https://miha.jugem.cc/?eid=397
SPI接続のカラーLCDの記事(ILI9328)
https://miha.jugem.cc/?eid=111
arduinoに512Kバイトの漢字ROM等を増設する方法
https://miha.jugem.jp/?eid=395
これらをつなぎ合わせてGUI風に表示するプログラムを
作ってみました
結果的には昔のテキスト版のアドベンチャーゲームみたいな
雰囲気になってしまいました。
https://youtu.be/XJSQ4KoNolw
これが以下のような簡単なプログラムで表示できるようになります。
DispColor(MakeColorGray(3));
//テキスト表示
showTftUTF8(0, 0, "吾輩は猫である", COLOR_BLUE);
showTftUTF8(0, 1, "吾輩は猫でなし", COLOR_RED,SHOW_DOUBLE);
showTftUTF8(0, 6, "1234567890ABCabcアイウ!#$♡", COLOR_WHITE);
//ベースの箱
// (x y 幅 高 色) 左下が起点
BoxFill(0, 120, 240, 200, MakeColorGray(16));
//警告ダイアログ
BoxFill(20, 148, 212, 160, MakeColorGray(24));
BoxFill(20, 288, 212, 20, COLOR_BLUE);
showTftUTF8(3, 18, "警告", COLOR_RED,SHOW_NORMAL);
showTftUTF8(3, 15, "吾輩は猫である。", COLOR_RED,SHOW_NORMAL);
showTftUTF8(3, 14, " あなたにも、この後", COLOR_RED,SHOW_NORMAL);
showTftUTF8(3, 13, " 猫になってもらいます", COLOR_RED,SHOW_NORMAL);
//ボタン
Button(9, 11, "了承", true);
Button(19, 11, "断る", false);
以下は手順
arduinoIDEはUTF8でプログラムを記述する関係で
SJISに変換する必要があります。
https://miha.jugem.cc/?eid=397
を参考にして変換テーブルを準備します。
用意するもの全角用と半角用のFONTを準備
https://miha.jugem.jp/?eid=396
を参考にして上記の変換テーブルと一緒に
SDカードに記録しておきます。
この時点でのSDカードの中身
Convert.dat
ILGH16XB.FNT
ILGZ16XF.FNT
※こちらのフォントはIPAが作成したものを
こばこのひみつ
さんでFONTX形式にしたものです。
http://ayati.cocolog-nifty.com/blog/2012/08/ipalx322416-64a.html
IPAのページ
https://moji.or.jp/ipafont/ipafontdownload/
FONTX形式フォントのダウンロード
http://www.ayati.com/LX/ILFONT03.zip
SDから読み込んでROM化する。
パソコンからEEPROMへ直接書き込めないので、
Arduinoで専用プログラムを書いて実行します。
EEPROMは512Kバイト 0x00000~0x70000の連続領域
メモリマップ
0x00000-4ffff ILGZ16XF.FNT
0x50000-5ffff ILGH16XB.FNT
0x60000-6ffff CONVERT.DAT
SDカードの接続
MOSI - D11
MISO - D12
CLK - D13
CS - D4
EEPROM(25FC1025)接続
参照
https://miha.jugem.cc/?eid=395
https://img-cdn.jg.jugem.jp/85e/51887/20241122_3600138.png
ROM化プログラム(_99.writeKanjiROM-R1.ino)
要点のみ抜粋(WriteFC1025についてはhttps://miha.jugem.cc/?eid=395参照)
FileToMemoryを3回呼び出してEEPROMへ書き込みます。
FileToMemory("CONVERT.DAT", 0x60000);
FileToMemory("ILGZ16XF.FNT", 0x00000);
FileToMemory("ILGH16XB.FNT", 0x50000);
int FileToMemory(char *szFileName, uint32_t address)
{
File f = SD.open(szFileName, FILE_READ);
if (!f) {
Serial.print(szFileName);Serial.println(" error SD.open");
return -1;
}
while(1){
if(!f.available()){
break;
}
char buf[32];
uint32_t n = f.read(buf, 32);
//Serial.print("read-byte=");Serial.println(n);
int nRc = WriteFC1025(address, buf, n); //メモリ書き込み
if(nRc!=0){
Serial.println("error WriteFC1025");
}
Serial.print("address=");Serial.println(address, HEX);
address = address + n;
}
f.close();
return 0;
}
ROMから文字関連データを読み込む様に改造する。(_99.TFT-SPI-KANJI-R2.ino)
過去記事https://miha.jugem.cc/?eid=396
つまり、上記過去記事はSDからFONTや変換テーブルの読み取りを
していますので、
fseekとreadの所を中心に書き換えればOKです。
読み込み関数はReadFC1025で過去記事https://miha.jugem.jp/?eid=395
で作成したものです。
メモリなのでopenとcloseは不要になりますからメインメモリの節約にもなります。
LCDに表示する。(_99.TFT-SPI-KANJI-R2.ino)
過去記事https://miha.jugem.cc/?eid=111
を参考にしてROMから取得してきたビット情報を
drawPixel関数でLCDに表示してやるのみです。
抜粋 drawPixel呼ぶ所
void showTftFONT(int col, int row, char *font_buf, int font_size, int width, int color, int bairitu=SHOW_NORMAL)
{
int x=0;
int y=0;
for(int i=0;i<font_size;i++){
uint16_t bit = font_buf[i];
for(int b=0;b<8;b++){
if(bit & 128){
drawPixel(col*8+x, row*16+16-y, color);
x++;
}
else{
x++;
}
bit = bit << 1;
}
if ((i+1) % int((width + 7) / 8) == 0){
x=0;
y++;
}
}
}
まあまあ、遅いですね。それがまたいい雰囲気出してます。
LCDの表示がおそらくはもっといい方法が有ると思うのですが、
2016年当時アイテンドーさんから入手してきたものを
結構な無理矢理感あるプログラムで動かしていますからね。
今やるならILI9341で、adafruitの専用ライブラリ使えれば
だいぶ早くなるんでしょうけど。今回は手持ちパーツという事で
次の機会に取っておきます。
今回の関連プログラム置き場
https://drive.google.com/file/d/1m759pW3nJRycYfg2ADz_a_mMqz396NeQ/view?usp=sharing