07.M5PaperS3でメニューtest
07.M5PaperS3でメニューtest
説明
次のブログで使用するための、メニュー画面を表示するだけのスケッチです。タッチで4変数を選択でき、SDのファイルも選択できるはずです。ただし、ファイルは、SDの
・ルートにあるファイル
・8.3形式のファイル
・9ファイル以下
の制約があります。
スケッチ
// メニュー画面 960x540
// 各種設定とルートファイル(8.3)を選択
#include <SD.h> // SDを使用
File root; // Fileのインスタンスを作成
#include <epdiy.h> // 電子ペーパードライバー
#include <M5GFX.h> // M5Stack用グラフィックライブラリ
M5GFX display; // M5GFXのインスタンスを作成
#define SD_SPI_CS_PIN GPIO_NUM_47 // SDのpin
#define SD_SPI_SCK_PIN GPIO_NUM_39 // SDのpin
#define SD_SPI_MOSI_PIN GPIO_NUM_38 // SDのpin
#define SD_SPI_MISO_PIN GPIO_NUM_40 // SDのpin
bool edpQ = false; // (true)高品質or(false)高速
bool gamenTate = true; // 画面(true)縦or(false)横
int16_t fontS = 32; // fontサイズ (32or36px)
int16_t gyoukan = 10; // 行間px
int16_t menuDY = 70; // メニュー画面刻みpx
String fList[20][2]; // [n][fName,fByte]
lgfx::touch_point_t tp[1]; // タッチポイント
void SetFont() { // Font等初期化関数
display.init(); // パネルの初期化
if (display.isEPD()) { // e-Paper displayなら
display.setEpdMode(epd_mode_t::epd_fastest); // 描画速いが、低品質に設定
}
display.setRotation(0); // 縦長に回転
//display.setRotation(1); // 横長に回転
display.fillScreen(TFT_WHITE); // 全画面白
display.setFont(&fonts::lgfxJapanGothic_32); // 固定幅ゴシック体 8,12,16,20,24,28,32,36,40
display.setTextColor(TFT_BLACK, TFT_WHITE); // (字,地)
display.setTextSize(1); // 文字サイズの倍数 1-7
display.setTextWrap(true, true); // 自動折返し(x,y)
display.setCursor(0, 0); // カーソル位置
display.setAutoDisplay(0); // 書込後即描画しない
}
void setup() {
SPI.begin(SD_SPI_SCK_PIN, SD_SPI_MISO_PIN,
SD_SPI_MOSI_PIN, SD_SPI_CS_PIN);
delay(100); // 0.1秒待つ
SetFont(); // Font等初期化関数へ
Serial.begin(115200); // シリアル通信を開始し、ポートが開くのを待つ:
if (!SD.begin(47)) { // SDライブラリとカードを初期化できなければ
Serial.println("失敗 SDライブラリ初期化"); // 表示
while (true) // 無限ループ
;
}
// -------------------------------- ファイル名取得
root = SD.open("/"); // ルートのファイルを開く
char buf[40]; // 作業用
int8_t i = 0;
while (true) { // breakになるまで無限ループ
File entry = root.openNextFile(); // ディレクトリ内の次のファイルまたはホルダを取得
if (!entry) break; // 次のファイルまたはフォルダがないなら抜ける
if (!entry.isDirectory()) { // ホルダでなければ
fList[i][0] = String(entry.name()); // ファイル名を取得
if (entry.size() < 1000) { // ファイルサイズが1kB未満なら
sprintf(buf, " %5dB\n", entry.size()); // bufにファイルサイズ(bytes)を
} else { // 1kB以上なら
sprintf(buf, " %4dkB\n", entry.size() / 1000); // Bufにファイルサイズ(kB)を
}
fList[i][1] = String(buf); // ファイルサイズ(B or kB単位)
i++; // 次のファイル番号
}
entry.close(); // ファイルを閉じる
}
}
void loop() {
// -------------------------------- メニュー1行目セット
int16_t menuX = 0, menuY = 20; // カーソル変数
display.setCursor(menuX, menuY); // カーソル位置
if (edpQ == 1) { // 高品質画面なら
display.print(" 品質・速度 : "); // 表示をセット
display.setTextColor(TFT_WHITE, TFT_BLACK); // (字,地)
display.print("高品質"); // 表示をセット
display.setTextColor(TFT_BLACK, TFT_WHITE); // (字,地)
display.print(" 高速"); // 表示をセット
} else { // 高速画面なら
display.print(" 品質・速度 : 高品質 "); // 表示をセット
display.setTextColor(TFT_WHITE, TFT_BLACK); // (字,地)
display.print("高速"); // 表示をセット
display.setTextColor(TFT_BLACK, TFT_WHITE); // (字,地)
}
// -------------------------------- メニュー2行目セット
menuY += menuDY; // 次の行へ
display.setCursor(menuX, menuY); // カーソル位置
if (gamenTate == 1) { // 縦画面なら
display.print(" 画面向き : "); // 表示をセット
display.setTextColor(TFT_WHITE, TFT_BLACK); // (字,地)
display.print("縦向き"); // 表示をセット
display.setTextColor(TFT_BLACK, TFT_WHITE); // (字,地)
display.print(" 横向き"); // 表示をセット
} else { // 横画面なら
display.print(" 画面向き : 縦向き "); // 表示をセット
display.setTextColor(TFT_WHITE, TFT_BLACK); // (字,地)
display.print("横向き"); // 表示をセット
display.setTextColor(TFT_BLACK, TFT_WHITE); // (字,地)
}
// -------------------------------- メニュー3行目セット
menuY += menuDY; // 次の行へ
display.setCursor(menuX, menuY); // カーソル位置
if (fontS == 32) { // fontサイズが32pxなら
display.print(" Font Size : "); // 表示をセット
display.setTextColor(TFT_WHITE, TFT_BLACK); // (字,地)
display.print("32px"); // 表示をセット
display.setTextColor(TFT_BLACK, TFT_WHITE); // (字,地)
display.print(" 36px"); // 表示をセット
} else { // fontサイズが36pxなら
display.print(" Font Size : 32px "); // 表示をセット
display.setTextColor(TFT_WHITE, TFT_BLACK); // (字,地)
display.print("36px"); // 表示をセット
display.setTextColor(TFT_BLACK, TFT_WHITE); // (字,地)
}
// -------------------------------- メニュー4行目セット
menuY += menuDY; // 次の行へ
display.setCursor(menuX, menuY); // カーソル位置
if (gyoukan == 5) { // 行間が5pxなら
display.print(" 行間(px) : "); // 行間px
display.setTextColor(TFT_WHITE, TFT_BLACK); // (字,地)
display.print("05"); // 表示をセット
display.setTextColor(TFT_BLACK, TFT_WHITE); // (字,地)
display.print(" 10 15"); // 表示をセット
} else if (gyoukan == 10) { // 行間が10pxなら
display.print(" 行間(px) : 05 "); // 表示をセット
display.setTextColor(TFT_WHITE, TFT_BLACK); // (字,地)
display.print("10"); // 表示をセット
display.setTextColor(TFT_BLACK, TFT_WHITE); // (字,地)
display.print(" 15"); // 表示をセット
} else { // 行間が15pxなら
display.print(" 行間(px) : 05 10 "); // 表示をセット
display.setTextColor(TFT_WHITE, TFT_BLACK); // (字,地)
display.print("15"); // 表示をセット
display.setTextColor(TFT_BLACK, TFT_WHITE); // (字,地)
}
// -------------------------------- ファイル名セット
menuY += menuDY; // 次の行へ
String fName; // ファイル名
for (int8_t i = 0; i < 9; i++) { // 9ファイルまで表示
display.setCursor(menuX, menuY); // カーソル位置
display.printf("%3d ", i + 1); // ファイル番号セット
fName = fList[i][0] // ファイル名
+ " "; // 9文字空白追加
fName = fName.substring(0, 12); // 頭から12文字
display.print(fName); // ファイル名セット
display.print(fList[i][1]); // ファイルサイズセット
menuY += menuDY; // 次の行へ
}
// -------------------------------- 罫線セット 960x540
for (int8_t i = 1; i < 5; i++) { // 水平線上4本
display.drawFastHLine(0, menuDY * i, 540, TFT_BLACK);
}
for (int8_t i = 5; i < 13; i++) { // 水平線下8本
display.drawFastHLine(0, menuDY * i, 400, TFT_BLACK);
}
display.drawFastVLine(335, 0, 210, TFT_BLACK); // 垂直線上3行
display.drawFastVLine(285, 210, 70, TFT_BLACK); // 4行目左
display.drawFastVLine(420, 210, 70, TFT_BLACK); // 4行目右
display.drawFastVLine(400, 280, 680, TFT_BLACK); // 垂直線下ファイル行
// -------------------------------- 文字セット
display.setCursor(450, 500); // カーソル位置
display.print("戻"); // 表示をセット
display.setCursor(450, 600); // カーソル位置
display.print("る"); // 表示をセット
display.display(); // セットを表示
// -------------------------------- タッチ判定
bool drawed = false; // 描画変数=描画していない
if (display.getTouchRaw(tp, 1)) { // タッチ情報を取得
drawed = true; // 描画した
if (tp[0].y < 70) { // 1行目なら
if (tp[0].x < 335) { // 左側なら
edpQ = 1; // 高品質
} else { // 右側なら
edpQ = 0; // 高速
}
} else if (tp[0].y < 140) { // 2行目なら
if (tp[0].x < 335) { // 左側なら
gamenTate = 1; // 縦向き
} else { // 右側なら
gamenTate = 0; // 横向き
}
} else if (tp[0].y < 210) { // 3行目なら
if (tp[0].x < 335) { // 左側なら
fontS = 32; // 32px
} else { // 右側なら
fontS = 36; // 36px
}
} else if (tp[0].y < 280) { // 4行目なら
if (tp[0].x < 285) { // 左側なら
gyoukan = 5; // 行間5px
} else if (tp[0].x < 420) { // 中央なら
gyoukan = 10; // 行間10px
} else { // 右側なら
gyoukan = 15; // 行間15px
}
} else if (tp[0].x > 400) { // 5行目以下の右なら
// 戻る
} else if (tp[0].y < 350) { // 5行目のfile1なら
fName = fList[1][0]; // file1
} else if (tp[0].y < 420) { // 6行目のfile2なら
fName = fList[2][0]; // file2
} else if (tp[0].y < 490) { // 7行目のfile3なら
fName = fList[3][0]; // file3
} else if (tp[0].y < 560) { // 8行目のfile4なら
fName = fList[4][0]; // file4
} else if (tp[0].y < 630) { // 9行目のfile5なら
fName = fList[5][0]; // file5
} else if (tp[0].y < 700) { // 10行目のfile6なら
fName = fList[6][0]; // file6
} else if (tp[0].y < 770) { // 11行目のfile7なら
fName = fList[7][0]; // file7
} else if (tp[0].y < 840) { // 12行目のfile8なら
fName = fList[8][0]; // file8
} else { // 13行目のfile9なら
fName = fList[9][0]; // file9
}
} else if (drawed) { // もし描画していれば
drawed = false; // 描画変数を戻す
}
vTaskDelay(1); // 1tickの間タスクをブロック
}
* flash memory(1.3Mbyte)のうち、スケッチが71%使用。RAM(327kbyte)のうち、global変数が6%使用、local変数で306kbyte使用可能。(1000byte=1kbyteで計算)