Home
ESP32-WROOM-32 ネットワーク接続パラメーター セッティングツール
更新履歴 Ver.2.2 '22/09/28
Ver.2.1 '22/08/26
Ver.2.0 '22/05/24
Ver.1.0 '20/04/25
All rights reserved JA3OOK 中村 利和
ESP32-WROOM-32 で WiFi ServerやClientを製作し、SSIDやPW、IPアドレスなどを変更したい場合、
普通はスケッチ(ソースプログラム)を変更しリコンパイルすることになり、時間がかかります。
このソフト(セッティングツール net-param-SPIFFS.ino)を利用すると、SSIDやPW、IPアドレスな
どの変更をスケッチの変更やリコンパイルなしに可能になり、「ESP32-WROOM-32とPCをUSBケーブルで
接続し、PCのターミナルソフト(注)からコマンド操作で設定や変更」ができます。
このセッティングツール(net-param-SPIFFS.ino)を Arduinoの .ino ファイルとして提供します。
メインの.ino から関数を呼ぶことにより利用します。
注 PCのターミナルソフトとは、Arduino IDE のシリアルモニタやTera Termなど。
動作原理は、ESP32-WROOM-32内蔵の不揮発性メモリーにSSIDなどの値を書き込んでおき、起動時
にそれを読み込んでその値で動作させます。内蔵不揮発性メモリー(フラッシュメモリ)の読み書き
は、ESP32-WROOM-32が持っているSPIFFS (SPI Flash File System)を利用しています。
動作確認環境 ESP32-DevKitC (ESP32-WROOM-32)
Arduino IDE 1.8.12 + esp32 by Espressif System バージョン 1.0.4
Arduino IDE 1.8.19 + esp32 by Espressif System バージョン 1.0.4
免責事項 このソフトの利用は利用者の自己責任で行ってください。
目次
1.コマンド操作で何ができるか
2.利用方法
3.操作方法
4.本ツールのソースプログラム
5.本ツールを利用したサンプルソースプログラム
6.本ツールの実際の組込み例の紹介
7.更新履歴
1.コマンド操作で何ができるか
次に示す枠内はこのツールのヘルプコマンド(?)での出力結果のハードコピーです。
Hellow! this is net-param setting tool
>?
list ファイルの中身をリスト出力
make 既定値でファイルを作る
del ファイルそのものを削除
save 更新結果をファイルに書き戻す
exit セッティングを抜け出る
? or help コマンドの説明
以下のコマンドで各データを更新、最後にsaveでファイルを上書きすること
sketch= 書き込み済みのメインスケッチファイル名など
debug= 整数値 0:本番
myとは:このプログラムが動作する場所(server or client)や、自身についての情報
myplace= server or client
myssid= 30文字以内
mypw= 30文字以内
myipaddr= .で区切る
myport= myport番号は指定しても無効(制限事項)
mydns= .で区切る
mygateway= .で区切る
mysubnet= .で区切る
hisとは:client の場合に、serverについての情報
hisnetname= サーバーのネットアドレス名 30文字以内
hisipaddr= 〃 のIPアドレス(上記とどちらか)
hisport= 〃 のポート番号
appとは:アプリレベルの情報
apppw= アプリレベルの認証パスワード(serverとclientで同じであること)
> |
どのようなデータをどのようなコマンドで操作しているかがだいたい分かるでしょう。
Wi-Fi(無線LAN)のSSIDやそのパスワードはもちろん、サーバーやクライアントプログラムの製
作に必要なデータやサーバーとクライアントのAPレベルの認証データの管理ができます。
ただし、ポート番号については指定しても無効(制限事項)と付記してあります。
スケッチの中でポート番号を変数で指定できる方法が私には分からないからです。
変数で指定できる方法が分かる方はポート番号を利用してください。
sketch= はこのESP32-WROOM-32に何が書かれているかを月日が経って忘れてもこれを見れば
分かるためのメモ書きです。スケッチファイル名以外も書き込めます。
debug= は整数値を指定でき、デバッグ時に各種の値を指定します。
使い方の例:
タイマー設定時間など試行錯誤が必要なテストでdebug=で設定すると、
スケッチの変更なしに試行錯誤でき開発時間を大幅に節約できる。
(コンパイルが不要で、ESP-WROOM-32Dを再起動してdebug=の値を変更するだけで
テストができる)
別の例では本番モードかデバッグモードかをdebug=で指定し、
デバッグのためのトレースをSerial.printするかしないかの切り分けに使える。
どのデータを理由するかは自由で、あなたが製作するプログラムに必要なデータだけ利用すれ
ばよいのです。
listコマンドでの出力結果の例です。 その時点での全データ内容が出力されます。
>list
sketch=mainaaaaa.ino 2022/05/01 メインスケッチファイル名など
debug=0 整数値 0:本番
myplace=server server or client
myssid=abcd 30文字以内
mypw=xxxx 30文字以内
myipaddr=192.168.0.40 .で区切る
myport=58000 myport番号は指定しても無効(制限事項)
mydns=192.168.0.1 .で区切る
mygateway=192.168.0.1 .で区切る
mysubnet=255.255.255.0 .で区切る
hisnetname=xxx.iobb.net clientの場合にサーバーのネットアドレス名
hisipaddr=200.200.10.10 〃 のIPアドレス(上記とどちらか)
hisport=58000 〃 のポート番号
apppw=applipw アプリレベルの認証パスワード(serverとclientで同じであること)
> |
myssid を pqrstu に変更してみましょう。(必要なら複数データ項目を続けて変更できます)
変更した最後に saveコマンドでファイルに書き戻します。
>myssid=pqrstu
accepted, must save after
>save
updated /internet.ini
>
|
そのファイル名が /internet.ini であることが読み取れます。
注意 このファイル名はコマンドでは変えられません。
変えるには本ツールのソースプログラム(net-param-SPIFFS.ino)の
42行目 #define iniFileName "/internet.ini" // 任意のファイル名
を変更しリコンパイルします。
その前に、元のファイルは delコマンドで削除しておいてください。削除しておかないと
永久に内蔵不揮発性メモリー内に残ります。
新しく作ったファイルも不要になれば削除してください。
(削除しておかないとSSDやPWを悪用される可能性があります。実際的には実害がないかも
知れませんが・・・)
listコマンドにより、変更結果を確認できます。
>myssid=pqrstu
accepted, must save after
>save
updated /internet.ini
>list
sketch=mainaaaaa.ino 2022/05/01 メインスケッチファイル名など
debug=0 数値 0:本番
myplace=server server or client
myssid=pqrstu 30文字以内
mypw=xxxx 30文字以内
myipaddr=192.168.0.40 .で区切る
myport=58000 myport番号は指定しても無効(制限事項)
mydns=192.168.0.1 .で区切る
mygateway=192.168.0.1 .で区切る
mysubnet=255.255.255.0 .で区切る
hisnetname=xxx.iobb.net clientの場合にサーバーのネットアドレス名
hisipaddr=200.200.10.10 〃 のIPアドレス(上記とどちらか)
hisport=58000 〃 のポート番号
apppw=applipw アプリレベルの認証パスワード(serverとclientで同じであること)
>
|
2.利用方法
a あなたが製作するArduinoソースプログラムを「メイン.ino」と呼ぶことにします。
そのメイン.inoと同じ名前(拡張子.inoは付けない名前)のフォルダーを作り、メイン.ino
と本ツールである net-param-SPIFFS.ino を入れます。(つまり net-param-SPIFFS.inoは3.項
のソースプログラム全体をコピーしてください)
(二つの.inoファイルが存在することになるが大丈夫)
b net-param-SPIFFS.inoの
24行目 // ここから メイン.ino と net-param-SPIFFS.ino との連携データ
から
39行目 // ここまで連携データ
までをコピーし、5項サンプルのメイン.inoのように メイン.inoの頭の方(ヘッダー)のグローバル変数の
定義の最初にペーストします。
ペーストして定義した変数を介して、二つの.inoがデータを受け渡しします。
(なお、net-param-SPIFFS.inoの24行目から39行目は、消さずコメントのままにしておく)
c 5項サンプルのメイン.inoのように次のソースコードを void setup() の始まりの箇所に
コピーペーストしてください。
pinMode(settingPin, INPUT_PULLUP);
// ランモード/設定モードの設定(settingPin:ピン番号32が接地されているかどうかで判定)
if(digitalRead(settingPin)) settingMode = false; // highなら、ランモード
else settingMode = true; // lowなら、設定モード
// settingModeがfalse: ランモード : ファイルが無ければ既定値でファイルを作成し、既定値でreturn
// ファイルが有ればファイルの値でreturn
// settingModeがtrue : 設定モード : 各種コマンドを入力でき、ファイルに書き込むことができる
// exitコマンドでランモードへ
setNetworkParameter(); // ネットワークパラメーターの設定を実行
これは、settingPinのピンモードの設定とhigh/lowによる意味づけを行ってから「ネットワークパラ
メーターの設定」をcallするコードです。
d その後は普通にコンパイルし、ESP32-WROOM-32へ書き込んでください。
参考 書き込みを行っても内蔵の不揮発性メモリーがリセットされたり、
書き変わることはない。即ち、以前に書かれた内容が保持される。
3.操作方法
概要 本ツールをターミナルソフトを使って操作する。
ターミナルソフトは、スケッチのデバッグ中なら「Arduinoのシリアルモニタ」が便利で、
デバッグが終わっていれば「Tera Term」が便利です。
通信速度条件はメイン.inoで設定し、ターミナルソフトもそれに一致させます。
a ESP32-WROOM-32へ外部からの電源供給していれば供給カット。
b ESP32-WROOM-32とPCをUSB変換基板を経由してUSBケーブルで接続。(USBケーブルからの電源で動作)
c settingPin をlow状態にする(接地する)。
(settingPin とは5項で示すサンプルなら27行目 #define settingPin 32 IO32ピン)
参考 settingPin がhigh状態で電源供給またはResetされると Run 状態になりコマンドは
受付けられない。
d ESP32-WROOM-32をResetする(J2 ENボタン押下)。
(電源供給より先にsettingPin がlow状態の場合はResetしなくてもコマンドを受付けられる)
e 1項の各種コマンドで操作する。
コマンドの一般的な順序。
list でメモリー内容確認
↓
sketch= myssid= mypw= myipaddr= などでそれぞれの値をセット
↓
save でセットした値をメモリーへ書き込む
↓
list でメモリー内容確認
注意 myportとhisportは設定しても動作に影響しません。
port番号を変更したい場合はスケッチの変更とリコンパイルが必要です。
f 操作の終了は、 exit の入力、または
settingPinを開放(high)しESP32-WROOM-32をReset(J2 ENボタン押下)。
g nothing /internet.ini メッセージが出た場合の処置。
(一般的にはこのESP32-WROOM-32に対して初めて操作する場合に出る)
make を入力すること。(これにより internet.iniファイル が既定値で作られる)
list で既定値の内容が分かり、eのコマンド操作を行う。
4.本ツール net-param-SPIFFS.ino のソースプログラム (これが全てです。コピーして活用してください)
// net-param-SPIFFS.ino 2022/08/21 Ver 2.1 JA3OOK
// ネットワーク接続パラメーター(Wi-Fi接続のIPアドレスなど)を内蔵不揮発性メモリーへSPIFFSを利用して
// 記憶させるツールです。(なお、内蔵不揮発性メモリーはプログラムが書き込まれても消えません)
// SSID,PW,IPアドレスなどの設定、保存、変更、読み出しなどがコマンドで可能で、
// ソースプログラムの変更やリコンパイルが不要です。
//
// 他のプログラムからこのツールを利用するは、settingMode変数に true/false を設定し
// setNetworkParameter(); を呼び出す。
// false: run mode : ファイルが無ければ既定値でファイルを作成し、既定値でreturn。
// ファイルが有ればファイルの値でreturn。
// true : setting mode : コマンドで設定し、ファイルに書き込む。
// exitコマンドでreturn。
// どちらにすべきかの切換えは、ラン実行の最初に、入力ピンの値がhighかlowかで行うのが一般的だろう。
//
// 動作確認環境 ESP32-DevKitC (ESP32-WROOM-32)
// Arduino IDE 1.8.12 + esp32 by Espressif System バージョン 1.0.4
// Arduino IDE 1.8.19 + esp32 by Espressif System バージョン 1.0.4
#include "FS.h"
#include "SPIFFS.h"
// このプログラムがWi-Fi(無線LAN)で接続するルーターの情報
/* // 次の連携データ定義をメインの.inoにコピーすること
// ここから メイン.ino と net-param-SPIFFS.ino との連携データ
bool settingMode = true;
String sketch; // メインスケッチファイル名など
int debug; // 0:本番
String myplace; // このプログラムが動作する場所(server / client)
char myssid[31]; // Wi-Fiルーターのssid (charの場合は文字数指定が必要)
char mypassword[31]; // Wi-Fiルーターのパスワード
String myportStr; // myport番号は指定しても無効(制限事項)
uint16_t myport; // myport番号は指定しても無効(制限事項)
IPAddress myip(192,168, 0, 49); //myipaddress 仮の値
IPAddress mygateway(192,168, 0, 1); //mygateway 〃
IPAddress mysubnet(255, 255,255, 0); //mysubnetmask 〃
IPAddress mydns(192,168, 0, 1); //mydns 〃
String hisNetname; // hisipのネットアドレス型式名
IPAddress hisip(49,49,49,49); //動作場所が"client"の場合に、his即ちサーバーの指定に使用
unsigned int hisport; //動作場所が"client"の場合に、his即ちサーバーの指定に使用
String appPW; //アプリレベルの認証パスワード
// ここまで連携データ
*/
#define iniFileName "/internet.ini" // 任意のファイル名(SPIFFS:不揮発性メモリー に書かれるファイル名)
// work area
String debugModeStr="0"; // 既定値:本番
String myssidStr; // ルーターのmyssid 最大30文字
String mypasswordStr; // ルーターのパスワード 最大30文字
String myipStr;
String mygatewayStr;
String mysubnetStr;
String mydnsStr;
String hisipStr;
String hisportStr;
char addr[4];
// make the file by default value
bool makeFile(){
File file = SPIFFS.open(iniFileName, FILE_WRITE); // 書き込み、存在すれば上書き
if(!file){
return false;
}
else{ // ファイルを既定値で作成する
file.println("sketch=mainaaaaa.ino 2022/05/01");
file.println("debug=0"); // 0:既定値:本番
file.println("myplace=server");
file.println("myssid=abcd");
file.println("mypw=xxxx");
file.println("myipaddr=192.168.0.40");
file.println("myport=58000"); // myport番号は指定しても無効(制限事項)
file.println("mydns=192.168.0.1");
file.println("mygateway=192.168.0.1");
file.println("mysubnet=255.255.255.0");
file.println("hisnetname=xxx.iobb.net"); // rmtKeyサーバーのネットアドレス名
file.println("hisipaddr=200.200.10.10"); // rmtKeyサーバーのIPアドレス
file.println("hisport=58000"); // rmtKeyサーバーのポート番号
file.println("apppw=applipw"); // アプリレベルの認証パスワード
file.println("endOfFile");
file.close();
return true;
}
}
// 192.168.0.1形式のアドレスを char配列addr[]に格納する
void setIPaddress(String str){
unsigned int loc[3];
loc[0] = str.indexOf('.');
loc[1] = str.indexOf('.',loc[0]+1);
loc[2] = str.indexOf('.',loc[1]+1);
addr[0] = str.substring(0,loc[0]).toInt();
addr[1] = str.substring(loc[0]+1,loc[1]).toInt();
addr[2] = str.substring(loc[1]+1,loc[2]).toInt();
addr[3] = str.substring(loc[2]+1).toInt();
}
// 192.168.0.1 形式でアドレスをプリントする
void listIPaddress(IPAddress ip){
Serial.print(ip[0], DEC);Serial.print('.');Serial.print(ip[1], DEC);Serial.print('.');
Serial.print(ip[2], DEC);Serial.print('.');Serial.print(ip[3], DEC);
}
// read file
void readFile(){
String str;
byte leng;
File file = SPIFFS.open(iniFileName, FILE_READ); // モード:読み取り
if(!file || file.isDirectory()){ // ファイルが存在しない
Serial.println("- failed to open file for writing");
Serial.print('>');
return;
}
while(file.available()){ // データがある限り
for (int i=1; i<=30; i++){
str=file.readStringUntil('\n'); // '\n'=0x0A=LF
str.replace("\r",""); // 右端の '\r'=0x0D=CR をnullに変換
leng = str.length();
// Serial.print(i); Serial.print(":"); // debug
// Serial.print(leng); Serial.print(":"); Serial.println(str); // debug
if(str.startsWith("sketch=") && leng >= 8){
sketch = str.substring(7);
}
if(str.startsWith("debug=") && leng >= 7){
debugModeStr = str.substring(6); debug = debugModeStr.toInt();
}
if(str.startsWith("myplace=") && leng >= 9){
myplace = str.substring(8);
}
if(str.startsWith("myssid=") && leng >= 8){
myssidStr = str.substring(7); myssidStr.toCharArray(myssid,31);
}
if(str.startsWith("mypw=") && leng >= 6){
mypasswordStr = str.substring(5); mypasswordStr.toCharArray(mypassword,31);
}
if(str.startsWith("myipaddr=") && leng >= 10){
myipStr = str.substring(9);
// Serial.println(myipStr);//debug
setIPaddress(myipStr); // 192.168.0.1形式から採取し、addr[]へ書き込む
myip[0]=addr[0]; myip[1]=addr[1]; myip[2]=addr[2]; myip[3]=addr[3];
// Serial.print(myip[0], DEC);Serial.print('.');Serial.print(myip[1], DEC);Serial.print('.');//debug
// Serial.print(myip[2], DEC);Serial.print('.');Serial.println(myip[3], DEC);//debug
}
if(str.startsWith("myport=") && leng >= 8){
myportStr = str.substring(7); myport = myportStr.toInt();
}
if(str.startsWith("mydns=") && leng >= 7){
mydnsStr = str.substring(6);
setIPaddress(mydnsStr); // 192.168.0.1形式から採取し、addr[]へ書き込む
mydns[0]=addr[0]; mydns[1]=addr[1]; mydns[2]=addr[2]; mydns[3]=addr[3];
}
if(str.startsWith("mygateway=") && leng >= 11){
mygatewayStr = str.substring(10);
setIPaddress(mygatewayStr); // 192.168.0.1形式から採取し、addr[]へ書き込む
mygateway[0]=addr[0]; mygateway[1]=addr[1]; mygateway[2]=addr[2]; mygateway[3]=addr[3];
}
if(str.startsWith("mysubnet=") && leng >= 10){
mysubnetStr = str.substring(9);
setIPaddress(mysubnetStr); // 192.168.0.1形式から採取し、addr[]へ書き込む
mysubnet[0]=addr[0]; mysubnet[1]=addr[1]; mysubnet[2]=addr[2]; mysubnet[3]=addr[3];
}
if(str.startsWith("hisnetname=") && leng >= 12){
hisNetname = str.substring(11);
}
if(str.startsWith("hisipaddr=") && leng >= 11){
hisipStr = str.substring(10);
setIPaddress(hisipStr); // 192.168.0.1形式から採取し、addr[]へ書き込む
hisip[0]=addr[0]; hisip[1]=addr[1]; hisip[2]=addr[2]; hisip[3]=addr[3];
}
if(str.startsWith("hisport=") && leng >= 9){
hisportStr = str.substring(8); hisport = hisportStr.toInt();
}
if(str.startsWith("apppw=") && leng >= 7){
appPW = str.substring(6);
}
if(str.startsWith("endOfFile")){
file.close(); return;
}
}//end for
}//end While
file.close();
}//end void readFile()
void setNetworkParameter(){
//ネットワークパラメターの設定 メイン処理
// false: ランモード : ファイルが無ければ既定値でファイルを作成し、既定値でreturn。
// ファイルが有ればファイルの値でreturn。
// true : 設定モード : コマンドで設定し、ファイルに書き込む。
// exitコマンドでreturn。
String str;
byte leng;
if(SPIFFS.begin(true)){
if(settingMode){
Serial.println("\nHellow! this is net-param setting tool");
Serial.print('>');
Serial.setTimeout(300000); // 300000ms=300s=5minutes後に、Enterキー押下と同じ動作になる
while(settingMode){
if(Serial.available()){
str = Serial.readStringUntil('\n'); // '\n'=0x0A=LF
Serial.println(str); // エコーを返す
str.replace("\r",""); // 右端の '\r'=0x0D=CR をnullに変換
leng = str.length();
if(str.startsWith("make") && leng == 4){ // make the file by default value
if (makeFile()){
Serial.print("made in setting "); Serial.println(iniFileName);
}
else{
Serial.println("- failed to open file for writing");
}
Serial.print('>');
}
else{
if(str.startsWith("list") && leng == 4){ // print : print contents in file
// read file
File file = SPIFFS.open(iniFileName, FILE_READ); // モード:読み取り
if(!file || file.isDirectory()){ // ファイルが存在しない
Serial.print("nothing "); Serial.println(iniFileName);
Serial.print('>');
}//end ファイルが存在しない
else{ // ファイルが存在するのでメモリーへの取り込んでプリント
file.close();
readFile();
// メモリー内容すなわちファイル内容をprint
Serial.print("sketch="); Serial.print(sketch); Serial.println(" メインスケッチファイル名など");
Serial.print("debug="); Serial.print(debug); Serial.println(" 整数値 0:本番");
Serial.print("myplace="); Serial.print(myplace); Serial.println(" server or client");
Serial.print("myssid="); Serial.print(myssid); Serial.println(" 30文字以内");
Serial.print("mypw="); Serial.print(mypassword); Serial.println(" 30文字以内");
Serial.print("myipaddr="); listIPaddress(myip); Serial.println(" .で区切る");
Serial.print("myport="); Serial.print(myport); Serial.println(" myport番号は指定しても無効(制限事項)");
Serial.print("mydns="); listIPaddress(mydns); Serial.println(" .で区切る");
Serial.print("mygateway="); listIPaddress(mygateway); Serial.println(" .で区切る");
Serial.print("mysubnet="); listIPaddress(mysubnet); Serial.println(" .で区切る");
Serial.print("hisnetname="); Serial.print(hisNetname); Serial.println(" clientの場合にサーバーのネットアドレス名");
Serial.print("hisipaddr="); listIPaddress(hisip); Serial.println(" 〃 のIPアドレス(上記とどちらか)");
Serial.print("hisport="); Serial.print(hisport); Serial.println(" 〃 のポート番号");
Serial.print("apppw="); Serial.print(appPW); Serial.println(" アプリレベルの認証パスワード(serverとclientで同じであること)");
Serial.print('>');
}
}//end list
else{
if(str.startsWith("save") && leng == 4){ // save : real update file
// 書き込み、存在すれば上書き
File file = SPIFFS.open(iniFileName, FILE_WRITE);
file.print("sketch="); file.println(sketch);
file.print("debug="); file.println(debugModeStr);
file.print("myplace="); file.println(myplace);
file.print("myssid="); file.println(myssidStr);
file.print("mypw="); file.println(mypasswordStr);
file.print("myipaddr="); file.println(myipStr);
file.print("myport="); file.println(myportStr);
file.print("mydns="); file.println(mydnsStr);
file.print("mygateway="); file.println(mygatewayStr);
file.print("mysubnet="); file.println(mysubnetStr);
file.print("hisnetname="); file.println(hisNetname);
file.print("hisipaddr="); file.println(hisipStr);
file.print("hisport="); file.println(hisportStr);
file.print("apppw="); file.println(appPW);
file.println("endOfFile");
Serial.print("updated "); Serial.println(iniFileName);
Serial.print('>');
}//end save
else{
if(str.startsWith("del") && leng == 3){ // del : delete file
if(SPIFFS.remove(iniFileName)){Serial.print("deleteed "); Serial.println(iniFileName);}
else{Serial.print("failed to delete"); Serial.println(iniFileName);}
Serial.print('>');
}
else{
if(str.startsWith("exit") && leng == 4){ // exit : セッティングを終わる
settingMode = false;
Serial.println("in to run mode");
}
else{
// modify parameter of .ini file
if(str.startsWith("sketch=") && leng >= 8){ // sketch=
sketch = str.substring(7);
Serial.println("accepted, must save after");
Serial.print('>');
}
else{
if(str.startsWith("debug=") && leng >= 7){ // debug=
debugModeStr = str.substring(6);
Serial.println("accepted, must save after");
Serial.print('>');
}
else{
if(str.startsWith("myplace=") && leng >= 9){ // myplace=
myplace = str.substring(8);
Serial.println("accepted, must save after");
Serial.print('>');
}
else{
if(str.startsWith("myssid=") && leng >= 8){ // myssid=
myssidStr = str.substring(7);
Serial.println("accepted, must save after");
Serial.print('>');
}
else{
if(str.startsWith("mypw=") && leng >= 6){ // mypw=
mypasswordStr = str.substring(5);
Serial.println("accepted, must save after");
Serial.print('>');
}
else{
if(str.startsWith("myipaddr=") && leng >= 10){ // myipaddr=
myipStr = str.substring(9);
// Serial.println(myipStr);//debug
Serial.println("accepted, must save after");
Serial.print('>');
}
else{
if(str.startsWith("myport=") && leng >= 8 && leng <= 12){ // myport=
myportStr = str.substring(7);
Serial.println("accepted, must save after");
Serial.print('>');
}
else{
if(str.startsWith("mydns=") && leng >= 7){ // mydns=
mydnsStr = str.substring(6);
Serial.println("accepted, must save after");
Serial.print('>');
}
else{
if(str.startsWith("mygateway=") && leng >= 11){ // mygateway=
mygatewayStr = str.substring(10);
Serial.println("accepted, must save after");
Serial.print('>');
}
else{
if(str.startsWith("mysubnet=") && leng >= 10){ // mysubnet=
mysubnetStr = str.substring(9);
Serial.println("accepted, must save after");
Serial.print('>');
}
else{
if(str.startsWith("hisnetname=") && leng >= 12){
hisNetname = str.substring(11);
Serial.println("accepted, must save after");
Serial.print('>');
}
else{
if(str.startsWith("hisipaddr=") && leng >= 11){
hisipStr = str.substring(10);
Serial.println("accepted, must save after");
Serial.print('>');
}
else{
if(str.startsWith("hisport=") && leng >= 9){
hisportStr = str.substring(8);
Serial.println("accepted, must save after");
Serial.print('>');
}
else{
if(str.startsWith("apppw=") && leng >= 7){
appPW = str.substring(6);
Serial.println("accepted, must save after");
Serial.print('>');
}
else{
if(str.startsWith("?") || str.startsWith("help")){ // ? or help
Serial.println("list ファイルの中身をリスト出力");
Serial.println("make 既定値でファイルを作る");
Serial.println("del ファイルそのものを削除");
Serial.println("save 更新結果をファイルに書き戻す");
Serial.println("exit セッティングを抜け出る");
Serial.println("? or help コマンドの説明");
Serial.println("以下のコマンドで各データを更新、最後にsaveでファイルを上書きすること");
Serial.println("sketch= 書き込み済みのメインスケッチファイル名など");
Serial.println("debug= 整数値 0:本番");
Serial.println("myとは:このプログラムが動作する場所(server or client)や、自身についての情報");
Serial.println("myplace= server or client");
Serial.println("myssid= 30文字以内");
Serial.println("mypw= 30文字以内");
Serial.println("myipaddr= .で区切る");
Serial.println("myport= myport番号は指定しても無効(制限事項)");
Serial.println("mydns= .で区切る");
Serial.println("mygateway= .で区切る");
Serial.println("mysubnet= .で区切る");
Serial.println("hisとは:client の場合に、serverについての情報");
Serial.println("hisnetname= サーバーのネットアドレス名 30文字以内");
Serial.println("hisipaddr= 〃 のIPアドレス(上記とどちらか)");
Serial.println("hisport= 〃 のポート番号");
Serial.println("appとは:アプリレベルの情報");
Serial.println("apppw= アプリレベルの認証パスワード(serverとclientで同じであること)");
Serial.print('>');
}
else{
if(leng > 0)Serial.println("ignore");
Serial.print('>');
}}}}}}}}}}}}}}}}}}}}
}//end if(Serial.available())
}//end while(settingMode)
}//end if(settingMode)
else {// runモード
File file = SPIFFS.open(iniFileName, FILE_READ); // モード:読み取り
if(!file || file.isDirectory()){ // ファイルが存在しない
// create the file
if (makeFile()){ Serial.print("made in auto"); Serial.println(iniFileName);}
else{ Serial.println("- failed to open file for writing"); }
}
}
readFile();
SPIFFS.end();
}
else{
Serial.println("SPIFFS Mount Failed");
}
}
|
5.本ツールを利用したサンプルソースプログラム
本サンプルは「WiFiServer」の一部です。その特徴は、
・net-param-SPIFFS.ino を利用しています。
・次の命令を void loop()内に記述してあるので、WiFi(無線LAN)電波が弱くて一時的に
途絶えても、自動的に再接続されます。
WiFi.config(myip, mygateway, mysubnet, mydns);
WiFi.begin(myssid, mypassword);
(Webでよく見かけるコード例は電波が一時的に途絶えても再立ち上げ操作が必要です。
原因は void setup()内に記述されているからです。本サンプルのようにvoid loop()内に記述すれば自動的に再接続されます)
// net-param-SPIFFS.ino の「WiFiServer」での使用例 2022/08/21 Ver 2.1 JA3OOK
//
#include <WiFi.h>
// ここから メイン.ino と net-param-SPIFFS.ino との連携データ
bool settingMode = true;
String sketch; // メインスケッチファイル名など
int debug; // 0:本番
String myplace; // このプログラムが動作する場所(server / client)
char myssid[31]; // Wi-Fiルーターのssid (charの場合は文字数指定が必要)
char mypassword[31]; // Wi-Fiルーターのパスワード
String myportStr; // myport番号は指定しても無効(制限事項)
uint16_t myport; // myport番号は指定しても無効(制限事項)
IPAddress myip(192,168, 0, 49); //myipaddress 仮の値
IPAddress mygateway(192,168, 0, 1); //mygateway 〃
IPAddress mysubnet(255, 255,255, 0); //mysubnetmask 〃
IPAddress mydns(192,168, 0, 1); //mydns 〃
String hisNetname; // hisipのネットアドレス型式名
IPAddress hisip(49,49,49,49); //動作場所が"client"の場合に、his即ちサーバーの指定に使用
unsigned int hisport; //動作場所が"client"の場合に、his即ちサーバーの指定に使用
String appPW; //アプリレベルの認証パスワード
// ここまで連携データ
// WiFiServer
WiFiServer server(50015); // PORT番号は定数でないとダメな模様(void loop()内でも定数でないとダメな模様)
WiFiClient client;
// ピン定義
#define settingPin 32 // 接地(LOW)時はシリアル端末を使用してIPドレス等設定
#define wifiConnectedPin 33 // 接続中表示
int i = 0; // Wi-Fi未接続時のプリント.数をカウントして改行
int stas = 0; // CONNECT時の状態遷移
void setup() {
delay(500);
Serial.begin(115200);
pinMode(settingPin, INPUT_PULLUP);
delay(200); // PULLUP完了までdelay
// ランモード/設定モードの設定(settingPinが接地されているかどうかで判定)
if(digitalRead(settingPin)) settingMode = false; // highなら、ランモード
else settingMode = true; // lowなら、設定モード
// settingModeがfalse: ランモード : ファイルが無ければ既定値でファイルを作成し、既定値でreturn
// ファイルが有ればファイルの値でreturn
// settingModeがtrue : 設定モード : 各種コマンドを入力でき、ファイルに書き込むことができる
// exitコマンドでランモードへ
setNetworkParameter(); // ネットワークパラメーターの設定を実行
pinMode(wifiConnectedPin, OUTPUT);
digitalWrite(wifiConnectedPin, LOW);
delay(10);
Serial.print("sketch=");
Serial.println(sketch); // net-param-SPIFFSで設定されているスケッチファイル名
Serial.print("debug=");
Serial.println(debug); // net-param-SPIFFSで設定されているデバッグモード
Serial.println("AP start");
} // void setup
void loop() {
String recvString ;
#define rcvEndMark '\t'
char ch; //受信1文字毎
bool wifiConnectedPinLchika = false;
if(WiFi.status() != WL_CONNECTED){
// try connect to WiFi
stas = 0;
Serial.print(stas);
Serial.print(" Connecting to ");
Serial.println(myssid);
WiFi.config(myip, mygateway, mysubnet, mydns);
delay(100);
WiFi.begin(myssid, mypassword);
while (WiFi.status() != WL_CONNECTED) { // loopの中なので、WiFi接続が切れた場合の自動再接続が可能
if(wifiConnectedPinLchika == false){ // 1秒毎に点滅
digitalWrite(wifiConnectedPin, HIGH); wifiConnectedPinLchika = true;
}
else{
digitalWrite(wifiConnectedPin, LOW); wifiConnectedPinLchika = false;
}
// Wi-Fi未接続時に.をプリント
Serial.print(".");
i++;
if (i >= 120) {
Serial.println("");
i = 0;
}
delay(1000);
}
stas = 1;
digitalWrite(wifiConnectedPin, HIGH);
Serial.println("");
Serial.print(stas);
Serial.println(" WiFi connected");
Serial.print("IP address: ");
Serial.print(WiFi.localIP());
Serial.print(':');
Serial.print(myport);
long rssi = WiFi.RSSI(); // print the received signal strength:
Serial.print(" signal strength:");
Serial.print(rssi);
Serial.println("dBm");
// サーバー開始
server.begin();
}//end WiFi connect
client = server.available(); // listen for incoming clients
if (client) { // if you get a client,
stas = 2;
Serial.print(stas);
Serial.println(" new client");
recvString = "";
while (client.connected()) {
stas = 3;
recvString = "";
if (client.available()) { // byte's number of received message from the client,
while( ( ch = client.read() ) != -1 ){
recvString += ch;
if (ch == rcvEndMark) break; //約束事 受信文の最後は特定の文字
}
if(ch != -1) {
// 受信データ処理、送信処理を記述
Serial.print(stas); // debug
Serial.println(' ' + recvString); // debug
client.print("hello " + recvString); // "hello" + 受信データ
// client.print(recvString);
}
}
} // while client.connected
client.stop();
if(stas >=2){
Serial.print(stas);
Serial.println(" client disonnected_A");
}
stas = 1;
}else{
// クライアントとつながっていない
if(stas >=2){
client.stop();
Serial.println(" client disonnected_B");
stas = 1;
}
}
} // void loop |
6.本ツールの実際の組込み例の紹介
・V2640搭載 Unit Cam Wi-Fi Camera(ESP32-WROOM-32E) で工夫したこと ソースプログラム付
7.更新履歴
Ver.2.2 '22/09/28
・サンプルソースプログラムに一行追加。
pinMode(settingPin, INPUT_PULLUP); の次に
delay(200); // PULLUP完了までdelay を一行追加。
(pinよってはpinの電圧が実際に上がるまで時間がかかることがあるようなので)
・nothing /internet.ini メッセージが出た場合の処置を追記。
「make」を入力すること。(これにより internet.iniファイルが既定値で作られる)
・実際の組込み例を紹介 Unit Cam Wi-Fi Camera
Ver.2.1 '22/08/25
・debug= を追加。整数値を指定。
・Wi-Fi未接続時のSerial.printの.を、120文字毎に改行。
Ver.2.0 '22/05/24
・内蔵不揮発性メモリー(フラッシュメモリ)の項目に、メインスケッチファイル名などを
書き込める sketch= を追加。
・ポート番号を変数で指定する方法がわからないことを明記。
・サンプルソースプログラム void loop() 内のコードを改善し実用性を向上。
・サンプルソースプログラム内の #include <WiFi.h> が画面に表示されないWeb記述の不具合を修正
Ver.1.0 '20/04/25 初稿
謝辞
本ソフトの開発に特に役立った資料を最後に列挙しました。この他にも役立った記事が色々
ありました。各著者に感謝します。
参考資料
1 DEKO ESP32-WROOM-32
2 GitHub SimpleWiFiServer.ino
3 mgo-tec電子工作 ESP-WROOM-32 ( ESP32 ) で Wi-Fi スマホ LED スイッチ作り
4 Ryo ESP32/arduino : ファイル分割
5 Tera Term Tera Term
直前の画面へは ブラウザの戻る をクリックしてください。Topに戻るにはHome