M5Stack Core2でなかなか出来なかったSDファイル入出力が出来たのでまとめておく。
副産物として、Gifアニメーション的な画像のペラペラ動画をやってみます。
SDファイル取得
このコードはスケッチのまんま動きました。
しかし、この出力に以下のファイル入出力のヒントが書かれていました。
以下は、気象衛星画像を取り込んだSDです。
これは、ファイル名の前に”/”がついています。
また、他の画像表示用のSDも以下のように"/"がついています。
/System Volume Information/
/System Volume Information/WPSettings.dat 12
/System Volume Information/IndexerVolumeGuid 76
/datalog.txt.txt 0
/jpn_trm_20210715061000.jpg 147774
/jpn_trm_20210715062000.jpg 148171
/jpn_b13_20210715062000.jpg 180546
/jpn_snd_20210715062000.jpg 230045
/jpn_trm_20210715063000.jpg 148581
/jpn_snd_20210715063000.jpg 227143
/jpn_trm_20210715091000.jpg 102250
/jpn_trm_20210715092000.jpg 95142
done!
。。。
/System Volume Information/
/System Volume Information/WPSettings.dat 12
/System Volume Information/IndexerVolumeGuid 76
/1.JPG 3589
/2.JPG 3140
done!
サンプルコード
/*
Listfiles
This example shows how print out the files in a
directory on a SD card
The circuit:
SD card attached to SPI bus as follows:
** MOSI - pin 11
** MISO - pin 12
** CLK - pin 13
** CS - pin 4 (for MKRZero SD: SDCARD_SS_PIN)
created Nov 2010
by David A. Mellis
modified 9 Apr 2012
by Tom Igoe
modified 2 Feb 2014
by Scott Fitzgerald
This example code is in the public domain.
*/
# include <SPI.h>
# include <SD.h>
File root;
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(115200);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.print("Initializing SD card...");
if (!SD.begin(4)) {
Serial.println("initialization failed!");
while (1);
}
Serial.println("initialization done.");
root = SD.open("/");
printDirectory(root, 0);
Serial.println("done!");
}
void loop() {
// nothing happens after setup finishes.
}
void printDirectory(File dir, int numTabs) {
while (true) {
File entry = dir.openNextFile();
if (! entry) {
// no more files
break;
}
for (uint8_t i = 0; i < numTabs; i++) {
Serial.print('\t');
}
Serial.print(entry.name());
if (entry.isDirectory()) {
Serial.println("/");
printDirectory(entry, numTabs + 1);
} else {
// files have sizes, directories do not
Serial.print("\t\t");
Serial.println(entry.size(), DEC);
}
entry.close();
}
}
サンプルコード
/*
SD card read/write
This example shows how to read and write data to and from an SD card file
The circuit:
SD card attached to SPI bus as follows:
** MOSI - pin 11
** MISO - pin 12
** CLK - pin 13
** CS - pin 4 (for MKRZero SD: SDCARD_SS_PIN)
created Nov 2010
by David A. Mellis
modified 9 Apr 2012
by Tom Igoe
This example code is in the public domain.
*/
# include <SPI.h>
# include <SD.h>
File myFile;
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(115200);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.print("Initializing SD card...");
if (!SD.begin(4)) {
Serial.println("initialization failed!");
while (1);
}
Serial.println("initialization done.");
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
myFile = SD.open("/test.txt", FILE_WRITE); //add "/"
// if the file opened okay, write to it:
if (myFile) {
Serial.print("Writing to test.txt...");
myFile.println("testing 1, 2, 3.");
// close the file:
myFile.close();
Serial.println("done.");
} else {
// if the file didn't open, print an error:
Serial.println("error opening test.txt");
}
// re-open the file for reading:
myFile = SD.open("/test.txt"); //add "/"
if (myFile) {
Serial.println("test.txt:");
// read from the file until there's nothing else in it:
while (myFile.available()) {
Serial.write(myFile.read());
}
// close the file:
myFile.close();
} else {
// if the file didn't open, print an error:
Serial.println("error opening test.txt");
}
}
void loop() {
// nothing happens after setup
}
Initializing SD card...initialization done.
Writing to test.txt...done.
test.txt:
testing 1, 2, 3.
画像入力
このコードはload-jpeg-coreのサンプルです(入手先を失念)。
しかし、オリジナルは上と同様"/"が無いので動きませんが、追加で動きます。
サンプルコード
//#include <M5Stack.h>
# include <M5Core2.h>
# define PROGRESS_MAX 100
static unsigned char gucProgress = 0;
static unsigned char gucOpenFlg = 0;
void setup() {
// M5Stackの初期化
M5.begin();
// テキストサイズ指定
M5.Lcd.setTextSize(2);
// OK
M5.Lcd.setCursor(60, 80);
M5.Lcd.printf("Now Loading...");
}
void loop() {
gucOpenFlg = 0;
// プログレスが100%まで表示を行う
if( PROGRESS_MAX >= (gucProgress * 20) )
{
// プログレスバー表示完了
M5.Lcd.progressBar(60, 110, 200, 20,(20 * gucProgress));
gucProgress++;
}
else
{
// ロゴ未表示
if( 0 == gucOpenFlg)
{
// m5stackロゴ表示
M5.Lcd.printf("Now drawing...");
M5.Lcd.drawJpgFile(SD,"/1.jpg");
M5.Lcd.printf("Finished...");
// ロゴ表示
gucOpenFlg = 1;
}
}
delay(1000);
}
}
サンプルコード
//#include <M5Stack.h>
# include <M5Core2.h>
# define PROGRESS_MAX 100
static unsigned char gucProgress = 0;
static unsigned char gucOpenFlg = 0;
void setup() {
// M5Stackの初期化
M5.begin();
// テキストサイズ指定
M5.Lcd.setTextSize(2);
// OK
M5.Lcd.setCursor(60, 80);
M5.Lcd.printf("Now Loading...");
}
int sk=0;
void loop() {
gucOpenFlg = 0;
// プログレスが100%まで表示を行う
if( PROGRESS_MAX >= (gucProgress * 20) )
{
// プログレスバー表示完了
M5.Lcd.progressBar(60, 110, 200, 20,(20 * gucProgress));
gucProgress++;
}
else
{
// ロゴ未表示
if( 0 == gucOpenFlg)
{
// m5stackロゴ表示
//M5.Lcd.printf("Now drawing...");
if(sk%2>0){
M5.Lcd.drawJpgFile(SD,"/1.jpg"); //"/jpn_trm_20210715061000.jpg"); //"/1.jpg");
}else{
M5.Lcd.drawJpgFile(SD,"/2.jpg"); //"/jpn_trm_20210715061000.jpg"); //"/1.jpg");
}
//M5.Lcd.printf("Finished...");
// ロゴ表示
gucOpenFlg = 1;
}
}
sk += 1;
delay(int(1000/sk));
if(sk>1000){
sk = 0;
}
}
結果は、以下の感じです。
SDカード利用したペラペラ動画が出来ました‼️
— ウワン (@MuAuan) July 19, 2021
今は画像二枚ですが、高速に動くので使えそうです
qiitaに本日まとめる予定です#M5Stack #Core2 pic.twitter.com/PsvzeVVE09
SD読込みアニメーション
上のコードはこのままではファイル名が単純な整数配列であっても単純な繰り返しを記述しないといけない。
Pythonでは、.formatが利用できてすぐに表現出来たが、C言語では簡単ではなさそう。
しかし、少し探してみると参考が見つかりました。
おかげでコードもシンプルになりました。
参考
【C言語入門】文字列の連結・分割(strcat、strtok)
これを利用して以下でうまく出来ました。
サンプルコード
//#include <M5Stack.h>
# include <M5Core2.h>
# define PROGRESS_MAX 100
# include <stdlib.h>
# include <string.h>
# include <stdio.h>
static unsigned char gucProgress = 0;
static unsigned char gucOpenFlg = 0;
char *arr3[10] = {"0", "1","2","3","4","5","6","7","8","9"};
char *arr2=".jpg";// png
char str3[30];
void setup() {
// M5Stackの初期化
M5.begin();
// テキストサイズ指定
M5.Lcd.setTextSize(2);
// OK
M5.Lcd.setCursor(60, 80);
M5.Lcd.printf("Now Loading...");
printf("\n");
}
int sk=0;
void loop() {
gucOpenFlg = 0;
// プログレスが100%まで表示を行う
if( PROGRESS_MAX >= (gucProgress * 20) )
{
// プログレスバー表示完了
M5.Lcd.progressBar(60, 110, 200, 20,(20 * gucProgress));
gucProgress++;
}
else
{
// ロゴ未表示
if( 0 == gucOpenFlg)
{
sprintf(str3, "/%s%s", arr3[sk%2], arr2);
M5.Lcd.drawJpgFile(SD,str3); // M5.Lcd.drawPngFile(SD,str3);
gucOpenFlg = 1;
}
}
sk += 1;
delay(1);
}
一応、動画と云えるかな🎵#M5Stack SD読込み動画 pic.twitter.com/pWqgq3u0Qd
— ウワン (@MuAuan) July 19, 2021
表示の参考は、以下にありますが、引数がうまくいきませんでした。
LCD@Core2
まとめ
・SD読み書きが出きるようになった
・SDの画像ファイルを読み込めるようになった
・ペラペラ動画をやってみた
・これとESPnow(近日まとめます)を合わせると、Stack兄弟の動作連携が出来る予定