2019年6月23日日曜日

ESP32/arduino:テキストファイルをアップロードする

目的:

ESP32 へ 設定ファイル等のテキストファイルをアップロードできる様にする。
この時、ボタンではなく、リンク (a要素) の文字列をでダウンロードできる様にする。

方法:


  1. input タグ で type='file' を指定し、ファイル選択したら ファイル読み込みのjavascript を起動。
    この input は hidden 属性にして ボタンを表示させない。
  2. a要素でリンク文字列を設置し、押下されたら jabascript で 1の input を クリックする様にする。
  3. ファイル読み込みの javascript では、ファイルをテキストで読み込み、XMLHttpRequest を使って POST でファイル内容を送る。
    または、html 内で読み込んだファイルを処理する。
  4. ESP32側では、XMLHttpRequest で送信されたテキストを処理する。
XMLHttpRequest を POST で送信する場合は、xhr.send() の ()内に送信内容を記述する。
具体的な記述は、下記の例 を参照。

例:

(ファイル一式(.zip) は こちら)
softAPでWiFi設定 の 設定ファイル をアップロードできる様に修正。本例では、設定ファイルの内容を ESP32 に送信するが、ESP32 側では受信してシリアル出力のみ行う。
設定ファイルの内容で、WiFi設定画面の各要素の値の更新を行い、設定ボタンの押下で処理を行う。
<各画面サンプル>
 LED調光の画面 (メイン処理)

ダウンロードのリンクは設定画面に移動
WiFi設定画面

設定ボタンの下にリブート用チェックボックスを追加
その下に、ダウンロード、アップロードのリンクを追加

<html>


main.html (メイン画面)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<!DOCTYPE html><html lang='ja'><head><meta charset='UTF-8'>
<style>
    #base       {font-size:16pt; text-align:center; width:400px; border:solid  4px #8fbc8f; background-color:#f0f0f0; }
    #area_1     {font-size:12pt; text-align:center; width:100%;  border:dotted 0px #0000ff; }
    #area_1-1   {font-size:12pt; text-align:center; width:40%;   float:left; margin:0px 0px 0px 10%  ; border:dotted 0px #008080 }
    #area_1-2   {font-size: 8pt; text-align:center; width:40%;   float:left; margin:0px 10px 0px 0%  ; border:dotted 0px #800080 }
    #area_2     {font-size:12pt; text-align:center; width:100%;  clear:both; border:dotted 0px #00ff00; }
    #area_2-1   {font-size:12pt; text-align:left  ; width:25%;   float:left; margin:0px 0px 0px 15%  ; border:dotted 0px #008080 }
    #area_2-2   {font-size: 8pt; text-align:left  ; height:12pt; float:left; margin:10px 0px 0px 5%  ; border:dotted 0px #800080 }
    #foot       {font-size:14pt; clear:both; border:dotted 0px #808000 }
</style>
 
<title>Sample form</title></head>
 
<body>
<div id="base">
  <span> LED ON/OFF </span>
  <div id="area_1">
    <br>
    <form method="get">
      <div id="area_1-1">
      <input type='submit' name='on' value='LED_ON' />
      </div>
      <div id="area_1-2">
      <input type='submit' name='off' value='LED_OFF' />
      </div>
    </form>
    <br>
    <br>
    <br>
  </div>
  <div id="area_2">
    <form method="get">
      <div id="area_2-1">
        <input class='button' type='submit' name='config' id='config' value='WiFi 設定画面'>
      </div>
      <div id="area_2-2">
      </div>
     </form>
  </div>
 <div id="foot">
   <span>$footer</span>
 </div>
</div>
 
</body>
</html>

wifi_conf.html (WIFI 設定画面)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
<!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; }
    #area_1     {font-size:12pt; text-align:center; width:100%;  border:dotted 0px #0000ff; }
    #item_text  {font-size:12pt; text-align:left;   width:45%;   height: 25px; float:left ; }
    #input_box  {font-size:12pt; text-align:left;   width:55%;   height: 25px; float:right; }
    #ip_box     {font-size:12pt; text-align:left;   width:15%;   height: 25px; float:right; }
    #radio_box  {font-size:12pt; text-align:center; width:80% ;  margin: 0% 0%; clear:both; }
    #area_2     {font-size:12pt; text-align:center; width:100%;  border:dotted 0px #00ff00; }
    #rbt_chk    {font-size:10pt; text-align:left; margin : 0% 0% 0% 20% ; }
    #area_3     {font-size:12pt; text-align:center; width:100%;  border:dotted 0px #00ff00; }
    #area_3-1   {font-size:12pt; text-align:left  ; width:25%;   float:left;  margin:0px 0px 0px 15%  ; border:dotted 1px #008080 }
    #area_3-2   {font-size: 8pt; text-align:left  ; height:12pt; float:left;  margin:10px 0px 0px 25% ; border:dotted 1px #800080  }
    #foot        {font-size:16pt; clear:both;}
    input.val    {width: 90%;}
    input.ip     {width: 20%;}
    input.button {margin:10px 10% 0% 10%; width: 25%;}
    input.radio  {margin:10px 0px 0px 15% ; }
</style>
 
<title>設定画面</title></head>
 
<body>
<div id="base">
  <p>設定画面</p>
  <div id="item_text">
    <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="item_text">
    <span> WiFi 接続先 PASSWORD </span>
  </div>
  <div id="input_box">
      <input class='val' type='text' name='pass' id='pass' value=$pass>
  </div>
  <div id="item_text">
    <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="item_text">
    <span> WiFi 接続  サブネットマスク</span>
  </div>
  <div id="input_box">
      <input class='ip' type='number' name='sm1' id='sm1' min=0 max=255 value=$sm1 >
      <input class='ip' type='number' name='sm2' id='sm2' min=0 max=255 value=$sm2 >
      <input class='ip' type='number' name='sm3' id='sm3' min=0 max=255 value=$sm3 >
      <input class='ip' type='number' name='sm4' id='sm4' min=0 max=255 value=$sm4 >
  </div>
  <div id="item_text">
    <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="item_text">
    <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="area_2">
      <input class='button' type='submit' name='set' id='set' value='設定'>
      <input class='button' type='submit' name='rtn' id='rtn' value='戻る'>
    <div id="rbt_chk">
      <input type="checkbox" name="rebt" id="rebt" value= "on" $checked_rebt autocomplete="off" >
      <span>設定時、リブートする</span>
    </div>
  </div>
 </form>
 <div id="area_3">
     
    <div id="area_3-2">
      <span>設定を </span>
      <a href='javascript:confdl();'>ダウンロード</a>
      <span>/ </span>
      <a href='javascript:selfile();'>アップロード</a>
      <span>する</span>
      <form id='form_ul'>
      <input name='fsel' id='fsel' type='file' onchange='conful()' hidden />
      </form>
     </div>
   <br>
 </div>
 <div id="foot">
   <span>$footer</span>
 </div>
</div>
 
  <script>
function confdl() {
  "use strict";
 
  var xhr = new XMLHttpRequest();
  xhr.open("get", "?confld=CLD");
  xhr.setRequestHeader('Cache-Control', 'no-cache');
  xhr.setRequestHeader('If-Modified-Since', 'Thu, 01 Jun 1970 00:00:00 GMT');
  xhr.responseType = 'document' ;
  
  xhr.onreadystatechange = function() {
    if( (xhr.readyState == 4) && (xhr.status == 200) ) {
      var filename = "config.txt" ;
      var str = xhr.response.getElementById("output").innerHTML ;
      var blob = new Blob([str],{type:'text/plain'}) ;
      if (window.navigator.msSaveBlob) {
      //window.navigator.msSaveBlob(blob, filename);
        window.navigator.msSaveOrOpenBlob(blob,filename) ;
      }
      else {
        var objectURL = window.URL.createObjectURL(blob);
        var link = document.createElement("a");
        document.body.appendChild(link);
        link.href = objectURL;
        link.download = filename;
        link.click();
        document.body.removeChild(link);
      }
    }
  }
  xhr.send("");
}
 
function selfile() {
  document.getElementById('fsel').click() ;
}
 
function conful() {
  "use strict";
 
  var ulfile  = document.getElementById("fsel") ;  // ファイル選択 id=fsel のエレメントを取得
  var file = ulfile.files[0] ;                     // 選択された ファイルオブジェクトを取得
  var reader = new FileReader() ;                  // ファイルリーダーオブジェクトの生成
  var pos = 0 ;                                    // テキスト解析用のポインタ
  var work = "";                                   // 一時格納用の変数
  var res = "";                                    // 一時格納用の変数
 
  var xhr_ul = new XMLHttpRequest();               // ファイル送信用の XHR オブジェクト生成
  xhr_ul.open("post", "?conful");                  // XHR の HTTPリクエスト を OPEN で作成
  xhr_ul.setRequestHeader('Cache-Control', 'no-cache');  // キャッシュ無効化
  xhr_ul.setRequestHeader('If-Modified-Since', 'Thu, 01 Jun 1970 00:00:00 GMT');
  xhr_ul.responseType = 'document' ;               // response type を document に設定
 
  xhr_ul.onreadystatechange = function() {
    if( (xhr_ul.readyState == 4) && (xhr_ul.status == 200) ) {
    // XHR の応答があった場合の処理 : 特になし 
    }
  }
 
  reader.readAsText(file) ;          // ファイルオブジェクトをテキストとして読み込む
  reader.onload = function(e){       // 読み込みが終了した場合に実行
    console.log(reader.result) ;
      // テキストを解析して、各要素に値を代入する ----------------------------
      // 読み込んだ設定ファイルから ssid を取得して 要素に代入
      pos = reader.result.indexOf("wifi_ssid") ;
      pos = reader.result.indexOf(":",pos) ;
      res = reader.result.substr(pos+1).split("\n") ;
      document.getElementById('ssid').value = res[0].trim() ;
      // 読み込んだ設定ファイルから パスワード を取得して 要素に代入
      pos = reader.result.indexOf("wifi_pass") ;
      pos = reader.result.indexOf(":",pos) ;
      res = reader.result.substr(pos+1).split("\n") ;
      document.getElementById('pass').value = res[0].trim() ;
      // 読み込んだ設定ファイルから IPアドレス を取得して 要素に代入
      pos = reader.result.indexOf("wifi_ip") ;
      pos = reader.result.indexOf(":",pos) ;
      res = reader.result.substr(pos+1).split("\n") ;
      res = res[0].split(".") ;
      document.getElementById('ip1').value = res[0].trim() ;
      document.getElementById('ip2').value = res[1].trim() ;
      document.getElementById('ip3').value = res[2].trim() ;
      document.getElementById('ip4').value = res[3].trim() ;
      // 読み込んだ設定ファイルから サブネットマスク を取得して 要素に代入
      pos = reader.result.indexOf("wifi_sm") ;
      pos = reader.result.indexOf(":",pos) ;
      res = reader.result.substr(pos+1).split("\n") ;
      res = res[0].split(".") ;
      document.getElementById('sm1').value = res[0].trim() ;
      document.getElementById('sm2').value = res[1].trim() ;
      document.getElementById('sm3').value = res[2].trim() ;
      document.getElementById('sm4').value = res[3].trim() ;
      // 読み込んだ設定ファイルから ゲートウェイアドレス を取得して 要素に代入
      pos = reader.result.indexOf("wifi_gw") ;
      pos = reader.result.indexOf(":",pos) ;
      res = reader.result.substr(pos+1).split("\n") ;
      res = res[0].split(".") ;
      document.getElementById('gw1').value = res[0].trim() ;
      document.getElementById('gw2').value = res[1].trim() ;
      document.getElementById('gw3').value = res[2].trim() ;
      document.getElementById('gw4').value = res[3].trim() ;
      // 読み込んだ設定ファイルから DNSアドレス を取得して 要素に代入
      pos = reader.result.indexOf("wifi_dns") ;
      pos = reader.result.indexOf(":",pos) ;
      res = reader.result.substr(pos+1).split("\n") ;
      res = res[0].split(".") ;
      document.getElementById('dns1').value = res[0].trim() ;
      document.getElementById('dns2').value = res[1].trim() ;
      document.getElementById('dns3').value = res[2].trim() ;
      document.getElementById('dns4').value = res[3].trim() ;
      // 読み込んだ設定ファイルから wifiモード を取得して 要素に代入
      pos = reader.result.indexOf("wifi_mode") ;
      pos = reader.result.indexOf(":",pos) ;
      res = reader.result.substr(pos+1).split("\n") ;
      if (res[0] == "ap")
        document.getElementById('rad_ap').checked = true ;
      else
        document.getElementById('rad_sta').checked = true ;
 
      // XHR を送信。 (ファイルのテキストを ESP32 に送信 )
      xhr_ul.send(reader.result);
  } ;
}
 
  </script>
 
</body>
</html>

wifi.resp.html (XHR 応答用)
1
2
3
4
5
<!DOCTYPE html><html lang='ja'>
  <head> <title>Color LED Controller</title></head>
  <html> <body>
    <output id='output'>$conf_text</output>
  </body> </html>

<ソース (.ino)>


test_AP3.ino (メインスケッチ)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
#include <WiFi.h>                                 // WiFi 使用の為
#include "FS.h"                                   // SPIFFS 使用の為
#include "SPIFFS.h"                               // SPIFFS 使用の為
                                                  //
#define DEBUG_HTML                              // Debug用 Serial 表示制御用
#define DEBUG                                   // Debug用 Serial 表示制御用
                                                  //
// -----------------------------------------------------------------------------
//  WiFi 設定関連 定義                                                       --
// -----------------------------------------------------------------------------
// AP モード用 WIFI 設定 -------------------------//
const char ssid[] = "ESP32_AP";                   // SSID for softAP
const char pass[] = "password";                   // password for softAP
const IPAddress ip(192, 168, 4, 1);               // IPアドレス for softAP
const IPAddress subnet(255, 255, 255, 0);         // サブネットマスク for softAP
                                                  //
// wifi_設定処理用 -------------------------------//
String s_config ;                                 // 設定ファイル用 String
char wifi_ssid[128] = "" ;                        // SSID        for WiFi STA
char wifi_pass[128] = "" ;                        // password    for WiFi STA
IPAddress wifi_ip(192,168,1,66) ;                 // IP Address  for WiFi STA
IPAddress wifi_gw(192,168,1,1)  ;                 // gate way    for WiFi STA
IPAddress wifi_sm(255,255,255,0) ;                // subnet mask for WiFi STA
IPAddress wifi_dns(192,168,1,1) ;                 // dns address for WiFi STA
int  set_reboot = 0 ;                             // 設定時リブート
char wifi_mode[16] = ""   ;                       // wifi mode
String foot_msg ="" ;                             // リブートメッセージ用
bool  rebootreq = false ;                         // リブート要求フラグ
bool  wifi_confdl = false ;                       // wifi 設定ダウンロード
bool  wifi_conful = false ;                       // wifi 設定アップロード
                                                  //
WiFiServer server(80);                            //
                                                  //
// 動作モードフラグ ------------------------------//
#define WIFI_CONF   0                             // HTML選択用 定義
#define MAIN        1                             //
                                                  //
bool stamode = true ;                             // WiFi STAモード : true
bool sta_exec = false ;                           // WiFi STAモード実行中フラグ
int  html_mode = MAIN ;                           // HTML選択 : MAIN
int  html_exec = MAIN ;                           // 実行中 HTML : MAIN
                                                  //
// -----------------------------------------------------------------------------
// | HTML ファイル名等 定義                                                   |
// -----------------------------------------------------------------------------
const char fname_wfCONF[] = "/wifi_conf.html" ;   // WiFi 設定用 HTMLファイル名
const char fname_wfRESP[] = "/wifi_resp.html" ;   // WiFi XHR応答用 HTMLファイル名
const char fname_MAIN[]   = "/main.html"   ;      // メイン HTML ファイル名
                                                  //
String html_wfCONF ;                              // WIFI設定用 HTML
String html_wfRESP ;                              // XHS レスポンス用 HTML
String html_MAIN ;                                // メイン HTML
                                                  //
// -----------------------------------------------------------------------------
                                                  //
// -----------------------------------------------------------------------------
//  MAIN 処理 定義                                                            --
// -----------------------------------------------------------------------------
// LED 調光処理用 --------------------------------//
byte brightness = 0 ;                             // LED 明るさ設定 (0-255)
                                                  //
// -----------------------------------------------------------------------------
                                                  //
// -----------------------------------------------------------------------------
//  arduino 初期化処理                                                        --
// -----------------------------------------------------------------------------
void setup() {                                    //
  int res = 0 ;                                   // 結果格納用 (ワーク)
                                                  //
  Serial.begin(115200);                           // シリアル 開始
  SPIFFS.begin(true) ;                            // SPIFFS 開始
                                                  //
  //HTML ファイルの読み込み ----------------------// HTML を変数に格納
  res = rd_SPIFFS(fname_wfCONF,html_wfCONF);      //  wifi設定用HTML
  res = rd_SPIFFS(fname_wfRESP,html_wfRESP) ;     //  wifi XHR応答用のHTML
  res = rd_SPIFFS(fname_MAIN,html_MAIN) ;         //  メイン処理のHTML
                                                  //
  // WiFi設定を読み込み、変数に設定しモードを決定 //
  res = rd_config() ;                             //
                                                  //
  // wifiモード(stamode) に応じてサーバ起動 ------//
  if (stamode == false) {                         // APモード時  softAP WiFi 開始
    start_AP_server() ;                           //   APモードでサーバー起動
    sta_exec = false ;                            //
  } else {                                        // STAモード時  Wifi 開始
    start_STA_server() ;                          //   STAモードでサーバー起動
    sta_exec = true ;                             //
  }                                               //
                                                  //
  // 実行中のモード (設定かメインか) を設定 ------//
  html_exec = html_mode ;                         // 実行中の html_mode を 設定
                                                  //
  Serial.println("Server start!");                //
                                                  //
  // メイン処理用 初期化 -----------------------------------------------------
  ledcSetup(0, 5000, 8);                          // channel:0,周波数:5000Hz, 8bit
  ledcAttachPin(2,0);                             // attach pin 2 to channel 0
  ledcWrite(0, 0);                                // initialize channel 0 to off    
                                                  //
}                                                 //
// -----------------------------------------------------------------------------
 
 
// -----------------------------------------------------------------------------
//  arduino メインループ処理                                                  --
// -----------------------------------------------------------------------------
void loop() {                                     //
  WiFiClient client = server.available();         //
  String line   = "" ;                            // クライアントからの入力用
  int xhr = 0 ;                                   // xhr 要求フラグ
  bool post_req = false ;                         // POST 要求フラグ
  char buf[257] ;                                 // 受信バッファ
  int  n ;                                        // 受信数用
                                                  //
  // HTML クライアント処理 -----------------------//
  if (client) {                                   //
    Serial.println(" +++++++++++++++++ new client! +++++++++++++++++ ");
    while (client.connected()) {                  // Client から接続されたとき
      if (client.available()) {                   // Client からのデータが有る間
        line = client.readStringUntil('\n');      // 1行分フォームデータを取得
        # ifdef DEBUG_HTML                        //
          Serial.println(line) ;                  //
        # endif                                   //
        if (line.indexOf("GET /?") != -1) {       // GET 処理
          if (html_mode == WIFI_CONF){            // 初期設定用 フォームデータ処理
            xhr = set_form2param(line) ;          //   フォームデータを変数に格納
          } else {                                // メイン用 処理
            xhr = proc_main(line) ;               //   フォームデータのメイン処理
          }                                       //
        }                                         //
        if (line.indexOf("POST /") != -1) {       // POST 要求の場合
          post_req = true ;                       //   POSTを受信したことを記憶
          if (line.indexOf("?conful") != -1) {    //     upload の場合 
            wifi_conful = true ;                  //       アップロードであることを記憶
          }                                       //
        }                                         //
        // 最終行(空行)を受信した時 --------------//
        if (line.length() == 1 && line[0] == '\r'){ // 空行の場合
          if (post_req) {                         //  POST 要求の場合
            line = ""  ;                          //    データ格納用変数初期化
            while (n=client.available()) {        //    残りデータを全て受信
              if (n<256){                         //   
                client.readBytes(buf,n) ;         //
                buf[n] = 0 ;                      //
              } else {                            //
                client.readBytes(buf,256) ;       //
                buf[256] = 0 ;                    //
              }                                   //
              line += buf ;                       //
            }                                     //
            // POST データ処理 -------------      //
            if (html_mode == WIFI_CONF){          // wifi設定用 フォームデータ処理
              if (wifi_conful == true) {          //   アップロードの場合
                Serial.println(" アップロード :") ; //   内容をシリアルに表示
                Serial.print(line) ;              //
                Serial.println("") ;              //
                wifi_conful = false ;             //   アップロード処理終了
              } else {                            //
                xhr = set_form2param(line) ;      //   フォームデータを変数に格納
              }                                   //
            } else {                              // メイン用 処理
              xhr = proc_main(line) ;           // フォームデータ(POST)のメイン処理
            }                                     //
          }                                       //
          // -- 最終処理 -------------------------//
   if (stamode != sta_exec) {              // sta_mode が変わった場合
     if (strcmp(wifi_mode,"ap") == 0){     //  リブートメッセージを設定
       foot_msg = "アクセスポイントモードに移行します。<br>" ;
       foot_msg += "この画面を閉じてアクセスポイントに接続して下さい。" ;
     }else{
       foot_msg = "ステーションモードに移行します。<br>";
       foot_msg += "この画面を閉じて 設定したアドレスに接続して下さい。" ;
     }                                     //
            if (html_exec == WIFI_CONF) {         //   初期設定中なら
              send_wfCONF_html(client) ;          //     初期設定 HTML 送信
     } else {                              //   メイン画面なら
              send_MAIN_html(client) ;            //     メイン HTML 送信
       html_exec = MAIN ;                  //
     }                                     // 
            rebootreq = true ;                    //   リブート要求セット
          } else {                                // sta_mode が変わらない場合
            if (xhr) {                            //   XHR の場合 (WiFi設定のみ)
              send_wfRESP_html(client) ;          //     WiFi XHR応答HTML 送信
            } else if (html_mode == WIFI_CONF) {  //   次に初期設定を表示するなら
              send_wfCONF_html(client) ;          //     WiFi設定 HTML 送信
            } else {                              //    メイン設定画面A
              send_MAIN_html(client) ;            //     メイン HTML 送信
            }                                     //
     html_exec = html_mode ;               //   実行中の HTMLモードを更新
   }                                       //
   # ifdef DEBUG_HTML                      //
     Serial.print("Send HTML : ") ;        //
            Serial.println(html_mode) ;           //
   # endif                                 //
          break ;                                 // ループ終了
        }                                         //
 //-------------------------------------------------------------------
      }                                           //
    }                                             //
    // 接続が切れた場合 ------------------------------------------------------
    client.stop();                                //
    Serial.println("client disonnected");         //
    Serial.println("----------------------------------------------------");
  }                                               //
                                                  //
  if (rebootreq) {                                // リブート要求時
    Serial.println("------------------- リブートします------------------- ");
    delay(500);                                   //
    ESP.restart() ;                               // リブート
  } else {                                        //
  }                                               //
  // --------------------------------------------------------------------------
                                                  //
}                                                 //
                                                  //

led_ctrl.ino.ino (LED調光処理用)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// *****************************************************************************
// * SPIFFS ファイルを String に読み込む                                       *
// *****************************************************************************
int rd_SPIFFS(String fname, String &sname) {   //
  File fp = SPIFFS.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
                                               //
// ****************************************************************************
// * ステーションモードで サーバーを起動                                      *
// ****************************************************************************
void start_STA_server() {                      //
  int lpcnt = 0 ;                              // ループカウント
  int lpcnt2 = 0 ;                             // ループカウント2
                                               //
  WiFi.config(wifi_ip, wifi_gw, wifi_sm, wifi_dns);  // Set fixed IP address
  delay(10) ;                                  //
  WiFi.begin(wifi_ssid, wifi_pass);            // wifi 開始
  lpcnt = 0 ;                                  //
  lpcnt2 = 0 ;                                 //
  while (WiFi.status() != WL_CONNECTED) {      // 接続確認
      lpcnt += 1 ;                             //
      if (lpcnt > 4) {                         //
        WiFi.begin(wifi_ssid, wifi_pass);      // 4回目(2秒) で再度開始指示
        lpcnt = 0 ;                            //
        lpcnt2 += 1 ;                          //
      }                                        //
      if (lpcnt2 > 5) {                        // 2秒x5 接続できなければ、
        stamode = false ;                      // APモードにして
        ESP.restart() ;                        // 再起動
      }                                        //
      Serial.print(".");                       //
      delay(500);                              //   0.5秒毎にチェック
  }                                            //
  server.begin();                              // サーバー開始
}                                              //
                                               //
// *****************************************************************************
// * HTML 送信処理                                                             *
// *****************************************************************************
                                               //
// ----------------------------------------------------------------------------
// - MAIN_HTML 送信                                                           -
// ----------------------------------------------------------------------------
void send_MAIN_html(WiFiClient client) {       //
  String htmlwk ;                              //
                                               //
  htmlwk = html_MAIN ;                         // htmlwk に HTML をコピー
  htmlwk.replace("$footer",foot_msg ) ;        // 変数を値に置き換える
                                               //
  send_html(client,htmlwk) ;                   // HTML 送信処理
                                               //
}                                              //
                                               //
// ---------------------------------------------------------------------------
// - HTML 送信処理                                                            -
// ----------------------------------------------------------------------------
void send_html(WiFiClient client, String &html ) { //
    client.println("HTTP/1.1 200 OK");         //
    client.println("Content-type:text/html");  //
    client.println();                          //
                                               //
    client.print(html) ;                       //
                                               //
    # ifdef DEBUG                              //
      Serial.println( " --- send html --- ");  //
    #endif                                     //
    # ifdef DEBUG_HTML                         //
    //  Serial.print(html) ;                   //
    #endif                                     //
}                                              //
                                               //
// *****************************************************************************
// * メイン処理                                                                *
// *****************************************************************************
// クライアント要求処理 --------------------------------------------------------
int  proc_main(String &line) {                 //
  String s_work ="" ;                          //
  int xhr = 0 ;                                //
                                               //
  if (line.indexOf("config=") != -1) {         // config
    html_mode=WIFI_CONF;                       //   HTML を WiFi設定 にする
  }                                            //
  if (line.indexOf("on=LED_ON") != -1) {       // "on"が押下された時
    brightness +=25 ;                          // 明るさを +25
    // -- for ledc                             //
    ledcWrite(0, brightness) ;                 // チャネル#0 に Duty値設定
  }                                            //
  if (line.indexOf("off=LED_OFF") != -1) {     // "off"が押下された時
    brightness = 0 ;                           // 明るさを "0"
    // -- for ledc                             //
    ledcWrite(0, brightness) ;                 // チャネル#0 に Duty値設定
  }                                            //
                                               //
  return xhr ;                                 //
}                                              //
                                               //
// -----------------------------------------------------------------------------

wifi_config.ino (WIFI 設定用)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
// -----------------------------------------------------------------------------
//  WiFi 設定関連 定義                                                       --
// -----------------------------------------------------------------------------
// *****************************************************************************
// *  初期設定ファイル をリードし、グローバル変数に値をセットする              *
// *****************************************************************************
int rd_config() {                              //
  File fp       ;                              // 設定ファイル用ファイルポインタ
  int result = 0 ;                             // 戻り値
                                               //
  if (SPIFFS.exists("/config.txt")) {          // 設定ファイル存在確認
    // ファイルがあった場合 -------------------//
    result = rd_SPIFFS("/config.txt",s_config) ; // s_config に config.txt を格納
  } else {                                     //
    // ファイルが無かった場合 -----------------//
    Serial.println("WiFi設定ファイルなし") ;   // 無かったら、APモード
    result = -1 ;                              //
  }                                            //
                                               //
  // ファイルが読み込めたら、グローバル変数にセットする
  if (result == 0)                             //
    # ifdef DEBUG                              // デバッグ用表示
      Serial.println("--- s_config --- ") ;    //
      Serial.println(s_config ) ;              //
    # endif                                    //
    set_conf2wifiparam(s_config) ;             // s_config の内容を変数に設定
  // 初期設定ファイルの状態で wifiモード, 画面モードを設定 ----------------------
  if (result != -1) {                          // 変数に設定できた場合
    if (( strcmp(wifi_ssid,"") ==0) || (strcmp(wifi_pass,"") ==0)) {
                                               // ssid,pass 設定なければ
      stamode = false ;                        //   APモード
      if ( strcmp(wifi_mode,"ap") == 0){       // wifi_mode が "ap" なら
        html_mode = MAIN ;                     //   メイン画面
      }else{                                   // wifi_mode が "ap" でなければ
        html_mode = WIFI_CONF ;                //   初期設定画面
      }                                        //
    } else {                                   // ssid,pass の設定があれば、
      html_mode = MAIN ;                       //   メイン画面
      if ( strcmp(wifi_mode,"ap") == 0)        // wifi_mode が "ap" なら
        stamode = false ;                      //   APモード
      else                                     // "ap" でなければ
        stamode = true  ;                      //   STAモード
    }                                          //
  } else {                                     // 変数に設定できなかった場合
    stamode = false ;                          //   APモード
    html_mode = WIFI_CONF ;                    //   初期設定画面
  }                                            //
                                               //
  return result ;                              //
}                                              //
                                               //
// ----------------------------------------------------------------------------
// - 設定ファイルの内容を グローバル変数に 設定する                           -
// ----------------------------------------------------------------------------
void set_conf2wifiparam(String &conf) {        //
  int    pos = 0 ;                             //
  int    npos = 0 ;                            //
  String s_work ;                              //
  String s_name ;                              //
  String s_data ;                              //
  // 記載内容を順次処理 ( 設定情報を取り出し、グローバル変数に設定する ) ------
  while(1) {
    if (conf.charAt(pos) == '/') {             // 先頭が '/' なら 次の行へ
      npos = conf.indexOf('\n',pos) ;          //
      pos = npos + 1 ;                         //
    } else {                                   //
      npos = conf.indexOf(':',pos) ;           // ':' までの文字をs_name に取得
      if (npos == -1) break ;                  //   見つからなければ終了
      s_name = conf.substring(pos,npos) ;      //
      s_name.trim() ;                          //
      pos = npos+1 ;                           // ポインタを ':' の次へ
      npos = conf.indexOf('\n',pos) ;          // '\n' までの文字をs_data に取得
      if (npos == -1) npos = conf.length() ;   //
      s_data = conf.substring(pos,npos) ;      //
      s_data.trim() ;                          //
      pos = npos+1 ;                           //
      set_wifiparam(s_name,s_data) ;           // 取得内容をグローバル変数に設定
    }                                          //
  //disp_param() ;                             //
  }                                            //
}                                              //
                                               //
// - 設定内容を判定し、グローバル変数に設定 ------------------------------------
void set_wifiparam(String &name, String &data) {   //
  if (name.compareTo("wifi_ssid")==0) {        // 'wifi_ssid' の場合
    data.toCharArray(wifi_ssid,128) ;          //
  }                                            //
  if (name.compareTo("wifi_pass")==0) {        // 'wifi_pass' の場合
    data.toCharArray(wifi_pass,128) ;          //
  }                                            //
  if (name.compareTo("wifi_ip")==0) {          // 'wifi_ip' の場合
    wifi_ip = stoip(data) ;                    //  取得文字列 をIPAddressに変換
  }                                            //
  if (name.compareTo("wifi_gw")==0) {          // 'wifi_gw' の場合
    wifi_gw = stoip(data) ;                    //
  }                                            //
  if (name.compareTo("wifi_sm")==0) {          // 'wifi_sm' の場合
    wifi_sm = stoip(data) ;                    //
  }                                            //
  if (name.compareTo("wifi_dns")==0) {         // 'wifi_dns' の場合
    wifi_dns = stoip(data) ;                   //
  }                                            //
  if (name.compareTo("wifi_mode")==0) {        // 'wifi_mode' の場合
    data.toCharArray(wifi_mode,16) ;           //
  }                                            //
  if (name.compareTo("set_reboot")==0) {       // 'set_reboot' の場合
    set_reboot = stoip(data) ;                 //
  }                                            //
//disp_param() ;                               //
}                                              //
                                               //
// - 文字列 から 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 start_AP_server() {               //
  Serial.println(" AP Server exec") ;  //
  WiFi.softAP(ssid, pass);             // SSIDとパスの設定
  delay(100);                          // delayが必要
  WiFi.softAPConfig(ip, ip, subnet);   // IP address, gateway, subnetmask の設定
  IPAddress myIP = WiFi.softAPIP();    // WiFi.softAPIP()でWiFi起動
  server.begin();                      // サーバーを起動(htmlを表示させるため)
}                                      //
                                       //
// ****************************************************************************
// * デバッグ表示用                                                           *
// ****************************************************************************
void disp_mode() {                             //
  # ifdef DEBUG_HTML                           // デバッグ用表示
    Serial.print("config_mode - exec : ") ;    // 設定画面か メイン画面か
    if (html_mode == WIFI_CONF)                // 変数の状態と実行状況を表示
      Serial.print("WiFi Config MODE - ") ;    //
    else                                       //
      Serial.print("Main MODE - ") ;           //
    if (html_exec == WIFI_CONF)                //
      Serial.println("WiFi Config MODE") ;     //
    else                                       //
      Serial.println("Main MODE") ;            //
                                               //
    Serial.print("wifi_mode - exec   : ") ;    // Wifi モードを
    if (stamode)                               // 変数の状態と実行状況を表示
      Serial.print("STA - ") ;                 //
    else                                       //
      Serial.print("AP - ") ;                  //
    if (sta_exec)                              //
      Serial.println("STA") ;                  //
    else                                       //
      Serial.println("AP") ;                   //
  # endif                                      //
}                                              //
                                               //
void disp_param() {                            //
  # ifdef DEBUG_HTML                           // デバッグ用表示
    Serial.print("wifi_ssid : ") ;             // 設定画面か メイン画面か
    Serial.println(wifi_ssid) ;                // SSID        for WiFi STA
    Serial.print("wifi_pass : ") ;             // 設定画面か メイン画面か
    Serial.println(wifi_pass) ;                // SSID        for WiFi STA
    Serial.print("wifi_ip   : ") ;             // 設定画面か メイン画面か
    Serial.println(wifi_ip) ;                  // SSID        for WiFi STA
    Serial.print("wifi_gw   : ") ;             // 設定画面か メイン画面か
    Serial.println(wifi_gw) ;                  // SSID        for WiFi STA
    Serial.print("wifi_sm   : ") ;             // 設定画面か メイン画面か
    Serial.println(wifi_sm) ;                  // SSID        for WiFi STA
    Serial.print("wifi_dns  : ") ;             // 設定画面か メイン画面か
    Serial.println(wifi_dns) ;                 // SSID        for WiFi STA
  # endif                                      //
}                                              //
                                               //
// ****************************************************************************
// * クライアントからのフォームデータを変数にセットし、設定ファイルに書き出す *
// ****************************************************************************
int  set_form2param(String &line) {            //
  String s_work ="" ;                          //
  int xhr = 0 ;                                //
                                               //
  if (line.indexOf("set=") != -1) {            // stamode set
    // クライアントからのデータを グローバル変数にセットする。 ------------------
    if (line.indexOf("ssid=") != -1) {         // wifi_ssid
      s_work = getvalue_s(line,"ssid=") ;      //  ssid に続く文字列を取得
      s_work.toCharArray(wifi_ssid,128) ;      //  変数にセット
    }                                          //
    if (line.indexOf("pass=") != -1) {         // wifi_pass
      s_work = getvalue_s(line,"pass=") ;      //  pass に続く文字列を取得
      s_work.toCharArray(wifi_pass,128) ;      //  変数にセット
    }                                          //
    if (line.indexOf("ip1=") != -1) {          // wifi_ip
      wifi_ip[0] = getvalue_i(line,"ip1=") ;   //  ip1 に続く数値を変数にセット
    }                                          //
    if (line.indexOf("ip2=") != -1) {          //
      wifi_ip[1] = getvalue_i(line,"ip2=") ;   //  ip2 に続く数値を変数にセット
    }                                          //
    if (line.indexOf("ip3=") != -1) {          //
      wifi_ip[2] = getvalue_i(line,"ip3=") ;   //  ip3 に続く数値を変数にセット
    }                                          //
    if (line.indexOf("ip4=") != -1) {          //
      wifi_ip[3] = getvalue_i(line,"ip4=") ;   //  ip4 に続く数値を変数にセット
    }                                          //
    if (line.indexOf("gw1=") != -1) {          // wifi_gw
      wifi_gw[0] = getvalue_i(line,"gw1=") ;   //  gw1 に続く数値を変数にセット
    }                                          //
    if (line.indexOf("gw2=") != -1) {          //                      
      wifi_gw[1] = getvalue_i(line,"gw2=") ;   //  gw2 に続く数値を変数にセット
    }                                          //                      
    if (line.indexOf("gw3=") != -1) {          //                      
      wifi_gw[2] = getvalue_i(line,"gw3=") ;   //  gw3 に続く数値を変数にセット
    }                                          //                      
    if (line.indexOf("gw4=") != -1) {          //                      
      wifi_gw[3] = getvalue_i(line,"gw4=") ;   //  gw4 に続く数値を変数にセット
    }                                          //
    if (line.indexOf("sm1=") != -1) {          // wifi_sm
      wifi_sm[0] = getvalue_i(line,"sm1=") ;   //  sm1 に続く数値を変数にセット
    }                                          //                      
    if (line.indexOf("sm2=") != -1) {          //                      
      wifi_sm[1] = getvalue_i(line,"sm2=") ;   //  sm2 に続く数値を変数にセット
    }                                          //                      
    if (line.indexOf("sm3=") != -1) {          //                      
      wifi_sm[2] = getvalue_i(line,"sm3=") ;   //  sm3 に続く数値を変数にセット
    }                                          //                      
    if (line.indexOf("sm4=") != -1) {          //                      
      wifi_sm[3] = getvalue_i(line,"sm4=") ;   //  sm4 に続く数値を変数にセット
    }                                          //
    if (line.indexOf("dns1=") != -1) {         // wifi_dns
      wifi_dns[0] = getvalue_i(line,"dns1=") ; //  dns1 に続く数値を変数にセット
    }                                          //                      
    if (line.indexOf("dns2=") != -1) {         //                      
      wifi_dns[1] = getvalue_i(line,"dns2=") ; //  dns2 に続く数値を変数にセット
    }                                          //                      
    if (line.indexOf("dns3=") != -1) {         //                      
      wifi_dns[2] = getvalue_i(line,"dns3=") ; //  dns3 に続く数値を変数にセット
    }                                          //                      
    if (line.indexOf("dns4=") != -1) {         //                      
      wifi_dns[3] = getvalue_i(line,"dns4=") ; //  dns4 に続く数値を変数にセット
    }                                          //
    if (line.indexOf("stamode=") != -1) {      // stamode set
      s_work = getvalue_s(line,"stamode=") ;   //  ssid に続く文字列を取得
      s_work.toCharArray(wifi_mode,16) ;       //  変数にセット
      if (s_work == "sta") {                   //  設定値により、モードをセット
        stamode = true ;                       //
        html_mode = MAIN ;                     //
      } else {                                 //
        stamode = false ;                      //
        html_mode = MAIN  ;                    //
      }                                        //
    }                                          //
    if (line.indexOf("rebt=") != -1) {         //                      
      s_work = getvalue_s(line,"rebt=") ;      //  ssid に続く文字列を取得
      if (s_work == "on") {                    //   rebt=on なら
        set_reboot = 1    ;                    //
        rebootreq = true ;                     //    リブート要求
      } else {                                 //
        set_reboot = 0    ;                    //
      }                                        //
    }                                          //
    // グローバル変数を 設定ファイルに書き出す -----------------------------------
    wr_wificonfig() ;                          // 設定を初期設定ファイルに書き出し
  }                                            //
  // 戻る 場合 -------------------------------------------------------------------
  if (line.indexOf("rtn=") != -1) {            // return
    html_mode = MAIN ;                         //
  }                                            //
  // ダウンロード の場合 ---------------------------------------------------------
  if (line.indexOf("confld=") != -1) {         // config.txt のダウンロード時
    wifi_confdl = true ;                       //
    xhr = 1 ;                                  //
  }                                            //
                                               //
  return xhr ;                                 //
}                                              //
                                               //
// 要素名に続く値(文字列)を取得する --------------------------------------------
String getvalue_s(String &line,String param) { //
  String val="" ;                              //
  int pos = 0 ;                                //
                                               //
  if ((pos=line.indexOf(param)) != -1) {       // 要素名の位置を取得
    pos += param.length() ;                    //
    while(   (line.charAt(pos) != '&')         //
           & (line.charAt(pos) != ' ')         //
           & (line.charAt(pos) != '\n')        //
           & (line.charAt(pos) != '\0')) {     //
      val += line.charAt(pos++) ;              //  '&' か 行末 まで文字を取得
    }                                          //
  }                                            //
  return val ;                                 //  取得した文字列を返す
}                                              //
                                               //
// 要素名に続く値(数値)を取得する ---------------------------------------------
int getvalue_i(String &line,String param) {    //
  String val="" ;                              //
  int pos = 0 ;                                //
                                               //
  if ((pos=line.indexOf(param)) != -1) {       // 要素名の位置を取得
    pos += param.length() ;                    //
    while(   (line.charAt(pos) >= '0')         //
           & (line.charAt(pos) <= '9')) {      //
      val += line.charAt(pos++) ;              //  数値でなくなるまで文字を
    }                                          //  取得
  }                                            //
  return val.toInt() ;                         //  数値に変換して返す
}                                              //
                                               //
// -----------------------------------------------------------------------------
// - グローバル変数の内容を設定ファイルに書き出す                              -
// -----------------------------------------------------------------------------
void wr_wificonfig() {                         //
  char s_work[128] ;                           //
  File fp ;                                    //
                                               //
  // String に 変数の内容を書き込む -------------------------------------------
  sprintf(s_work,"wifi_ssid : %s\n",wifi_ssid) ;  //
  s_config = String(s_work) ;                     //
  sprintf(s_work,"wifi_pass : %s\n",wifi_pass) ;  //
  s_config += String(s_work) ;                    //
  sprintf(s_work,"wifi_ip   : %3d.%3d.%3d.%3d\n",wifi_ip[0],wifi_ip[1],wifi_ip[2],wifi_ip[3]) ;
  s_config += String(s_work) ;                    //
  sprintf(s_work,"wifi_sm   : %3d.%3d.%3d.%3d\n",wifi_sm[0],wifi_sm[1],wifi_sm[2],wifi_sm[3]) ;
  s_config += String(s_work) ;                    //
  sprintf(s_work,"wifi_gw   : %3d.%3d.%3d.%3d\n",wifi_gw[0],wifi_gw[1],wifi_gw[2],wifi_gw[3]) ;
  s_config += String(s_work) ;                    //
  sprintf(s_work,"wifi_dns  : %3d.%3d.%3d.%3d\n",wifi_dns[0],wifi_dns[1],wifi_dns[2],wifi_dns[3]) ;
  s_config += String(s_work) ;                    //
  sprintf(s_work,"wifi_mode : %s\n",wifi_mode) ;  //
  s_config += String(s_work) ;                    //
  sprintf(s_work,"set_reboot: %d\n",set_reboot) ; //
                                                  //
  // 設定ファイルに書き込む ----------------------------------------------------
  fp = SPIFFS.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() ;                               // ファイルクローズ
  }                                            //
                                               //
}                                              //
                                               //
// *****************************************************************************
// * HTML 送信処理                                                             *
// *****************************************************************************
                                               //
// ----------------------------------------------------------------------------
// - CONF_HTML 送信  -----------------------------------------------------------
// ----------------------------------------------------------------------------
void  send_wfCONF_html(WiFiClient client) {    //
  String htmlwk ;                              //
                                               //
  // 変数置換え処理 ------------------------------------------------------------
  htmlwk = html_wfCONF ;                       //
  htmlwk.replace("$ssid",String(wifi_ssid)) ;  //
  htmlwk.replace("$pass",String(wifi_pass)) ;  //
  htmlwk.replace("$ip1",String(wifi_ip[0])) ;  //
  htmlwk.replace("$ip2",String(wifi_ip[1])) ;  //
  htmlwk.replace("$ip3",String(wifi_ip[2])) ;  //
  htmlwk.replace("$ip4",String(wifi_ip[3])) ;  //
  htmlwk.replace("$sm1",String(wifi_sm[0])) ;  //
  htmlwk.replace("$sm2",String(wifi_sm[1])) ;  //
  htmlwk.replace("$sm3",String(wifi_sm[2])) ;  //
  htmlwk.replace("$sm4",String(wifi_sm[3])) ;  //
  htmlwk.replace("$gw1",String(wifi_gw[0])) ;  //
  htmlwk.replace("$gw2",String(wifi_gw[1])) ;  //
  htmlwk.replace("$gw3",String(wifi_gw[2])) ;  //
  htmlwk.replace("$gw4",String(wifi_gw[3])) ;  //
  htmlwk.replace("$dns1",String(wifi_dns[0])) ;//
  htmlwk.replace("$dns2",String(wifi_dns[1])) ;//
  htmlwk.replace("$dns3",String(wifi_dns[2])) ;//
  htmlwk.replace("$dns4",String(wifi_dns[3])) ;//
  if (stamode) {                               // ステーションモード時
    htmlwk.replace("$checked_sta","checked") ; //
    htmlwk.replace("$checked_ap","") ;         //
  } else {                                     // アクセスポイントモード時
    htmlwk.replace("$checked_sta","") ;        //
    htmlwk.replace("$checked_ap","checked") ;  //
  }                                            //
  if (set_reboot != 0) {                       // ステーションモード時
    htmlwk.replace("$checked_rebt","checked") ;//
  } else {                                     // アクセスポイントモード時
    htmlwk.replace("$checked_rebt","") ;       //
  }                                            //
  htmlwk.replace("$footer",foot_msg ) ;        //
  // --------------------------------------------------------------------------
                                               //
  send_html(client,htmlwk) ;                   // HTML 送信処理
}                                              //
                                               //
// ----------------------------------------------------------------------------
// - XHR RESPONSE_HTML 送信                                                   -
// ----------------------------------------------------------------------------
void send_wfRESP_html(WiFiClient client) {     //
  String htmlwk ;                              // HTML 編集用 ワーク
                                               //
  htmlwk = html_wfRESP ;                       // htmlwk に HTML をコピー
                                               //
  // 変数を値に変換----------------------------//
  if (wifi_confdl) {                           //  ダウンロードの場合
    htmlwk.replace("$conf_text",s_config) ;    // 変数に 設定文字列をセット
    wifi_confdl = false ;                      //
  } else  {                                    //  アップロードの場合
    htmlwk.replace("$conf_text","") ;          //   変数に文字列(ダミー)をセット
  }                                            //
  // HTML を送信 ------------------------------//
  send_html(client,htmlwk) ;                   // HTML 送信処理
                                               //
}                                              //
                                               //

  以下、覚書など。

< メイン HTML (LED調光用 HTML) >

 ダウンロード用リンク、javascript は削除。

< WiFi 設定画面用 HTML >

(行#82~85)
設定後のリブート指示用のチェックボックスを追加。
( リブートしないと設定が反映されない為 )


(行#91~95)
ダウンロード、アップロードのリンクを設定。
 クリックで javascript を実行する為、
  href='javascript:selfile();'
の様に href に javascript を設定する。

(行#96~98)
type='file' の input。
 属性を hidden にし、WEB 画面には表示しない。


(行#107~138)
ダウンロード用の javascript。
メイン HTML にあったものと同じ。

(行#140~143)
 アップロード用にリンクをクリックした場合に実行する javascript。
行#97 の input をクリックする。


(行#144 ~ 230)
行#97 の input を クリックした時に実行する javascript。
行#97 の input (ファイル選択) でのファイルオブジェクトを取得。
ファイルオブジェクトをテキストとして読み込んだら、内容を解析して HTML の各要素の値をアップロードした値で更新し、XHR を使用して ファイル内容を ESP32 へ送信。
XHR 送信時、 xhr_ul.open("post", "?conful");
で、 POST コマンドを指定し、URL に ?conful を指定
 xhr_ul.send(reader.result);
で、ファイルの内容 (reader.result) を指定。
詳細は、HTML 内のコメントを参照。

<XHR 応答用 HTML>

XHR 応答時に送信するが、特に送信するものは無し。

<メインスケッチ (test_AP3.ino>

全面的に見直し/修正を行っているが、主な変更は、
  1. POST 処理対応
    POST処理については、POST受信 参照。
    (行#131~134)
    POST 受信時は フラグをセット。
    アップロード要求時は、アップロードのフラグをセット。
    (行#139~150)
    POST受信時は、メッセージボディを取得
    (行#141~164)
    POST 要求の処理。
    アップロード以外は 行#159 で GET 時と同じ処理を実行。
  2. アップロード対応
    (行#153~157)
    アップロードの場合、シリアルにデータを表示。
    今回は、ESP32 では特に処理を行わない。
    (クライアント側で 各要素の値に代入するだけ。)

<LED調光処理用スケッチ (led_ctrl.ino>

ダウンロード時の処理を削除 (WIFI設定に移動)

<WIFI 設定用スケッチ (wifi_config.ino>

 全面的に見直し/修正を行っているが、主な変更は、
  1. フォームデータ処理を GET,POST どちらでも対応できる様に修正。
    (行#209,210)
    "GET /?" を判定から削除
  2. リブート指示時の処理追加
    (行#106~109)
    設定ファイル処理にリブートを追加。
    (行#276~284)
    フォームデータでリブート設定時の処理追加。(フラグセット)
    (行#355)
    リブート設定を設定ファイルに追記。
    (行#411~414)
    HTML送信時の リブート チェックボックスの値を設定。
  3. ダウンロード処理追加 ( LED調光画面からの移動)
    (行#293~298)
    フォームデータでダウンロード指定時の処理 (フラグセット)
    (行#421~440)
    XHR 応答送信処理追加 (LED調光画面からの移動)

0 件のコメント:

コメントを投稿