前回の行入力ルーチンの改良をするつもりが、Xiao-ESP32C3のブレッドボードの整理(SDスロットとカラーLCDを並べて載せる)に時間とってしまい、ソフトの改良は「僅か」であります。でも、とりあえずカーソルを左右に動かして上書き編集と、以下消去くらいはできるようになりました。行入力っぽくなってきた?
※「IoT何をいまさら」投稿順Indexはこちら
SDスロットとカラーLCDは並べただけ、ソフトは要切替
冒頭にアイキャッチ画像掲げましたが、SDカードのスロットとからーLCDのI/Fを並べて載せてXiao-ESP32C3と接続してみました。ただし、両方が一本のSPIにぶら下がっていて、SPIの設定条件が異なるなので、今のところソフトウエアで切り替えた方を使える、というおとぼけな接続です。まあ、おいおい手を入れて両方使えるような雰囲気を出していきたいと思います。
「行入力、readlineもどき」の改良
VT100互換の制御シーケンスに対応している仮想端末ソフト(TeratermProなど)でXiaoのUSBシリアルに接続したときに使える readlineモドキを前回から作り始めてます。前回は文字列を入力することと、BSキーで末尾の1文字を削れるだけのものでした。今回は以下追加しました。
-
- カーソル移動。CTRL+Bで左、CTRL+Fで右、CTRL-Aで行頭、CTRL-Eで行末にカーソル移動
- カーソル位置にある文字を上書きできる
- 行末にカーソルがあるときのみBSキーによる一文字左削除(前回と同じ)
- 行の途中にカーソルがあるとき、CTRL+Dでカーソルから行末まで削除
ちょいとは行編集ぽくなって来た?
前回から変更したコード部分が以下に。
void leftCursor() { Serial.print((char)0x1B); Serial.print('6'); } void rightCursor() { Serial.print((char)0x1B); Serial.print('9'); } void saveCursor() { Serial.print((char)0x1B); Serial.print('7'); } void restoreCursor() { Serial.print((char)0x1B); Serial.print('8'); } bool blockingReadLine(char *buf, const int maxBuf) { char bufIndex = 0; char bufUsed = 0; char selchar = 0; const int tcMax = 3; const char term[tcMax] = {0x3, 0xA, 0xD}; while (!endOfLineChar(selchar, term, tcMax)) { selchar = blgetASCII(0); if (selchar == 0x08) { //BS key if ((bufIndex > 0) && (bufUsed == bufIndex)) { bufIndex--; bufUsed--; Serial.print(selchar); Serial.print(' '); } else { selchar = 0; } } else if (selchar == 0x1) { //CTRL+A (start of line) Serial.print('\r'); selchar = 0; bufIndex= 0; } else if (selchar == 0x2) { //CTRL+B (left) if (bufIndex >0) { leftCursor(); bufIndex--; } selchar = 0; } else if (selchar == 0x6) { //CTRL+F (right) if (bufIndex < bufUsed) { rightCursor(); bufIndex++; } selchar = 0; } else if (selchar == 0x5) { //CTRL+E (end of line) while (bufIndex < bufUsed) { rightCursor(); bufIndex++; } selchar = 0; } else if (selchar == 0x4) { //CTRL+D (delete right..EOL) char temp = bufIndex; saveCursor(); while (bufIndex < bufUsed) { Serial.print(' '); bufIndex++; } restoreCursor(); bufIndex = temp; bufUsed = temp; selchar = 0; } else if (bufIndex < (maxBuf+1)) { buf[bufIndex++] = selchar; if (bufIndex > bufUsed) { bufUsed = bufIndex; } } if (selchar != 0) { Serial.print(selchar); } } buf[bufUsed] = '\0'; if (selchar == 0x3) { return false; } return true; }
なお、上記のルーチンでは矢印キーを押すとカーソルが動いてしまいますが、それは正常に処理できてないです。処理できるのはCTRLキーを押しながら文字キーを押した場合のみ。編集キーには未対応です。
先は長いのう。