2025年9月22日月曜日

ESP32/arduino: AP(アクセスポイント)モードで WiFi設定を行う。

目的:

WiFi設定(接続先設定、IPアドレス 等)をスケッチには記述せず、スマホ等からAPモードでの接続で設定できる様にする。
"スマホからIPアドレス等のWiFi設定を行う”と同じ内容を LittleFs, WebServer を使用し、IDE2.x でコンパイルできるようにする。

背景:

以前 "スマホからIPアドレス等のWiFi設定を行う”でスケッチを作成したが、IDE2.x ではそのまま使用できなくなった。
この為、IDE2.x で使用できるように修正する必要があった。

動作概要:

・softAP で APモードでサーバ起動し、スマホ等から WiFi接続設定を行う。
 (APモードの時の ESP32 の SSID,パスワードは 固定値)
・設定したWiFi接続情報は、SPIFFS で 設定ファイルに保存する。
・設定ファイルが有り、接続先が設定されている場合は STA(ステーション)モードでサーバー起動する。
・STAモードで 接続できなかった場合は APモードでサーバー起動する。
・APモードのまま、メインの動作も可能。

接続手順:

  1. 最初は、接続設定がないため、ESP32 は AP モードで起動。
  2. スマホ等から、WiFi接続先として
    SSID  : ESP32_AP
    パスワード : password
    で接続できる。 
  3. 接続後、ブラウザで "192.168.4.1" にアクセスすると、下記設定画面が表示される。
  4. WiFi接続設定(SSID, PASSWORD, IPアドレス等) を設定し、STA MODE を選択して "設定"ボタンを押下すると、 ESP32 がリブートして 設定した WiFi 親機に接続する。
  5. スマホ等から、ブラウザで設定した IPアドレスにアクセスすると、下記 LED調光画面が表示される。
  6. LED 調光画面から、WiFi 設定画面 ボタンを押下すると再度 WiFiの設定画面に遷移する。
  7. WiFi 親機に接続できなかった場合は、再度 AP モードで立ち上がる。
  8. 設定画面で、AP MODE を選択した場合は、AP モードのまま、LED調光画面に遷移する。

修正点:

主な修正項目はIDE2.x 対応のための修正で、以下の通り。
  • SPIFFS から LittleFS に変更
  • WebServer を使用
  • led 制御 (ledcAttach) 変更
  • その他、記述の整理
修正前については "スマホからIPアドレス等のWiFi設定を行う”を参照。

スケッチ:

スケッチの詳細はコード内のコメント参照。

< WiFi 設定画面用 HTML >

<!DOCTYPE html><html lang='ja'><head><meta charset='UTF-8'>
<style>
    #base         {font-size:16pt; text-align:center; width:600px; border:solid 4px 00000000; background-color:#c0c0c0; }
    #text_box     {height: 25px; font-size:12pt; float:left ; text-align:left; width:45%; }
    #input_box    {height: 25px; font-size:12pt; float:right; text-align:left; width:55%; }
    #ip_box       {height: 25px; font-size:12pt; float:right; text-align:left; width:15%; }
    #radio_box    {font-size:12pt; clear:both; margin : 0% 20% ; width : 60% ; }
    #button_box   {font-size:12pt; clear:both; margin : 0% 20% ; width : 60% ; }
    #foot         {font-size:16pt; clear:both;}
    input.val     {width: 90%;}
    input.ip      {width: 20%;}
    input.button  {margin:10px 10% ; width: 25%;}
    input.radio   {margin:10px 0px 0px 15% ; }
</style>
 
<title>設定画面</title></head>
 
<body>
<div id="base">
  <p>設定画面</p>
  <div id="text_box">
    <span> WiFi 接続先 SSID </span>
  </div>
 <form  method="get">
  <div id="input_box">
      <input class='val' type='text' name='ssid' id='ssid' value=$ssid>
  </div>
  <div id="text_box">
    <span> WiFi 接続先 PASSWORD </span>
  </div>
  <div id="input_box">
      <input class='val' type='text' name='pass' id='pass' value=$pass>
  </div>
  <div id="text_box">
    <span> WiFi 接続  IP アドレス </span>
  </div>
  <div id="input_box">
      <input class='ip' type='number' name='ip1' id='ip1' min=0 max=255 value=$ip1 >
      <input class='ip' type='number' name='ip2' id='ip2' min=0 max=255 value=$ip2 >
      <input class='ip' type='number' name='ip3' id='ip3' min=0 max=255 value=$ip3 >
      <input class='ip' type='number' name='ip4' id='ip4' min=0 max=255 value=$ip4 >
  </div>
  <div id="text_box">
    <span> WiFi 接続  サブネットマスク</span>
  </div>
  <div id="input_box">
      <input class='ip' type='number' name='sn1' id='sn1' min=0 max=255 value=$sm1 >
      <input class='ip' type='number' name='sn2' id='sn2' min=0 max=255 value=$sm2 >
      <input class='ip' type='number' name='sn3' id='sn3' min=0 max=255 value=$sm3 >
      <input class='ip' type='number' name='sn4' id='sn4' min=0 max=255 value=$sm4 >
  </div>
  <div id="text_box">
    <span> WiFi 接続  デフォルトゲートウェイ</span>
  </div>
  <div id="input_box">
      <input class='ip' type='number' name='gw1' id='gw1' min=0 max=255 value=$gw1 >
      <input class='ip' type='number' name='gw2' id='gw2' min=0 max=255 value=$gw2 >
      <input class='ip' type='number' name='gw3' id='gw3' min=0 max=255 value=$gw3 >
      <input class='ip' type='number' name='gw4' id='gw4' min=0 max=255 value=$gw4 >
  </div>
  <div id="text_box">
    <span> WiFi 接続  DNSアドレス</span>
  </div>
  <div id="input_box">
      <input class='ip' type='number' name='dns1' id='dns1' min=0 max=255 value=$dns1 >
      <input class='ip' type='number' name='dns2' id='dns2' min=0 max=255 value=$dns2 >
      <input class='ip' type='number' name='dns3' id='dns3' min=0 max=255 value=$dns3 >
      <input class='ip' type='number' name='dns4' id='dns4' min=0 max=255 value=$dns4 >
  </div>
  <div id="radio_box">
      <input class='radio' type='radio' name='wifi_stamode' id='rad_sta' value='sta' $checked_sta > STA MODE
      <input class='radio' type='radio' name='wifi_stamode' id='rad_ap' value='ap' $checked_ap > AP MODE
  </div>
  <div id="button_box">
    <!--
      <button class='button' type='submit' name='set' id='set' onclick="location.href='/conf'" value='設定'>設定</button>
      <a href="/conf" class='button'>設定</a>
    -->
      <input class='button' type='submit' name='set' id='set' value='設定'>
      <input class='button' type='submit' name='set' id='set' value='キャンセル'>
  </div>
 </form>
 <div id="foot">
   <span>$footer</span>
 </div>
</div>
</body>
</html>

 < LED調光用 HTML >

<!DOCTYPE html><html lang='ja'><head><meta charset='UTF-8'>
<style>
    #base       {font-size:16pt; text-align:center; width:400px; border:solid 4px #93ff93; background-color:#f0f0f0; }
    #text_box   {height: 30px; font-size:12pt; float:left ; text-align:left; width:45%;}
    #button_box {font-size:12pt; clear:both;}
    #foot       {font-size:16pt; clear:both;}
    input       {margin:8px;width:100px;}
    div         {font-size:16pt;text-align:center;}
</style>
 
<title>Color LED Controller</title></head>
 
<body>
<div id="base">
  <p>LED ON/OFF</p>
  <form method='get'>
    <input type='submit' name='on' value='ON' />
    <input type='submit' name='off' value='OFF' />
  </form>
 
  <form method="get">
    <div id="button_box">
      <input class='button' type='submit' name='config' id='config' value='WiFi設定画面'>
    </div>
   </form>
 <div id="foot">
   <span>$footer</span>
 </div>
</div>
</body>
</html>

 < スケッチ (メイン) >

// +==========================================================================+
// |  WiFi Setting By AP mode                                                 |
// +==========================================================================+
#include <WiFi.h>                                // WiFi 使用の為
#include <WebServer.h>                           // WebServer 使用の為
#include <ArduinoJson.h>                         // JSOM 使用 の為
#include "FS.h"                                  // LittleFS 使用の為
#include "LittleFS.h"                            // LittleFs 使用に必要
//                                               //
#define DEBUG_HTML                               // Debug用 Serial 表示制御用
#define DEBUG                                    // Debug用 Serial 表示制御用
//                                               //
// +---------------------------------------------------------------------------+
// | WiFi 設定 他                                                              |
// +---------------------------------------------------------------------------+
//                                             //                             
// 動作モードフラグ ------------------------------------------------------------
bool stamode = true ;                          // WiFi STA 接続モード : true
bool sta_exec = false ;                        // WiFi STA接続モード実行中フラグ
bool config_mode = false ;                     // 初期設定モード ; true
bool config_exec = false ;                     // 初期設定実行中フラグ
char wifi_mode[16] = ""   ;                    // wifi mode
String foot_msg ="" ;                          // リブートメッセージ用
//                                             // 
// AP モード用 WIFI 設定 (AP : Access Point) -----------------------------------
const char      ap_ssid[] = "ESP32_AP";        // SSID for softAP                   
const char      ap_pass[] = "password";        // password for softAP
const IPAddress ap_ip(192, 168, 4, 1);         // IPアドレス for softAP
const IPAddress ap_subnet(255, 255, 255, 0);   // サブネットマスク for softAP
//                                             // 
// ST モード用 WIFI 設定 (ST : STation) ----------------------------------------
String    s_config ;                           // 設定ファイル用 String
char      st_ssid[128] = "" ;                  // SSID        for WiFi STA
char      st_pass[128] = "" ;                  // password    for WiFi STA
IPAddress st_ip(192,168,1,66) ;                // IP Address  for WiFi STA
IPAddress st_gw(192,168,1,1)  ;                // gate way    for WiFi STA
IPAddress st_sm(255,255,255,0) ;               // subnet mask for WiFi STA
IPAddress st_dns(192,168,1,1) ;                // dns address for WiFi STA
//                                             //
WebServer server(80);                          // WebServer オブジェクト生成
//                                             //
String    html_CONF ;                          // 設定用 HTML
String    html_MAIN ;                          // メイン HTML
//                                             //
// LED 調光処理用 ---------------------------------------------------------------
// -- for ledc                                 //
byte brightness = 0 ;                          // LED 明るさ設定 (0-255)
//                                             //
// +---------------------------------------------------------------------------+
// | ハンドル処理 : WEBからの要求に対する応答処理                              |
// +---------------------------------------------------------------------------+
// 受信した要求の内容を文字列に格納して返す      //
String get_client_msg() {                        //  受信した要求の内容を作成
  String s_req = "request param ----\n";         //    Clientからの要求
  s_req += "URI: " + server.uri() + "\n" ;       // 
  s_req += "Method: ";                           //
  s_req += (server.method() == HTTP_GET) ? "GET\n" : "POST\n"; //
  s_req += "Arguments: " + String(server.args()) + "\n" ; //
  for (uint8_t i = 0; i < server.args(); i++) {  //
    s_req += " " + server.argName(i) + ": " ;    //
    s_req += server.arg(i) + "\n" ;              //
  }                                              //
  s_req += "------------------ \n";              //
  Serial.print(s_req);                           // シリアルに表示
  return s_req ;                                 // 呼び出し元に文字列を応答
}                                                //                                                 
//                                               //
void handleRoot() {                              //メイン HTMLページを返す
  String s_wk ;                                  //
  Serial.println("-- handlRoot() ----") ;        //
  get_client_msg() ;                             // (debug) 受信メッセージ表示
  //                                             //
  if (server.hasArg("set")) {                    //                  
    proc_config() ;                              //  WiFi 設定用 ハンドル処理
    //                                           //
  } else {                                       //                       
    proc_main() ;                                //  Main処理用 ハンドル処理  
    //                                           //
  }                                              //
}                                                //
// +---------------------------------------------------------------------------+
// | arduino 初期化処理                                                        |
// +---------------------------------------------------------------------------+
void setup() {                                   //
  int res = 0 ;                                  // 結果格納用 (ワーク)
  //                                             //
  Serial.begin(115200);                          // シリアル 開始
  LittleFS.begin(true) ;                         // LittleFS 開始
  pinMode(2, OUTPUT);                            // set the LED pin mode
  delay(10) ;                                    //
  //                                             //
  // 初期設定用 HTML ファイルの読み込み ----------------------------------------
  Serial.println("") ;                           //
  Serial.println("-- start rd html_CONF file ---") ;  //
  res = rd_LittleFS("/Config.html",html_CONF) ;  // html_CONFにConfig.html を格納
  // 本体 HTML ファイルの読み込み ----------------------------------------------
  Serial.println("-- start rd html_MAIN file ---") ;  //
  res = rd_LittleFS("/main.html",html_MAIN) ;    // html_MAIN に main.html を格納
  // 初期設定ファイルを読み込み、グローバル変数に設定し、wifi,画面モードを決定 ---
  Serial.println("-- start rd_config --") ;      //
  res = rd_config() ;                            //
  //                                             //
  // wifiモード(stamode) に応じて AP か STA かを選択してサーバー起動 -------------
  if (stamode == false) {                        // APモードの場合softAP WiFi開始
    start_AP_server() ;                          // APモードでサーバー起動
    sta_exec = false ;                           //
  } else {                                       // STAモードの場合 Wifi 開始
    start_STA_server() ;                         // APモードでサーバー起動
    sta_exec = true ;                            //
  }                                              //
  //                                             //
  // 実行中のモード (設定かメインか) を設定 ------------------------------------
  if (config_mode) config_exec = true ;   // config_mode なら config_exec を '1'
  else config_exec = false ;                     //
  //                                             //
  Serial.println("Server start!");               //
  //                                             //
  // メイン処理用 初期化 ------------------------------------------------------
  ledcAttach(2,5000, 8);                         // attach pin 2 
  ledcWrite(0, 0);                               // initialize pin2 off     
  //                                             //
}                                                //
//                                               //
// +---------------------------------------------------------------------------+
// | arduino メインループ処理                                                  |
// +---------------------------------------------------------------------------+
void loop() {                                    //
  // HTML クライアント処理 ----------------------//-----------------------------
  server.handleClient();                         //
  //                                             //
}                                                //
//                                               //

 < スケッチ (WiFi設定用) >

// +===========================================================================+
// |  AP モード 用 処理                                                        |
// +===========================================================================+
// int rd_LiitleFs(String,String) : LittleFs から ファイルを 文字列に読み込む
// IPAddress stoip(String)        : 文字列を IPAddress に変換する
// void set_param(String,String) : 文字列を解析して 内部変数に変換してセットする
// void set_conf2param()      : 設定ファイル文字列を解析して内部変数にセットする 
// int  rd_config() : 初期設定ファイルから設定値を 設定ファイル用変数にセットする
// void start_AP_server()         : AP モード で サーバー開始
// void start_STA_server()        : STAtion モードでサーバー開始
// void dbgdisp_mode(String)      : デバッグ用 モードステータス表示
// void wr_config()               : 設定変数のファイルへの書き出し
// void set_form2param()          : クライアントからのデータを設定変数にセット
// void proc_config()             : クライアントからの要求処理
// void  send_CONF_html()         : 設定画面用 HTML の送信
//                                             // 
// +---------------------------------------------------------------------------+
// | LittleFs ファイルを String に読み込む                                     |
// +---------------------------------------------------------------------------+
int rd_LittleFS(String fname, String &sname) {   //
  File fp = LittleFS.open(fname,"r") ;           // ファイルをオープンする
  if (!fp) {                                     //  オープン失敗の場合
    Serial.print(fname) ;                        //
    Serial.println(" : file open error") ;       //
    return -1 ;                                  //    戻り値 -1
  }else {                                        //  オープン出来たら
    sname = fp.readString() ;                    //    String変数に読み込む
    fp.close() ;                                 //
  }                                              //
  return 0 ;                                     //  オープン出来た時のみ
}                                                //    戻り値 0
//                                               //
// +---------------------------------------------------------------------------+
// | 設定ファイルの内容を グローバル変数に 設定する                            |
// +---------------------------------------------------------------------------+
//                                             // 
// - 文字列 から IPAddress へ変換 ----------------------------------------------
IPAddress stoip(String &data) {                //
  IPAddress ip ;                               //
  String num = "" ;                            //
  int pos = 0 ;                                //
  while(data.charAt(pos) != '.') {             // 先頭から '.' までの文字を取得
    num += data.charAt(pos++) ;                //
  }                                            //
  ip[0] = num.toInt() ;                 // 数値に変換して 第1オクテット に 代入
  pos++ ;                                      // '.' の次から
  num="";                                      //
  while(data.charAt(pos) != '.') {             // '.' までの文字を取得
    num += data.charAt(pos++) ;                //
  }                                            //
  ip[1] = num.toInt() ;                  // 数値に変換して 第2オクテットに代入
  pos++ ;                                      // '.' の次から
  num="";                                      //
  while(data.charAt(pos) != '.') {             // '.' までの文字を取得
    num += data.charAt(pos++) ;                //
  }                                            //
  ip[2] = num.toInt() ;                        //
  pos++ ;                                      // '.' の次から
  num="";                                      // 
  while(data.charAt(pos) != '.') {         // '.' または 最後まで の 文字を取得
    num += data.charAt(pos++) ;                //
    if (pos > data.length()) break ;           //
  }                                            //
  ip[3] = num.toInt() ;                   // 数値に変換して 第4オクテットに代入
  //                                           //
  return ip ;                                  // IPAddress を戻り値とする
}                                              //
//                                             // 
// 設定用文字列を判定し、グローバル変数に設定 ---------------------------------
void set_param(String &name, String &data) {   //
  if (name.compareTo("st_ssid")==0) {          // 'st_ssid' の場合
    data.toCharArray(st_ssid,128) ;            //
  }                                            //
  if (name.compareTo("st_pass")==0) {          // 'st_pass' の場合
    data.toCharArray(st_pass,128) ;            //
  }                                            //
  if (name.compareTo("st_ip")==0) {            // 'st_ip' の場合
    st_ip = stoip(data) ;                      // 取得情報(文字列)をIPAddressに変換
  }                                            //
  if (name.compareTo("st_gw")==0) {            // 'st_gw' の場合
    st_gw = stoip(data) ;                      //
  }                                            //
  if (name.compareTo("st_sm")==0) {            // 'st_sm' の場合
    st_sm = stoip(data) ;                      //
  }                                            //
  if (name.compareTo("st_dns")==0) {           // 'st_dns' の場合
    st_dns = stoip(data) ;                     //
  }                                            //
  if (name.compareTo("wifi_mode")==0) {        // 'wifi_mode' の場合
    data.toCharArray(wifi_mode,16) ;           //
  }                                            //
}                                              //
// 設定ファイルの文字列を解析して内部変数にセットする -----------------------------------
void set_conf2param() {                        //
  int    pos = 0 ;                             //
  int    npos = 0 ;                            //
  String s_work ;                              //
  String s_name ;                              //
  String s_data ;                              //
//                                             //
// 記載内容を順次処理 ( 設定情報を取り出し、グローバル変数に設定する ) --------
  Serial.println("-- set config to param --") ; //
  while(1) {                                   //
    if (s_config.charAt(pos) == '/') {         // 先頭が '/' なら 次の行へ 
      npos = s_config.indexOf('\n',pos) ;      //
      pos = npos + 1 ;                         //
    } else {                                   //
      npos = s_config.indexOf(':',pos) ;       // ':' までの文字をs_name に取得
      if (npos == -1) break ;                  //   見つからなければ終了
      s_name = s_config.substring(pos,npos) ;  //
      s_name.trim() ;                          //
      pos = npos+1 ;                           // ポインタを ':' の次へ
      npos = s_config.indexOf('\n',pos) ;      // '\n' までの文字をs_data に取得
      if (npos == -1) npos = s_config.length() ;  //
      s_data = s_config.substring(pos,npos) ;  //
      s_data.trim() ;                          //
      pos = npos+1 ;                           //
      set_param(s_name,s_data) ;               // 取得した内容をグローバル変数に設定
    }                                          //
  }                                            //
}                                              //
//                                             //
// 初期設定ファイル をリードし、グローバル変数に値をセットする ----------------------
int rd_config() {                                //
  File fp       ;                                // 設定ファイル用ファイルポインタ
  int result = 0 ;                               // 戻り値
  String s_wd ;                                  //
  //                                             //
  if (LittleFS.exists("/config.txt")) {          // 設定ファイル存在確認
    // ファイルがあった場合 ---------------------//
    result = rd_LittleFS("/config.txt",s_config) ; // s_configにconfig.txtを格納
  } else {                                       //
    // ファイルが無かった場合 -------------------//
    Serial.println("設定ファイルなし") ;         // 無かったら、APモード
    result = -1 ;                                //
  }                                              //
  //                                             // 
  // ファイルが読み込めたら、グローバル変数にセットする
  if (result == 0) {                             //
    # ifdef DEBUG                                // デバッグ用表示
      Serial.println("-- s_config (config.txt) -- ") ;      //
      Serial.println(s_config ) ;                //
    # endif                                      //
    set_conf2param() ;                           // s_config の内容を変数に設定
  }                                              //
  // 初期設定ファイルの状態で wifiモード, 画面モードを設定 ----------------------
  if (result == 0) {                           // 変数に設定できた場合
    if (( strcmp(st_ssid,"") ==0) || (strcmp(st_pass,"") ==0)) {
      //                                       // ssid,pass 設定なければ
      stamode = false ;                        //   APモード
      if ( strcmp(wifi_mode,"ap") == 0)        // wifi_mode が "ap" なら
        config_mode = false ;                  //   メイン画面
      else                                     // wifi_mode が "ap" でなければ
        config_mode = true ;                   //   初期設定画面
    } else {                                   // ssid,pass の設定があれば、
      config_mode = false ;                    //   メイン画面
      if ( strcmp(wifi_mode,"ap") == 0)        // wifi_mode が "ap" なら
        stamode = false ;                      //   APモード
      else                                     // "ap" でなければ
        stamode = true  ;                      //   STAモード
    }                                          //
  } else {                                     // 変数に設定できなかった場合
    stamode = false ;                          //   APモード
    config_mode  = true ;                      //   初期設定画面
  }                                            //
  //                                           // 
  s_wd = (stamode ? "true" : "false" ) ;       //
  Serial.println("set stamode = " + s_wd) ;    //
  s_wd = (config_mode ? "true" : "false" ) ;   //
  Serial.println("set config_mode = " + s_wd) ;//
  return result ;                              //
}                                              //
//                                             //
// +---------------------------------------------------------------------------+
// | アクセスポイント モードで サーバーを起動                                  |
// +---------------------------------------------------------------------------+
void start_AP_server() {                       // AP モード で サーバー開始
  Serial.println(" AP Server exec") ;          //
  WiFi.softAP(ap_ssid, ap_pass);               // SSIDとパスの設定
  delay(100);                                  // delayが必要
  WiFi.softAPConfig(ap_ip, ap_ip, ap_subnet);  // IP adr,gateway,submskの設定
  IPAddress myIP = WiFi.softAPIP();            // WiFi.softAPIP()でWiFi起動
  //                                           // 
  server.on("/", HTTP_GET, handleRoot);        // メインHTML の設定
  //                                           // 
  server.begin();                              // サーバーを起動
}                                              //
//                                             //
// +---------------------------------------------------------------------------+
// | ステーションモードで サーバーを起動                                       |
// +---------------------------------------------------------------------------+
void start_STA_server() {                            //
  int lpcnt = 0 ;                                    // ループカウント
  int lpcnt2 = 0 ;                                   // ループカウント2
  //                                                 //
  WiFi.config(st_ip, st_gw, st_sm, st_dns);          // Set fixed IP address
  delay(10) ;                                        //
  WiFi.begin(st_ssid, st_pass);                  // wifi 開始
  lpcnt = 0 ;                                        // 
  lpcnt2 = 0 ;                                       //
  while (WiFi.status() != WL_CONNECTED) {            // 接続確認
      lpcnt += 1 ;                                   //
      if (lpcnt > 4) {                               //
        WiFi.begin(st_ssid, st_pass);            // 4回目(2秒) で再度開始指示
        lpcnt = 0 ;                                  //
        lpcnt2 += 1 ;                                //
      }                                              //
      if (lpcnt2 > 5) {                              // 2秒x5 接続できなければ、
        stamode = false ;                            // APモードにして
        ESP.restart() ;                              // 再起動
      }                                              //
      Serial.print(".");                             //
      delay(500);                                    //   0.5秒毎にチェック
  }                                                  //
  //                                                 // 
  server.on("/", HTTP_GET, handleRoot);              // メインHTML の設定
  //                                                 // 
  server.begin();                                    // サーバー開始
}                                                    //
//                                                   //
// +---------------------------------------------------------------------------+
// | デバッグ表示用                                                            |
// +---------------------------------------------------------------------------+
void dbgdisp_mode(String prefix) {                    //
  String s_wk ;                                       //
  # ifdef DEBUG_HTML                                  // デバッグ用表示
    s_wk = (sta_exec ? "true" : "false" ) ;           //
    Serial.println(prefix + " sta_exec = " + s_wk) ;  //
    s_wk = (stamode ? "true" : "false" ) ;            //
    Serial.println(prefix + " stamode  = " + s_wk) ;  //
    s_wk = (config_mode ? "true" : "false" ) ;        //
    Serial.println(prefix + " cfg_mode = " + s_wk) ;  //
    s_wk = (config_exec ? "true" : "false" ) ;        //
    Serial.println(prefix + " cfg_exec = " + s_wk) ;  //
  # endif                                             //
}                                                     //
//                                                    //
// +--------------------------------------------------------------------------+
// | クライアントからのフォームデータを変数にセットし、設定ファイルに書き出す |
// +--------------------------------------------------------------------------+
//                                                    //
// -- グローバル変数の内容を設定ファイルに書き出す  
void wr_config() {                                    //
  char s_work[128] ;                                  //
  File fp ;                                           //
//                                                    //
  // String に 変数の内容を書き込む ------------------//-----------------------
  sprintf(s_work,"st_ssid : %s\n",st_ssid) ;          //
  s_config = String(s_work) ;                         //
  sprintf(s_work,"st_pass : %s\n",st_pass) ;          //
  s_config += String(s_work) ;                        //
  sprintf(s_work,"st_ip   : %3d.%3d.%3d.%3d\n",       //
              st_ip[0],st_ip[1],st_ip[2],st_ip[3]) ;  //
  s_config += String(s_work) ;                        //
  sprintf(s_work,"st_sm   : %3d.%3d.%3d.%3d\n",       //
              st_sm[0],st_sm[1],st_sm[2],st_sm[3]) ;  //
  s_config += String(s_work) ;                        //
  sprintf(s_work,"st_gw   : %3d.%3d.%3d.%3d\n",       //
              st_gw[0],st_gw[1],st_gw[2],st_gw[3]) ;  //
  s_config += String(s_work) ;                        //
  sprintf(s_work,"st_dns  : %3d.%3d.%3d.%3d\n",       //
          st_dns[0],st_dns[1],st_dns[2],st_dns[3]) ;  //
  s_config += String(s_work) ;                        //
  sprintf(s_work,"wifi_mode : %s\n",wifi_mode) ;      //
  s_config += String(s_work) ;                        //
  //                                                  //
  // 設定ファイルに書き込む --------------------------//------------------------
  fp = LittleFS.open("/config.txt",FILE_WRITE) ;      // 設定ファイルを開く
  if (!fp) {                                          //
    Serial.println(" 設定ファイル オープンエラー !!") ;  //
  } else {                                            //
    // 初期設定ファイル書き込み -------------------------------------------------
    if(fp.print(s_config)) {                          // ファイルに書き込み
      Serial.println("s_config written") ;            //   終了メッセージ
    } else {                                          //
      Serial.println("s_config write error !!") ;     //   失敗メッセージ
    }                                                 //
    fp.close() ;                                      // ファイルクローズ
  }                                                   //
  //                                                  //
}                                                     //
// クライアントからのデータを設定変数にセットする ----------------------------- 
void set_form2param() {                               //
  String s_work ="" ;                                 //
//                                                    //
  // クライアントからのデータを グローバル変数にセットする。
  if (server.arg("set") == "設定") {          //
    if (server.hasArg("ssid")) {              //   受信メッセージを表示
      s_work = server.arg("ssid") ;           //   ssid に続く文字列を取得
      s_work.toCharArray(st_ssid,128) ;       //   変数にセット
    }                                         //
    if (server.hasArg("pass")) {              //   受信メッセージを表示
      s_work = server.arg("pass") ;           //   pass に続く文字列を取得
      s_work.toCharArray(st_pass,128) ;       //   変数にセット
    }                                         //
    if (server.hasArg("ip1")) {               //   受信メッセージを表示
      s_work = server.arg("ip1") ;            //   ip1 に続く数値を変数にセット
      st_ip[0] = s_work.toInt()  ;            //   ip1 に続く数値を変数にセット
    }                                         //
    if (server.hasArg("ip2")) {               //   受信メッセージを表示
      s_work = server.arg("ip2") ;            //   ip1 に続く数値を変数にセット
      st_ip[1] = s_work.toInt()  ;            //   ip1 に続く数値を変数にセット
    }                                         //
    if (server.hasArg("ip3")) {               //   受信メッセージを表示
      s_work = server.arg("ip3") ;            //   ip1 に続く数値を変数にセット
      st_ip[2] = s_work.toInt()  ;            //   ip1 に続く数値を変数にセット
    }                                         //
    if (server.hasArg("ip4")) {               //   受信メッセージを表示
      s_work = server.arg("ip4") ;            //   ip1 に続く数値を変数にセット
      st_ip[3] = s_work.toInt()  ;            //   ip1 に続く数値を変数にセット
    }                                         // 
    if (server.hasArg("gw1")) {               //   受信メッセージを表示
      s_work = server.arg("gw1") ;            //   ip1 に続く数値を変数にセット
      st_gw[0] = s_work.toInt()  ;            //   ip1 に続く数値を変数にセット
    }                                         //
    if (server.hasArg("gw2")) {               //   受信メッセージを表示
      s_work = server.arg("gw2") ;            //   ip1 に続く数値を変数にセット
      st_gw[1] = s_work.toInt()  ;            //   ip1 に続く数値を変数にセット
    }                                         //
    if (server.hasArg("gw3")) {               //   受信メッセージを表示
      s_work = server.arg("gw3") ;            //   ip1 に続く数値を変数にセット
      st_gw[2] = s_work.toInt()  ;            //   ip1 に続く数値を変数にセット
    }                                         //
    if (server.hasArg("gw4")) {               //   受信メッセージを表示
      s_work = server.arg("gw4") ;            //   ip1 に続く数値を変数にセット
      st_gw[3] = s_work.toInt()  ;            //   ip1 に続く数値を変数にセット
    }                                         //
    if (server.hasArg("sm1")) {               //   受信メッセージを表示
      s_work = server.arg("sm1") ;            //   ip1 に続く数値を変数にセット
      st_sm[0] = s_work.toInt()  ;            //   ip1 に続く数値を変数にセット
    }                                         //
    if (server.hasArg("sm2")) {               //   受信メッセージを表示
      s_work = server.arg("sm2") ;            //   ip1 に続く数値を変数にセット
      st_sm[1] = s_work.toInt()  ;            //   ip1 に続く数値を変数にセット
    }                                         //
    if (server.hasArg("sm3")) {               //   受信メッセージを表示
      s_work = server.arg("sm3") ;            //   ip1 に続く数値を変数にセット
      st_sm[2] = s_work.toInt()  ;            //   ip1 に続く数値を変数にセット
    }                                         //
    if (server.hasArg("sm4")) {               //   受信メッセージを表示
      s_work = server.arg("sm4") ;            //   ip1 に続く数値を変数にセット
      st_sm[3] = s_work.toInt()  ;            //   ip1 に続く数値を変数にセット
    }                                         //
    if (server.hasArg("dns1")) {              //   受信メッセージを表示
      s_work = server.arg("dns1") ;           //   ip1 に続く数値を変数にセット
      st_dns[0] = s_work.toInt()  ;           //   ip1 に続く数値を変数にセット
    }                                         //
    if (server.hasArg("dns2")) {              //   受信メッセージを表示
      s_work = server.arg("dns2") ;           //   ip1 に続く数値を変数にセット
      st_dns[1] = s_work.toInt()  ;           //   ip1 に続く数値を変数にセット
    }                                         //
    if (server.hasArg("dns3")) {              //   受信メッセージを表示
      s_work = server.arg("dns3") ;           //   ip1 に続く数値を変数にセット
      st_dns[2] = s_work.toInt()  ;           //   ip1 に続く数値を変数にセット
    }                                         //
    if (server.hasArg("dns4")) {              //   受信メッセージを表示
      s_work = server.arg("dns4") ;           //   ip1 に続く数値を変数にセット
      st_dns[3] = s_work.toInt()  ;           //   ip1 に続く数値を変数にセット
    }                                         //
    if (server.hasArg("wifi_stamode")) {      //   stamode set 
      s_work = server.arg("wifi_stamode") ;   //   ip1 に続く数値を変数にセット
      s_work.toCharArray(wifi_mode,16) ;      //   変数にセット
      if (s_work == "sta") {                  //   設定値により、モードをセット
        stamode = true ;                      // 
        config_mode = false ;                 // 
      } else {                                // 
        stamode = false ;                     // 
        config_mode = false ;                 // 
      }                                       //
    }                                         //
    // グローバル変数を 設定ファイルに書き出す 
    wr_config() ;                           // 設定を初期設定ファイルに書き出し
  } else {                                    //
    config_mode = false ;                     //
  }                                           //
  //                                          //
  dbgdisp_mode("set") ;                       //
}                                             //
//                                            //
// +--------------------------------------------------------------------------+
// | CONF_HTML 送信                                                           |
// +--------------------------------------------------------------------------+
void  send_CONF_html() {
  String htmlwk ;
 
  // 変数置換え処理 ------------------------------------------------------------
  htmlwk = html_CONF ;
  htmlwk.replace("$ssid",String(st_ssid)) ;
  htmlwk.replace("$pass",String(st_pass)) ;
  htmlwk.replace("$ip1",String(st_ip[0])) ;
  htmlwk.replace("$ip2",String(st_ip[1])) ;
  htmlwk.replace("$ip3",String(st_ip[2])) ;
  htmlwk.replace("$ip4",String(st_ip[3])) ;
  htmlwk.replace("$sm1",String(st_sm[0])) ;
  htmlwk.replace("$sm2",String(st_sm[1])) ;
  htmlwk.replace("$sm3",String(st_sm[2])) ;
  htmlwk.replace("$sm4",String(st_sm[3])) ;
  htmlwk.replace("$gw1",String(st_gw[0])) ;
  htmlwk.replace("$gw2",String(st_gw[1])) ;
  htmlwk.replace("$gw3",String(st_gw[2])) ;
  htmlwk.replace("$gw4",String(st_gw[3])) ;
  htmlwk.replace("$dns1",String(st_dns[0])) ;
  htmlwk.replace("$dns2",String(st_dns[1])) ;
  htmlwk.replace("$dns3",String(st_dns[2])) ;
  htmlwk.replace("$dns4",String(st_dns[3])) ;
  if (stamode) {                                // ステーションモード時
    htmlwk.replace("$checked_sta","checked") ;  // 
    htmlwk.replace("$checked_ap","") ;          //
  } else {                                      // アクセスポイントモード時
    htmlwk.replace("$checked_sta","") ;         //
    htmlwk.replace("$checked_ap","checked") ;   //
  }
  htmlwk.replace("$footer",foot_msg ) ;
  // --------------------------------------------------------------------------
  server.send(200, "text/html", htmlwk);        // HTMLを送信
}
//                                             //
// +---------------------------------------------------------------------------+
// | 設定用 ハンドル処理 : WEBからの要求に対する応答処理                       |
// +---------------------------------------------------------------------------+
void proc_config() {                           //メイン HTMLページを返す
  Serial.println("-- config ---------") ;      //
  //                                           //
  set_form2param() ;                           //
  //                                           //
  dbgdisp_mode("   ") ;                        //
  //                                           //
  if (stamode != sta_exec) {                   // sta_mode が変わった場合
    if (strcmp(wifi_mode,"ap") == 0){          //  リブートメッセージを設定
      foot_msg = "アクセスポイントモードに移行します。<br>" ;
      foot_msg += "この画面を閉じてアクセスポイントに接続して下さい。" ;
    }else{                                     //
      foot_msg = "ステーションモードに移行します。<br>"; 
      foot_msg += "この画面を閉じて 設定したアドレスに接続して下さい。" ;
    }                                          //
    if (config_exec) {                         //   初期設定中なら
      send_CONF_html() ;                       //     初期設定 HTML 送信
    } else {                                   //   メイン画面なら
      send_MAIN_html() ;                       //     メイン HTML 送信
    }                                          //    ( その後 リブート)
  } else {                                     // sta_mode が変わらない場合 
    if (config_mode) {                         //   次に初期設定を表示するなら
      send_CONF_html() ;                       //     初期設定 HTML 送信
      config_exec = true ;                     //
    } else {                                   //   次にメイン画面なら
       send_MAIN_html() ;                      //     メイン HTML 送信
       config_exec = false ;                   //
    }                                          // 
  }                                            //
  if (stamode != sta_exec) {                   // sta_mode が変わった場合
    Serial.println("------------------- リブートします------------------- ");
    delay(500);                                // 
    ESP.restart() ;                            // リブート
  }                                            //
}                                              //
 

 < スケッチ (LED調光用) >

// +===========================================================================+
// |  メイン処理                                                               |
// +===========================================================================+
// void send_MAIN_html()       // メインHTML を送信する
// void proc_main()            // メインHTML用ハンドル処理
// +---------------------------------------------------------------------------+
// | HTML 送信処理                                                             |
// +---------------------------------------------------------------------------+
// - CONF_HTML 送信                              //
void send_MAIN_html() {                          //
  String htmlwk ;                                //
  //                                             //
  htmlwk = html_MAIN ;                           // htmlwk に HTML をコピー
  htmlwk.replace("$footer",foot_msg ) ;          // 変数を値に置き換える
  //                                             //
  server.send(200, "text/html", htmlwk);         // HTMLを送信
  //                                             //
}                                                //
//                                               // 
void proc_main() {                               //
  if (server.hasArg("on")) {                     //                  
    brightness +=25 ;                            // 明るさを +25 
    Serial.print("brightness value : ");         //
    Serial.println(brightness);                  //
    // -- for ledc                               //
    ledcWrite(2, brightness) ;                   // チャネル#0 に Duty値設定
  } else if (server.hasArg("off")) {             //
    brightness = 0 ;                             // 明るさを "0" 
    Serial.print("brightness value : ");         //
    Serial.println(brightness);                  //
    // -- for ledc                               //
    ledcWrite(2, brightness) ;                   // チャネル#0 に Duty値設定
  } else if (server.hasArg("config")) {          //
    config_mode = true ;                         //
  } else {                                       //
  }                                              //
  dbgdisp_mode("   ") ;                          //
  if (config_mode) {                             // 次に初期設定を表示するなら
    send_CONF_html() ;                           //   初期設定 HTML 送信
    config_exec = true ;                         //
  } else {                                       //   次にメイン画面なら
     send_MAIN_html() ;                          //     メイン HTML 送信
     config_exec = false ;                       //
  }                                              // 
  send_CONF_html() ;                             //     初期設定 HTML 送信
}                                                //

0 件のコメント:

コメントを投稿