こんにちは、ENGかぴです。
ESP32シリーズのSPIFFSライブラリを使用するとSDカードのようにFLASHにアクセスしてデータの読み書きができます。ブラウザー(スマホ)からアクセスポイントの設定に関わる設定値を変更しFLASHに保存して動作させる方法をまとめました。
ESP32-WROOM-32E開発ボード(秋月電子)を使用しArduino IDEで開発を行います。
SPIFFSライブラリの使い方などは下記記事にまとめています。本記事はSPIFFSを使った応用例としてまとめています。
ESP32-WROOM-32EのFLASH(SPIFFS)を使用する方法
ESP32-WROOM-32Eで動作確認したことについてリンクをまとめています。
ESP32-WROOM-32Eで学べるソフト開発と標準ライブラリの使い方
SPIFFSの応用例
ESP32シリーズでアクセスポイントの設定をFLASHから取得したデータを使って行います。ブラウスマホなどのブラウザーでSSIDやパスワードなどアクセスポイントの設定やIPアドレスやゲートウェイ設定も変更できるようにします。
SPIFFSの初期設定
#include <FS.h>
#include <SPIFFS.h>
void setup() {
SPIFFS.begin(); //SPIFFSの初期化
FfsRead(); //フラッシュのデータを読み込み
SetAp(); //フラッシュデータを使ってアクセスポイントの
}
SPIFFSライブラリを使用するためにSPIFFS.hをインクルードします。ファイルを開いて読み書きするためFS.hライブラリをインクルードします。Webページをブラウザー上に表示するためWebServer.hライブラリをインクルードします。
setup()関数内で最初にSPIFFSのbegin()関数を使ってSPIFFSの初期化を行います。ユーザー自作のFfsRead()関数でフラッシュデータの読み込みSetAp()関数でアクセスポイントの設定を行います。
PR:わからないを放置せず、あなたにあった最低限のスキルを身に着けるコツを教える テックジム 「書けるが先で、理解が後」を体験しよう!
FLASHのデータを読み込む
void FfsRead(void){
File fp = SPIFFS.open(settings,"r");
if(fp){ //ファイルが開いて以下を処理
ssid = (fp.readStringUntil('\n')); //ssid部分を読み込む
pass = fp.readStringUntil('\n'); //password部分を読み込む
ipadr1 = fp.readStringUntil('\n'); //IP部分を読み込む(MSB)
//以下ゲートウェイ設定
fp.close();
}
else{ //ファイルが開けなかった場合
Serial.println("Flash Read error");
ssid = "EngKapi1";
pass = "22223333";
ipadr1 = "192";
}
ssid.trim(); //null文字を削除
pass.trim();
ipadr1.trim();
if( ipadr1.toInt() == 0){ //整数型に直したとき0であれば初期値を入れる
ipadr1 = "192";
}
}
SPIFFSを使ってファイルを開くためにopen()関数を使用します。第1引数にはファイルのパスを指定します。第2引数にデータを読み込む場合は”r”を指定します。
ファイルが開けるとフラッシュに保管したデータ分のサイズをreadStringUntil()関数を使用し引数に(‘\n’)を指定して読み込みます。readStringUntil()関数は引数で指定した文字列を検出するまで読み込む関数です。
読み込んだ後はファイルを閉じるためclose()関数を使用します。
プログラムを初期動作させる場合はファイルが存在しないため初期値を入力しています。
WiFi.softAP(ssid.c_str(),pass.c_str());
IPAddress ip(ipadr1.toInt(), ipadr2.toInt(), ipadr3.toInt(), ipadr4.toInt());
IPAddress gateway(gwadr1.toInt(), gwadr2.toInt(), gwadr3.toInt(), gwadr4.toInt());
FLASHからデータを読み込んだ後WiFiの設定を行います。SSIDやパスワードは文字列の型からchar型に変換するためc_str()関数を指定しています。
WiFiのIPやゲートウェイは整数型で指定する必要があるためtoInt()関数で文字列の型からint型に変換しています。整数型に変換できない場合(数値以外の文字が入っている)場合は0になります。
本記事のソフトは対策としてIPとゲートウェイの最上位ビットから16ビット分が0にならないように対策しています。
PR:RUNTEQ(ランテック )- マイベスト3年連続1位を獲得した実績を持つWebエンジニア養成プログラミングスクール
FLASHにデータを書き込む
bool FfsWrite(void){
bool ret = true;
File fp = SPIFFS.open(settings,"w");
if( fp ){
fp.println(ssid);
fp.println(pass);
//IP及びゲートウェイを書き込み(省略)
fp.close();
}
else{
Serial.println("Flash Write Error");
ret = false;
}
return ret;
}
SPIFFSを使ってファイルを開くためにopen()関数を使用します。第1引数にはファイルのパスを指定します。第2引数にデータを書き込む場合は”w”を指定します。
書き込んだ後はファイルを閉じるためにclose()関数を使用します。
ファイルを開くとprintln()関数を使って改行コード付きの文字列で書き込みを行います。読み込んだ際に改行コードをデータの区切りとして判断させることができます。
write()関数で書き込む場合はバイナリデータを書き込むことが前提になるためあらかじめデータのサイズなどのフォーマットを統一しておくとよいでしょう。
一見するとテキストデータの方が文字として見やすく感じますが1文字あたり2バイトデータとなるためバイナリデータで管理するよりもデータ容量が大きくなってしまうデメリットもあります。
WebサーバーでHTML情報を取得する
#include <WebServer.h>
WebServer Wserver(80);
void SetAp(void){
//WIFIの設定(省略)
Wserver.on("/",HTTP_GET,HtmlGet); //HTMLの表示
Wserver.on("/",HTTP_POST,HtmlPost); //HTMLからデータを受け取る
Wserver.onNotFound(handleNotFound); //ページが存在しない場合
Wserver.begin();
}
WebServerライブラリを使用するためにインクルードします。WebServerの型で変数を宣言しインスタンスを生成します。初期化関数内でWebServerの設定を行います。
on()関数はURLに対して接続要求がある場合に処理する関数を指定します。第1引数にはURLアドレスの階層を示す文字を指定します。
例えばブラウザーから「192.168.11.2」を指定する場合は”/”となり「192.168.11.2/ti」を指定して表示する場合は”/ti”を指定します。
第2引数にHTTPの種類(HTTP_GETやHTTP_POST)などを指定します。
第3引数に接続要求に対するURLが存在する場合に処理する関数を指定します。
例ではHTMLの表示用の関数としてHtmlGet()を実装し、HTMLからデータを受け取った場合に遷移する関数としてHtmlPost()を指定しています。
onNotFound()はURLが見つからない場合の処理する関数を指定します。
begin()で指定したポートでWebServerが動作開始します。指定しない場合はポート80で動作開始します。
void HtmlGet(void) { //webページの内容を一部抜粋
html += "<input type='text' name='ssid' value='" + ssid + "' placeholder='EngKapi1'style ='width:100px;font-size:20px;'>";
}
void HtmlPost(void){
ssid = Wserver.arg("ssid"); //送信された値を取得
pass = Wserver.arg("pass");
ipadr1 = Wserver.arg("ipadr1");
if( FfsWrite()){ //データを書き込み
FfsRead(); //書き込んだデータを読み返し
readSet(); //変更した内容を表示
}
}
ブラウザーに表示するHtmlGet()ではSSIDの設定用にテキストボックスを実装していますがユーザーがテキストボックス内に入力した値がvalueにセットされます。テキストボックスの値はSSIDの名前でリンクしているためHtmlPost()内でデータの名前で指定することができます。
HtmlPost()ではHTMLから送信された値をarg()関数を使って読み込んでいます。arg()関数の引数に読み込みたいデータの名前を指定します。戻り値は読み込んだ値の文字列となるためHTML内でユーザーが指定した値がセットされます。
HtmlGet()でユーザーが入力したarg()関数によって取得しSPIFFSライブラリを使ってFLASHにアクセスしてデータを書き込みます。
PR:RUNTEQ(ランテック )- マイベスト3年連続1位を獲得した実績を持つWebエンジニア養成プログラミングスクール
動作確認
スマホでアクセスポイントとして表示されている「Engkapi」を接続し「192.168.11.3」をスマホのGoogle Chromeでアクセスすると設定項目が表示されます。動作確認としてIPアドレスを「192.168.11.5」に変更し設定値送信のボタンを押すと現在設定値が表示されます。
ESP32-WROOM-32Eをリスタート(電源OFFまたはリセットボタン)すると変更した値でWiFi通信がスタートします。使用するブラウザーによってテキストボックスやボタンの大きさが変化するため可能な限りテキストボックスの幅やボタンの大きさをHTML言語で指定しておく方がよさそうです。
設定がスマホからできて便利だと感じますが、WiFi通信が届かないことやAndroidスマホ(環境によると思います)では接続が継続できずに切断したりするため通信ができない場合の対策についても十分に検討する必要がありそうです。
ソースコード全体
ソースコードは記事作成時点において動作確認できていますが、使用しているライブラリの更新により動作が保証できなくなる可能性があります。また、ソースコードを使用したことによって生じた不利益などの一切の責任を負いかねます。参考資料としてお使いください。
リンクからZIPファイル形式のファイルをダウンロードし、任意の場所に展開していただくとテキストファイルが生成されます。
関連リンク
Arduinoのライブラリを使って動作確認を行ったことを下記リンクにまとめています。
Arduinoで学べるマイコンのソフト開発と標準ライブラリの使い方
Seeeduino XIAOで学べるソフト開発と標準ライブラリの使い方
ESP32-WROOM-32Eで学べるソフト開発と標準ライブラリの使い方
PR:
わからないを放置せず、あなたにあったスキルを身に着けるコツを教える テックジムPython入門講座の申込
最後まで、読んでいただきありがとうございました。
今回はSPIFFSでWIFIの設定を変更して動作させる例としてアクセスポイント設定を変更しましたが、他のセンサーの設定情報などを保管する方法等にも応用することができます。