こんにちは、ENGかぴです。
ESP32シリーズのFLASHにファイルをアップロードする方法として、SDカードライブラリとSPIFFSライブラリを使用する方法をまとめました。ESP32 Sketch Data Uploadプラグインの代替の方法として使用できます。
Arduino IDEのバージョンアップで2.0.0以降でESP32 Sketch Data Uploadプラグイン(2023年11月上旬では本プラグインは対応していない)が使用できなくなったため、代替の方法でFLASHにファイルをアップロード(書き込み)します。
ESP32-WROOM-32E開発ボード(秋月電子)を使用し、Arduino IDEで開発を行います。また、SDカードモジュール(秋月電子)を使用しています。
ESP32-WROOM-32Eで動作確認したことについてリンクをまとめています。
ESP32-WROOM-32Eで学べるソフト開発と標準ライブラリの使い方
ファイルをアップロードする方法
ファイルを開く方法として標準関数を使う方法がありますが、Arduino環境ではfopen()などの標準関数は非対応となっています。SDカードライブラリはfopen()関数などに準拠したファイルの操作ができます。
ESP32シリーズ専用にSPIFFSライブラリが搭載されており、SDカードライブラリと同じような操作でFLASH領域にデータの読み書きができるようになります。
SDカードライブラリとSPIFFSライブラリの関係
SDカードライブラリでSDカードのファイルを読み出し、SPIFFSライブラリでSDカードから読み出したファイルをFLASHに書き込みます。
本記事では下記記事のグラフ表示に必要なファイルをFLASHに書き込みします。
ESP32-WROOM-32Eで温湿度データをグラフで表示する
ESP32 Sketch Data Uploadプラグインを使用する方法と同様にdataフォルダ内に書き込むデータを準備します。
SDカードに保存したdataフォルダの「myfavicon.ico」「chart.umd.js」を読み出してSPIFFSを使ってFLASHに書き込みます。
- 手順1SDカードのファイルをリードモードで開く
- 手順2SPIFFSのファイルをライトモードで開く
- 手順3SDカードから読み出したデータをFLASHに書き込む
- 手順4ファイルを閉じる
ライブラリの初期化
#include <FS.h>
#include <SPIFFS.h>
#include <SD.h>
SPIFFS.begin(); //SPIFFSの初期化
SPIFFS.format(); //FLASHのデータをフォーマットする場合
if(!SD.begin()){
Serial.println("initialization failed!");
while (1);
}
SPIFFSライブラリ及びSDカードライブラリを使用するためSPIFFS.h、SD.hをインクルードします。またファイルを操作するためFS.hをインクルードします。
SPIFFSの初期化を行うためbegin()関数を使用します。FLASHに不要なファイルが残ることを防ぐ場合はformat()関数でFLASHをフォーマットします。
SDライブラリの初期化を行うためbegin()関数を使用します。初期化に失敗した場合は以降の処理を行えないためwhile()で無限ループするようにしています。
SDカードのファイルを読み込む
//ディレクトリのファイル名を表示
File root = SD.open("/data"); //dataフォルダを開く
File file = root.openNextFile();//ファイルを順次開く
while(file){
Serial.println(file.name());
while(file.available()){
Serial.write(file.read());//シリアルモニターにファイルの内容を表示
//FLASHに読み込んだデータを書き込む処理を追加
}
file.close();
file = root.openNextFile();
}
root.close(); //ファイルを閉じる
SDカードのdataフォルダを開くため、open()関数に”/data”を指定します。次にdataフォルダーのファイルを開くためopenNextFile()関数で順次ファイルを開きます。
ファイルが存在する場合はFileクラスをインスタンス化した変数(file)にファイルの情報が格納されます。
Fileクラスのname()関数を使用するとファイル名が取得できます。例ではwhile()で繰り返すことで存在するファイル名をすべて表示するようにしています。
openNextFile()関数でファイルを開いた状態になっているためavailable()関数で読み込めるファイルのデータ数が確認できます。
read()関数でデータを読み込むとavailable()の値が更新されるため、while()の繰り返しの条件にavailable()を指定することでファイルのデータをすべて取得することができます。例ではread()関数で読み込んだデータをシリアルモニターに表示します。
ファイルのデータを読み終えたらclose()関数でファイルを閉じます。
FLASHにデータを書き込む
File fp = SPIFFS.open("/myfavicon.ico",FILE_WRITE);
if( fp ){
while(file.available()){
fp.write(file.read()); //fileはSDカードを開いたファイル
}
fp.close();
}
SPIFFSを使ってファイルを開くためにopen()関数を使用します。第1引数にはファイルのパスを指定します。第2引数にFILE_WRITE(“w”)を指定します。
対象のファイルが開くと、SPIFFSライブラリのwrite()関数でデータを書き込みます。例は、SDカードのファイルのデータを読み込んだ結果をSPIFFSライブラリのwrite()関数で書き込んでいます。
SDカードのファイルのデータをすべて書き込んだあとはファイルを閉じるためにclose()関数を使用します。
ESP32 Sketch Data Uploadでファイルをアップロードする(参考)
Arduino IDEの旧バージョンのVer1.8.19であれば、下記の方法でESP32 Sketch Data Uploadプラグインが使用できるため手早くファイルをアップロードしたい場合は旧バージョンでアップロードしても良いと思います。
- 手順1SPIFFSのプラグインをダウンロード
- 手順2Arudinoスケッチ保存場所にtoolsフォルダを作成
- 手順3toolsフォルダにダウンロードしたファイルを解凍して移動(コピー)
SPIFFSプラグインをダウンロードしてArduino IDEのツールに「ESP32 Sketch Data Upload」を追加します。
GitHub-arduino-esp32fs-プラグインのダウンロード
ダウンロードしたファイルをArduinoフォルダに追加します。ダウンロードしたファイルを解凍すると「ESP32FS」フォルダが生成されます。Arduinoのスケッチブックの保存場所に指定しているフォルダ内で「tools」フォルダを作成してtoolsファルダー内にESP32FSをコピー(移動)します。
環境設定でスケッチブックの保存場所を確認することができます。初期のままであればドキュメント内のArduinoフォルダが指定されています。例ではC:\WorkSpace\Arduinoを指定しています。
toolsフォルダにESP32FSを追加した後でArduino IDEを起動するとツール欄にESP32 Sketch Data Upload」が追加されます。
ESP32 Sketch Data UploadをクリックするとFlashにデータを書き込むことができますがFlashにデータを書き込む前に書き込むファイルを準備する必要があります。Arduinoファイルが保管されているフォルダに「data」フォルダを作成します。
例ではArduinoファイルが「spiffs」フォルダにあります。このフォルダ内に「data」フォルダを作成しflash_dat.txtファイルを追加しています。
動作確認
ESP32-WROOM-32EとSDカードモジュールの配線例を示しています。SPIライブラリは初期化時に指定しなければVSPIになります。またスレーブセレクト(SS)はデフォルトで5ピンです。
回路図の番号はESP32-WROOM-32Eの左上を1ピンとした時反時計回りにピンを数えた場合の番号としています。ピン番号横の()内の番号はシルク印刷されているピンの名称です。
ソースコード全体のソフトを書き込む前にESP32-WROOM-32Eで温湿度データをグラフで表示するのソフトを書き込んでWiFiでアクセスすると ファビコン及びchart.jpのライブラリが無いため表示されていません。
ソースコード全体のソフトを書き込んでSDカードに保存したdataフォルダの「myfavicon.ico」「chart.umd.js」をFLASHに書き込みます。
書き込み後はESP32-WROOM-32Eで温湿度データをグラフで表示するのソフトを書き込みます。
WiFiでアクセスすると「myfavicon.ico」「chart.umd.js」がFLASHに書き込まれているためファビコンとグラフの表示がされていることが確認できました。
ソースコード全体
以下のソースコードはコンパイルして動作確認をしております。コメントなど細かな部分で間違っていたりやライブラリの更新などにより動作しなくなったりする可能性があります。参考としてお使いいただければと思います。
#include <FS.h>
#include <SPIFFS.h>
#include <SD.h>
//#define FLASH_FORMAT
File myfile;
uint32_t datacnt;
void setup() {
Serial.begin(9600);
SPIFFS.begin();
delay(1000);
#ifdef FLASH_FORMAT
Serial.println( "Format start!" );
SPIFFS.format();
Serial.println( "Format Complete!" );
#endif
delay(1000);
if(!SD.begin()){
Serial.println("initialization failed!");
while (1);
}
else{
File root = SD.open("/data");
File file = root.openNextFile();
String flash_path;
while(file){
flash_path="/";
flash_path.concat(file.name());
Serial.println(flash_path);
File fp = SPIFFS.open(flash_path,FILE_WRITE);
if( fp ){
datacnt = 0;
while(file.available()){
fp.write(file.read());
++datacnt;
Serial.println(datacnt);
}
fp.close();
}
file.close();
file = root.openNextFile();
}
root.close();
}
delay(1000);
Serial.println("--end--");
}
void loop() {
// put your main code here, to run repeatedly:
}
FLASHにファイルを書き込む前にフォーマットする場合は、#define FLASH_FORMATのコメントアウトは外して使用してください。
関連リンク
Arduinoのライブラリを使って動作確認を行ったことを下記リンクにまとめています。
Arduinoで学べるマイコンのソフト開発と標準ライブラリの使い方
Seeeduino XIAOで学べるソフト開発と標準ライブラリの使い方
ESP32-WROOM-32Eで学べるソフト開発と標準ライブラリの使い方
最後まで、読んでいただきありがとうございました。