Nゲージ用 PWM制御パワーパックの改良/機能追加として、以下を行う。
(1) softAP による WiFi設定の対応
(2) 自動走行対応
(2) 自動走行対応
追加機能:
パワーパック改からの追加機能は、以下の通り。
- softAP による WiFi設定の対応
"softAPでWiFi設定" と同様。
上記内容に、"戻る"ボタンを追加。 - 自動走行対応
発車ボタン押下で、自動運行設定に従って自動走行を行う。設定項目は、
加速度で、5種類設定可能で、繰り返し実行できる様にする。
目標速度
走行時間
また、設定間は、スイッチ押下で遷移させる事も可能。
設定は SPIFFS に保存。
パワーパック ハードウェア:
ハードウェア(回路) はパワーパック改と同じ。
WEB画面:
WiFi設定画面 ( WiFi接続先, ESP32 の IPアドレス等を設定する )
PWPK設定画面 ( 自動運行の設定を行う )
PWPKメイン画面 ( PWPK の操作画面 )
スケッチ、HTML等 ファイル構成:
HTML, スケッチ共に、だいぶ大きくなってきた為、各ファイルは以下の様に分割。
( ファイルの分割は、まだうまく整理できていない。今後見直し要。
まだ、バグ等があると思われるため、参考にする場合は十分確認願います。)
スケッチの拡張子は全て .ino
HTML : MAIN HTML (pwpk.html)
WiFi設定 HTML (wifi_conf.html)
PWPK設定 HTML (pwpk_conf.html)
XHR 応答 HTML (pwpk_resp.html)
PWPK設定 HTML (pwpk_conf.html)
XHR 応答 HTML (pwpk_resp.html)
スケッチ : MAIN (変数定義, setup, loop 関数)
WIFI設定 (主に WiFI 設定用 の関数)
PWPK処理 (主に PWPK処理、PWPK 設定用 の関数)
PWPK処理 (主に PWPK処理、PWPK 設定用 の関数)
<!DOCTYPE html><html lang='ja'><head><meta charset='UTF-8'> <style> #base {font-size:16pt; text-align:center; width:600px; border:solid 4px #000000; background-color:#c0c0c0; } #radio_box {font-size:12pt; float:left ;text-align:left; width:30%; margin: 0px 5% 20px 15% ; } #dir_box {font-size:12pt; float:right;text-align:left; width:30%; margin: 0px 15% 20px 5% ; } #disp_box {font-size:12pt; clear:both; text-align:left; margin: 0px 0px 20px 100px ; } #pwr_box {font-size:12pt; text-align:left; margin: 0px 0px 0px 100px ; } #slid_box {font-size:12pt; text-align:left; margin: 10px 0px 10px 50px ; } #sw_box {font-size:12pt; text-align:center; margin: 10px 0% 10px 0% ; } #cnfgbtn1 {font-size:12pt; text-align:right ; margin: 0px 5%;width 100%} #cnfgbtn2 {font-size:12pt; text-align:right ; margin: 0px 5%;width 100%} #footer {font-size:12pt; clear:both;} output.disp {margin-left:200px; font-size:14pt; } input.radio {margin-left:8px; width:30px;} input.dir {margin-left:8px; width:30px;} input.value {margin-left:100px; width:40px; font-size:12pt; } input.setbutton{margin-left:8px; width:40px;} input.slider {margin-left:50px; width:400px;} input.button {margin:0px 13%; width:20%;} </style> <title>Power PWN Controller</title></head> <body> <div id="base"> <p>運 行 管 理</p> <div id="radio_box"> <form method="get"> <input class="radio" type="radio" name="remote" id="rad_lo" value="local" $checked_lo onclick="disp_ctrl(this.value); submit(this.value)">制御盤<br> <input class="radio" type="radio" name="remote" id="rad_rm" value="remote" $checked_rm onclick="disp_ctrl(this.value); submit(this.value)">遠隔<br> </form> </div> <div id="dir_box"> <form method="get"> <input class="dir" type="radio" name="dir" id="dir_fw" value="foward" $checked_fw onclick="submit(this.value)" disabled >前進<br> <input class="dir" type="radio" name="dir" id="dir_bw" value="backward" $checked_bw onclick="submit(this.value)" disabled >後退<br> </form> </div> <div id="disp_box"> <span> 現在出力 </span> <output class='disp' id='o1'> $pwr </output> </div> <div id="pwr_box"> <form method="get"> <span> 出力設定 (0-255)</span> <input class='value' type='text' name='pwr_v' value= $pwr id='pwr_v' disabled> <input class='setbutton' type='submit' name='set' id='set' value='SET' disabled> </form> </div> <div id="slid_box"> <form method='get'> <input class='slider' type='range' name='pwr_s' id='pwr_s' value= $pwr min=$pwmin max='255' step='1' disabled onchange='setval(this.value);' oninput='setval(this.value)'; onmouseup='submit(this.form)': ontouchend='submit(this.form)'> </form> </div> <div id="sw_box"> <form method='get'> <input class='button' type='submit' name='ready' id='ready' value= '準備/解除' disabled > <input class='button' type='button' name='start' id='start' value= '発車/停車' onclick='sw_start()' disabled > </form> </div> <div id="cnfgbtn1"> <form method="get"> <input type='submit' name='mconf' id='mconf' style="width:100px" value='運行設定画面'> </form> </div> <div id="cnfgbtn2"> <form method="get"> <input type='submit' name='config' id='config' style="width:100px" value='WiFi設定画面'> </form> </div> <div id="footer"> <br/> </div> </div> <script> var polling = null ; function setval(pwr){ if (polling == null) clearInterval(polling); pollint = null ; var xhr = new XMLHttpRequest(); xhr.open("get", "?slid="+pwr ); 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) ) { document.getElementById('pwr_v').value = parseInt(xhr.response.getElementById("output1").innerHTML) ; document.getElementById('o1').innerHTML = xhr.response.getElementById("output1").innerHTML; } } ntimeout = function(e) { xhr.abort() ; } xhr.send(); } function getval(){ var xhrget = new XMLHttpRequest(); xhrget.open("get", "?pol" ); xhrget.setRequestHeader('Cache-Control', 'no-cache'); xhrget.setRequestHeader('If-Modified-Since', 'Thu, 01 Jun 1970 00:00:00 GMT'); xhrget.responseType = 'document' ; xhrget.onreadystatechange = function() { if( (xhrget.readyState == 4) && (xhrget.status == 200) ) { document.getElementById('o1').innerHTML = xhrget.response.getElementById("output1").innerHTML; document.getElementById('pwr_s').value = parseInt(xhrget.response.getElementById("output1").innerHTML); document.getElementById('pwr_v').value = parseInt(xhrget.response.getElementById("output1").innerHTML); } } ntimeout = function(e) { xhrget.abort() ; } xhrget.send(); } function sw_start() { var xhr_start = new XMLHttpRequest(); xhr_start.open("get", "?start" ); xhr_start.setRequestHeader('Cache-Control', 'no-cache'); xhr_start.setRequestHeader('If-Modified-Since', 'Thu, 01 Jun 1970 00:00:00 GMT'); xhr_start.responseType = 'document' ; xhr_start.onreadystatechange = function() { if( (xhr_start.readyState == 4) && (xhr_start.status == 200) ) { if (polling == null) polling = setInterval(getval,100) ; } } ntimeout = function(e) { xhr_start.abort() ; } xhr_start.send(); } function disp_ctrl( radioid ) { if(radioid == 'remote') { document.getElementById('dir_fw').disabled = false; document.getElementById('dir_bw').disabled = false; document.getElementById('pwr_v').disabled = false; document.getElementById('set').disabled = false; document.getElementById('pwr_s').disabled = false; document.getElementById('ready').disabled = false; document.getElementById('start').disabled = false; if (polling == null) clearInterval(polling); pollint = null ; } else { document.getElementById('dir_fw').disabled = true; document.getElementById('dir_bw').disabled = true; document.getElementById('pwr_v').disabled = true; document.getElementById('set').disabled = true; document.getElementById('pwr_s').disabled = true; document.getElementById('ready').disabled = true; if (polling == null) polling = setInterval(getval,100) ; } } window.onload = function() { if(document.getElementById("rad_rm").checked) { document.getElementById('dir_fw').disabled = false; document.getElementById('dir_bw').disabled = false; document.getElementById('pwr_v').disabled = false; document.getElementById('set').disabled = false; document.getElementById('pwr_s').disabled = false; document.getElementById('ready').disabled = false; document.getElementById('start').disabled = false; if (polling == null) clearInterval(polling); pollint = null ; } else if(document.getElementById("rad_lo").checked) { document.getElementById('dir_fw').disabled = true; document.getElementById('dir_bw').disabled = true; document.getElementById('pwr_v').disabled = true; document.getElementById('set').disabled = true; document.getElementById('pwr_s').disabled = true; document.getElementById('ready').disabled = true; document.getElementById('start').disabled = true; polling = setInterval(getval,100) ; } } </script> </body> </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 {font-size:12pt; clear:both; width 50%} #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"> <input class='button' type='submit' name='set' id='set' value='設定'> <input class='button' type='submit' name='rtn' id='rtn' value='戻る'> </div> </form> <div id="foot"> <span>$footer</span> </div> </div> </body> </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; } #item_box {height:30px; font-size:12pt; text-align:left; } #item_0 {font-size:10pt; float:left ; text-align:left; width:20%; } #item_1 {font-size:10pt; float:left ; text-align:center; width:20%; } #item_def {font-size:10pt; float:left ; text-align:center; width:15.5%; } #chec_box {height:30px; font-size:12pt; cleart:both ;text-align:left; } #conf_box {height:30px; font-size:12pt; text-align:left; } #button {font-size:12pt; clear:both; width 50%} input.button {margin:10px 10% ; width: 25%;} </style> <title>運行設定画面</title></head> <body> <div id="base"> <p>設定画面</p> <form method="get"> <div id="chec_box"> <div id="item_0"> <span> Loop </span> <input type="checkbox" name="loop" id="loop" value="1" $checked_loop autocomplete="off" onclick="disp_ctrl_0(this.checked)" > </div> <div> <span> 回数 </span> <input type="number" name="loopnum" id="loopnum" value=$loopnum max="36000" style="width:80px;" > </div> </div> <!-- 項目名の表示 ========================================= --> <div id="item_box"> <div id="item_0"> <span> </span> </div> <div id="item_1"> <span>起点</span> </div> <div id="item_def"> <span>加速度</span> </div> <div id="item_def"> <span>目標速度</span> </div> <div id="item_def"> <span>時間(x0.1秒)</span> </div> </div> <!-- 設定 1 の 入力欄 ===================================== --> <div id="conf_box"> <div id="item_0" > <span style="margin-left:25px"> 設定1 : </span> </div> <div id="item_1"> <span> </span> </div> <div id="item_def"> <input type="number" name="acc1" id="acc1" value=$acc1 max="255" style="width:50px;" > </div> <div id="item_def"> <input type="number" name="spd1" id="spd1" value=$spd1 max="255" style="width:50px;" > </div> <div id="item_def"> <input type="number" name="tim1" id="tim1" value=$tim1 max="36000" style="width:50px;" > </div> </div> <!-- 設定 2 の 入力欄 ===================================== --> <div id="conf_box"> <div id="item_0"> <input type="checkbox" name="chk2" id="chk2" value="1" $en2 autocomplete="off" onclick="disp_ctrl_2(this.checked)" > <span> 設定2 : </span> </div> <div id="item_1"> <select name="trg2" id="trg2" autocomplete="off"> <option value="0" $trg2_sel0 >前項の続き</option> <option value="1" $trg2_sel1 >スイッチ押下</option> </select> </div> <div id="item_def"> <input type="number" name="acc2" id="acc2" value=$acc2 max="255" style="width:50px;" > </div> <div id="item_def"> <input type="number" name="spd2" id="spd2" value=$spd2 max="255" style="width:50px;" > </div> <div id="item_def"> <input type="number" name="tim2" id="tim2" value=$tim2 max="36000" style="width:50px;" > </div> </div> <!-- 設定 3 の 入力欄 ===================================== --> <div id="conf_box"> <div id="item_0"> <input type="checkbox" name="chk3" id="chk3" value="1" $en3 autocomplete="off" onclick="disp_ctrl_3(this.checked)" > <span> 設定3 : </span> </div> <div id="item_1"> <select name="trg3" id="trg3" autocomplete="off"> <option value="0" $trg3_sel0>前項の続き</option> <option value="1" $trg3_sel1>スイッチ押下</option> </select> </div> <div id="item_def"> <input type="number" name="acc3" id="acc3" value=$acc3 max="255" style="width:50px;" > </div> <div id="item_def"> <input type="number" name="spd3" id="spd3" value=$spd3 max="255" style="width:50px;" > </div> <div id="item_def"> <input type="number" name="tim3" id="tim3" value=$tim3 max="36000" style="width:50px;" > </div> </div> <!-- 設定 4 の 入力欄 ===================================== --> <div id="conf_box"> <div id="item_0"> <input type="checkbox" name="chk4" id="chk4" value="1" $en4 autocomplete="off" onclick="disp_ctrl_4(this.checked)" > <span> 設定4 : </span> </div> <div id="item_1"> <select name="trg4" id="trg4" autocomplete="off"> <option value="0" $trg4_sel0>前項の続き</option> <option value="1" $trg4_sel1>スイッチ押下</option> </select> </div> <div id="item_def"> <input type="number" name="acc4" id="acc4" value=$acc4 max="255" style="width:50px;" > </div> <div id="item_def"> <input type="number" name="spd4" id="spd4" value=$spd4 max="255" style="width:50px;" > </div> <div id="item_def"> <input type="number" name="tim4" id="tim4" value=$tim4 max="36000" style="width:50px;" > </div> </div> <!-- 設定 5 の 入力欄 ===================================== --> <div id="conf_box"> <div id="item_0"> <input type="checkbox" name="chk5" id="chk5" value="1" $en5 autocomplete="off" onclick="disp_ctrl_5(this.checked)" > <span> 設定5 : </span> </div> <div id="item_1"> <select name="trg5" id="trg5" autocomplete="off"> <option value="0" $trg5_sel0>前項の続き</option> <option value="1" $trg5_sel1>スイッチ押下</option> </select> </div> <div id="item_def"> <input type="number" name="acc5" id="acc5" value=$acc5 max="255" style="width:50px;" > </div> <div id="item_def"> <input type="number" name="spd5" id="spd5" value=$spd5 max="255" style="width:50px;" > </div> <div id="item_def"> <input type="number" name="tim5" id="tim5" value=$tim5 max="36000" style="width:50px;" > </div> </div> <br/> <div id="button"> <input type="submit" name="set" id="set" value="設定" style="width:100px" > <input type="checkbox" name="save" id="save" autocomplete="off" > <span>ファイルに保存する</span> <input type="submit" name="rtn" id="rtn" value="戻る" style="width:100px; margin-left:10%" > </div> </form> </div> <!-- JAVA SCRIPT ========================================================= --> <script> function disp_ctrl_0(enable) { if (enable == true) { document.getElementById('intval').disabled = false ; }else { document.getElementById('intval').disabled = true ; } } function disp_ctrl_2(enable) { if (enable == true) { document.getElementById('trg2').disabled = false ; document.getElementById('acc2').disabled = false ; document.getElementById('spd2').disabled = false ; document.getElementById('tim2').disabled = false ; }else { document.getElementById('trg2').disabled = true ; document.getElementById('acc2').disabled = true ; document.getElementById('spd2').disabled = true ; document.getElementById('tim2').disabled = true ; } } function disp_ctrl_3(enable) { if (enable == true) { document.getElementById('trg3').disabled = false ; document.getElementById('acc3').disabled = false ; document.getElementById('spd3').disabled = false ; document.getElementById('tim3').disabled = false ; }else { document.getElementById('trg3').disabled = true ; document.getElementById('acc3').disabled = true ; document.getElementById('spd3').disabled = true ; document.getElementById('tim3').disabled = true ; } } function disp_ctrl_4(enable) { if (enable == true) { document.getElementById('trg4').disabled = false ; document.getElementById('acc4').disabled = false ; document.getElementById('spd4').disabled = false ; document.getElementById('tim4').disabled = false ; }else { document.getElementById('trg4').disabled = true ; document.getElementById('acc4').disabled = true ; document.getElementById('spd4').disabled = true ; document.getElementById('tim4').disabled = true ; } } function disp_ctrl_5(enable) { if (enable == true) { document.getElementById('trg5').disabled = false ; document.getElementById('acc5').disabled = false ; document.getElementById('spd5').disabled = false ; document.getElementById('tim5').disabled = false ; }else { document.getElementById('trg5').disabled = true ; document.getElementById('acc5').disabled = true ; document.getElementById('spd5').disabled = true ; document.getElementById('tim5').disabled = true ; } } window.onload = function() { if(document.getElementById('loop').checked) { document.getElementById('intval').disabled = false ; }else{ document.getElementById('intval').disabled = true ; } if(document.getElementById('chk2').checked) { document.getElementById('trg2').disabled = false ; document.getElementById('acc2').disabled = false ; document.getElementById('spd2').disabled = false ; document.getElementById('tim2').disabled = false ; }else{ document.getElementById('trg2').disabled = true ; document.getElementById('acc2').disabled = true ; document.getElementById('spd2').disabled = true ; document.getElementById('tim2').disabled = true ; } if(document.getElementById('chk3').checked) { document.getElementById('trg3').disabled = false ; document.getElementById('acc3').disabled = false ; document.getElementById('spd3').disabled = false ; document.getElementById('tim3').disabled = false ; }else{ document.getElementById('trg3').disabled = true ; document.getElementById('acc3').disabled = true ; document.getElementById('spd3').disabled = true ; document.getElementById('tim3').disabled = true ; } if(document.getElementById('chk4').checked) { document.getElementById('trg4').disabled = false ; document.getElementById('acc4').disabled = false ; document.getElementById('spd4').disabled = false ; document.getElementById('tim4').disabled = false ; }else{ document.getElementById('trg4').disabled = true ; document.getElementById('acc4').disabled = true ; document.getElementById('spd4').disabled = true ; document.getElementById('tim4').disabled = true ; } if(document.getElementById('chk5').checked) { document.getElementById('trg5').disabled = false ; document.getElementById('acc5').disabled = false ; document.getElementById('spd5').disabled = false ; document.getElementById('tim5').disabled = false ; }else{ document.getElementById('trg5').disabled = true ; document.getElementById('acc5').disabled = true ; document.getElementById('spd5').disabled = true ; document.getElementById('tim5').disabled = true ; } } </script> </body> </html>
<!DOCTYPE html><html lang='ja'> <head> <title>Color LED Controller</title></head> <body> <output id='output1'> $pwr</output> </body> </html>
#include <WiFi.h> // WiFi 使用の為 #include "FS.h" // SPIFFS 使用の為 #include "SPIFFS.h" // SPIFFS 使用の為 #include <Ticker.h> //#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 // STA モード用 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 char wifi_mode[16] = "" ; // wifi mode String foot_msg ="" ; // リブートメッセージ用 WiFiServer server(80); // 動作モードフラグ ----------------------------------------------------------- #define WIFI_CONF 0 // html モード用定義 #define MAIN 1 // #define MAIN_CONF 2 // bool stamode = true ; // WiFi STA 接続モード : true bool sta_exec = false ; // WiFi STA接続モード実行中フラグ int html_mode = MAIN ; // WiFi設定モード ; true int html_exec = MAIN ; // WiFi設定実行中フラグ // ----------------------------------------------------------------------------- // | HTML ファイル名等 | // ----------------------------------------------------------------------------- const char fname_CONF[] = "/wifi_conf.html" ; // WiFi 設定用 HTML ファイル名 const char fname_MAIN[] = "/pwpk.html" ; // メイン HTML ファイル名 const char fname_RESP[] = "/pwpk_resp.html" ; // XHR レスポンス HTML ファイル名 const char fname_MCONF[] = "/pwpk_conf.html"; // メイン設定用 HTML ファイル名 String html_CONF ; // 設定用 HTML 格納用 String html_pwpk ; // メイン HTML 格納用 String html_resp ; // XHR 応答用 HTML 格納用 String html_MCONF ; // メイン設定用 HTML 格納用 // ----------------------------------------------------------------------------- // - PWPK処理用 - // ----------------------------------------------------------------------------- // 運行設定用 変数定義 -------------------------------------------------------- String m_config ; // 設定ファイル用 String int prg_tbl[6][5] = // 運行設定 { {0,1,0,0,0}, // prg_loop,prg_loop_intval, resrv,reserv,reserv, {1,0,5,145,0}, // prt_1_en,reserv, prg_1_acc,prt_1_spd,prg_1_tim, {0,0,0,0,0}, // prt_2_en,prg_2_trg,prg_2_acc,prg_2_spd,prg_2_tim, {0,0,0,0,0}, // prt_3_en,prg_3_trg,prg_3_acc,prg_3_spd,prg_3_tim, {0,0,0,0,0}, // prt_4_en,prg_4_trg,prg_4_acc,prg_4_spd,prg_4_tim, {0,0,0,0,0} } ; // prt_5_en,prg_5_trg,prg_5_acc,prg_5_spd,prg_5_tim, // グローバル変数定義 --------------------------------------------------------- bool local = true ; // local フラグ bool localen = false ; // 制御盤操作許可 byte duty = 0 ; // PWM デューティ設定 (0~255) int loopcnt = 0 ; // 定期割り込み回数カウント用 bool ticker_val = false ; // 定期割り込みフラグ bool pre_strt = false ; // 発車要求スイッチ状態保持用 bool start_sw = false ; // 発車要求スイッチ押下検出 bool running = false ; // 走行中フラグ int base = 25 ; // 準備時 (LED点灯時) の duty 値 int target = 145 ; // 目標デューティ int rate = 5 ; // 増減速の割合 (1/10 S 当たりの 増加 duty値) unsigned long start_time = 0 ; // 開始時刻 unsigned long now_time = 0 ; // 現在時刻 // ( 制御盤/WEB 操作情報用 ) -------- int vol_value = 0 ; // 制御盤ボリューム値 (0~4095) int base_val = 0 ; // 最低速度時のDuty 値 bool dir_bkwd = false ; // 進行方向フラグ bool dir_change = false ; // 進行方向変化フラグ bool pre_rdy = false ; // 準備要求スイッチ状態保持用 bool ready = false ; // 準備要求フラグ ( LED 常時点灯要求) bool rdy_change = false ; // 準備要求状態変化 // ( 自動運転用 ) ------------------- bool prg_run = false ; // 自動運行実行中 bool prg_start = false ; // 自動運行開始指示 bool prg_next = false ; // 自動運行設定更新指示 int prg_no = 0 ; // 実行中の運行設定 No. int nextno = 0 ; // 次の運行設定 No. int prg_tim = 0 ; // 運行時間 int prg_loopnum= 1 ; // 自動運行繰り返し回数 bool start = false ; // 発車要求フラグ bool stop = false ; // 停車要求フラグ bool autorun = false ; // 自動走行中フラグ bool wait_sw = false ; // STARTスイッチ待ち bool time_ovr = false ; // 運行時間オーバー // ( LED 制御用 ) ------------------- bool st_blink = false ; // ステータス 点滅 int st_bl_intvl= 0 ; // ステータス 点滅間隔 int st_bl_cnt = 0 ; // ステータス 点滅時 カウント値 bool st_bl_off = false ; // ステータス 点滅時 OFF 状態 bool st_on = false ; // ステータス 点灯 int st_val = 0 ; // ステータス値 Ticker ticker; // ------ Define for IO Port -------------------------------------------------- #define PWR_VOL A7 // ADC1 A7 (IO35) #define PWR_OUT 2 // Degital Output IO2 #define DIR_OUT 4 // Degital Output IO4 (0:FWD,1:BWD) #define SW_FWD 27 // Degital Input IO27 #define SW_BWD 14 // Degital Input IO14 #define SW_READY 13 // Degital Input IO13 #define SW_START 16 // Degital Input IO16 #define LED_FWD 17 // Degital Output IO17 #define LED_BWD 12 // Degital Output IO12 #define LED_ST1 23 // Degital Output IO23 #define LED_ST2 19 // Degital Output IO19 #define LED_ST3 18 // Degital Output IO18 // ----- Define for LEDC ------------------------------------------------------ #define PWM_FEQ 20000 #define DUTY_bw 8 // ----------------------------------------------------------------------------- // arduino 初期化処理 -- // ----------------------------------------------------------------------------- void setup() { int res = 0 ; // 結果格納用 (ワーク) pinMode(PWR_OUT,OUTPUT) ; // Set pin mode for SPEED control pinMode(DIR_OUT,OUTPUT) ; // Set pin mode for Dirction control pinMode(LED_FWD,OUTPUT) ; // Set pin mode for Forward LED pinMode(LED_BWD,OUTPUT) ; // Set pin mode for Backward LED pinMode(LED_ST1,OUTPUT) ; // Set pin mode for status 1 LED pinMode(LED_ST2,OUTPUT) ; // Set pin mode for status 2 LED pinMode(LED_ST3,OUTPUT) ; // Set pin mode for status 3 LED // セットアップ中、LED を点灯させる digitalWrite(LED_FWD,1) ; digitalWrite(LED_BWD,1) ; digitalWrite(LED_ST1,1) ; digitalWrite(LED_ST2,1) ; digitalWrite(LED_ST3,1) ; Serial.begin(115200); // シリアル 開始 SPIFFS.begin(true) ; // SPIFFS 開始 // 初期設定用 HTML ファイルの読み込み --------------------------------------- res = rd_SPIFFS(fname_CONF,html_CONF) ; // html_CONF に html を格納 // 本体 HTML ファイルの読み込み ---------------------------------------------- res = rd_SPIFFS(fname_MAIN,html_pwpk) ; // html_pwpk に html を格納 // XHR 応答ファイルの読み込み ------------------------------------ res = rd_SPIFFS(fname_RESP,html_resp) ; // html_resp に html を格納 // メイン用設定 HTML ファイルの読み込み ------------------------------------- res = rd_SPIFFS(fname_MCONF,html_MCONF) ; // html_MCONF に html を格納 // wifi 初期設定ファイルを読み込み、変数に格納し、wifi,画面モードを決定 ----- 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 ; // } // // 実行中のモード (設定かメインか) を設定 ------------------------------------ html_exec = html_mode ; // 実行中の html_mode を 設定 Serial.println("Server start!"); // for PWM Control =========================================================== // メイン設定ファイルを読み込み、変数に格納する ------------------------------ res = rd_mainconf() ; // ledc 設定 ----------------------------------------------------------------- ledcSetup(0, PWM_FEQ, DUTY_bw); // setup channel 0 with frequency 5000 Hz, // 8 bit precission for LEDC timer ledcAttachPin(PWR_OUT,0); // attach pin 2 to channel 0 ledcWrite(0, 0); // initialize channel 0 to off // LED を初期状態に設定。 ---------------------------------------------------- digitalWrite(LED_FWD,1) ; digitalWrite(LED_BWD,0) ; digitalWrite(LED_ST1,0) ; digitalWrite(LED_ST2,0) ; digitalWrite(LED_ST3,0) ; // 周期割り込みを開始 -------------------------------------------------------- ticker.attach_ms(100, execTicker) ; // 割り込み間隔と割り込み処理を設定。 } // ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- // arduino メインループ処理 -- // ----------------------------------------------------------------------------- void loop() { WiFiClient client = server.available(); String htmlwk = "" ; // html 用 ワーク変数 String line = "" ; // クライアントからの入力用 int xhr = 0 ; // if (ticker_val) { // 定期割込みフラグが true だったら、定期処理を実行。 do_JOB() ; } // HTML クライアント処理 ------------------------------------------------------ if (client) { # ifdef DEBUG_HTML Serial.println(" +++++++++++++++++ new client! +++++++++++++++++ "); # endif // while (client.connected()) { // クライアントから接続されたとき if (client.available()) { // line = client.readStringUntil('\n'); // 1行分取得 # ifdef DEBUG_HTML // Serial.println(line) ; // # endif // if (line.indexOf("GET /?") != -1) { // GET 処理 if (html_mode == WIFI_CONF){ // 初期設定用 フォームデータ処理 set_form2param(line) ; // フォームデータを変数に格納 }else if (html_mode == MAIN_CONF) { // set_mconf2param(line) ; // フォームデータを変数に格納 } else { // メイン用 処理 xhr = proc_main(line) ; // フォームデータのメイン処理 } // } // // 最終行(空行)を受信した時 ------------------------------------------- if (line.length() == 1 && line[0] == '\r'){ // 最終行判定 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_CONF_html(client) ; // 初期設定 HTML 送信 } else { // メイン画面なら send_MAIN_html(client) ; // メイン HTML 送信 html_exec = MAIN ; // } // ( その後 リブート) } else { // sta_mode が変わらない場合 if (xhr) { send_resp_html(client) ; // メイン HTML 送信 } else if (html_mode == WIFI_CONF) { // 次に初期設定を表示するなら send_CONF_html(client) ; // 初期設定 HTML 送信 } else if (html_mode == MAIN_CONF) { // 次にメイン画面なら send_MCONF_html(client) ; // メイン設定 HTML 送信 } else { // メイン設定画面A send_MAIN_html(client) ; // メイン HTML 送信 } // html_exec = html_mode ; // } // # ifdef DEBUG_HTML // Serial.println("Send HTML") ; // # endif // break ; // ループ終了 } // //------------------------------------------------------------------- } } // 接続が切れた場合 ------------------------------------------------------ client.stop(); # ifdef DEBUG_HTML // Serial.println("client disonnected"); Serial.println("----------------------------------------------------"); # endif } if (stamode != sta_exec) { // sta_mode が変わった場合 Serial.println("------------------- リブートします------------------- "); delay(500); // ESP.restart() ; // リブート } else { } // -------------------------------------------------------------------------- }
// ***************************************************************************** // * 初期設定ファイル をリードし、グローバル変数に値をセットする * // ***************************************************************************** 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 の内容を変数に設定 // 初期設定ファイルの状態で 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 ; // メイン画面 Serial.println("set html_mode (rd_config) : MAIN") ; }else{ // wifi_mode が "ap" でなければ html_mode = WIFI_CONF ; // 初期設定画面 Serial.println("set html_mode (rd_config) : 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() { int pos = 0 ; int npos = 0 ; String s_work ; String s_name ; String s_data ; // 記載内容を順次処理 ( 設定情報を取り出し、グローバル変数に設定する ) ------ 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_wifiparam(s_name,s_data) ; // 取得した内容をグローバル変数に設定 } // } // } // // - 設定内容を判定し、グローバル変数に設定 ------------------------------------ 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) ; // } // } // // - 文字列 から 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("html_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 set_form2param(String &line) { String s_work ="" ; if (line.indexOf("set=") != -1) { // stamode set // クライアントからのデータを グローバル変数にセットする。 ------------------ if (line.indexOf("GET /?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 ; // } } Serial.print("html_mode(set_form2param) :") ; Serial.println(html_mode) ; // グローバル変数を 設定ファイルに書き出す ----------------------------------- wr_wificonfig() ; // 設定を初期設定ファイルに書き出し } if (line.indexOf("rtn=") != -1) { // stamode set html_mode = MAIN ; } } // 要素名に続く値(文字列)を取得する -------------------------------------------- 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') ) { 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) ; // // 設定ファイルに書き込む ---------------------------------------------------- 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_CONF_html(WiFiClient client) { String htmlwk ; // 変数置換え処理 ------------------------------------------------------------ htmlwk = html_CONF ; 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") ; // } htmlwk.replace("$footer",foot_msg ) ; // -------------------------------------------------------------------------- send_html(client,htmlwk) ; // HTML 送信処理 }
// ***************************************************************************** // * 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 // // ***************************************************************************** // * メイン用初期設定ファイル をリードし、グローバル変数に値をセットする * // ***************************************************************************** int rd_mainconf() { // File fp ; // 設定ファイル用ファイルポインタ int result = 0 ; // 戻り値 // if (SPIFFS.exists("/mconf.txt")) { // 設定ファイル存在確認 // ファイルがあった場合 ---------------------// result = rd_SPIFFS("/mconf.txt",m_config) ; // m_config に config.txt を格納 } else { // // ファイルが無かった場合 -------------------// Serial.println("メイン設定ファイルなし") ; // 無かったら、APモード result = -1 ; // } // // ファイルが読み込めたら、グローバル変数にセットする if (result == 0) // # ifdef DEBUG // デバッグ用表示 Serial.println("--- m_config --- ") ; // Serial.println(m_config ) ; // # endif // set_conf2param() ; // m_config の内容を変数に設定 return result ; // } // ---------------------------------------------------------------------------- // - 設定ファイルの内容を グローバル変数に 設定する - // ---------------------------------------------------------------------------- void set_conf2param() { int pos = 0 ; int npos = 0 ; String s_work ; String s_name ; String s_data ; // 記載内容を順次処理 ( 設定情報を取り出し、グローバル変数に設定する ) ------ while(1) { if (m_config.charAt(pos) == '/') { // 先頭が '/' なら 次の行へ npos = m_config.indexOf('\n',pos) ; // pos = npos + 1 ; // } else { // npos = m_config.indexOf(':',pos) ; // ':' までの文字をs_name に取得 if (npos == -1) break ; // 見つからなければ終了 s_name = m_config.substring(pos,npos) ; // s_name.trim() ; // pos = npos+1 ; // ポインタを ':' の次へ npos = m_config.indexOf('\n',pos) ; // '\n' までの文字をs_data に取得 if (npos == -1) npos = m_config.length() ; // s_data = m_config.substring(pos,npos) ; // s_data.trim() ; // pos = npos+1 ; // set_param(s_name,s_data) ; // 取得した内容をグローバル変数に設定 } // } // } // // - 設定内容を判定し、グローバル変数に設定 ------------------------------------ void set_param(String &name, String &data) { // if (name.compareTo("prg_loop")==0) { // 'prg_loop' の場合 prg_tbl[0][0] = data.toInt() ; // } // if (name.compareTo("prg_loopnum")==0) { // 'prg_loopnum' の場合 prg_tbl[0][1] = data.toInt() ; // } // if (name.compareTo("prg_1_acc")==0) { // 'prg_1_acc' の場合 prg_tbl[1][2] = data.toInt() ; // } // if (name.compareTo("prg_1_spd")==0) { // 'prg_1_spd' の場合 prg_tbl[1][3] = data.toInt() ; // } // if (name.compareTo("prg_1_tim")==0) { // 'prg_1_tim' の場合 prg_tbl[1][4] = data.toInt() ; // } // if (name.compareTo("prg_2_en")==0) { // 'prg_2_en' の場合 prg_tbl[2][0] = data.toInt() ; // } // if (name.compareTo("prg_2_trg")==0) { // 'prg_2_trg' の場合 prg_tbl[2][1] = data.toInt() ; // } // if (name.compareTo("prg_2_acc")==0) { // 'prg_2_acc' の場合 prg_tbl[2][2] = data.toInt() ; // } // if (name.compareTo("prg_2_spd")==0) { // 'prg_2_spd' の場合 prg_tbl[2][3] = data.toInt() ; // } // if (name.compareTo("prg_2_tim")==0) { // 'prg_2_tim' の場合 prg_tbl[2][4] = data.toInt() ; // } // if (name.compareTo("prg_3_en")==0) { // 'prg_3_en' の場合 prg_tbl[3][0] = data.toInt() ; // } // if (name.compareTo("prg_3_trg")==0) { // 'prg_3_trg' の場合 prg_tbl[3][1] = data.toInt() ; // } // if (name.compareTo("prg_3_acc")==0) { // 'prg_3_acc' の場合 prg_tbl[3][2] = data.toInt() ; // } // if (name.compareTo("prg_3_spd")==0) { // 'prg_3_spd' の場合 prg_tbl[3][3] = data.toInt() ; // } // if (name.compareTo("prg_3_tim")==0) { // 'prg_3_tim' の場合 prg_tbl[3][4] = data.toInt() ; // } // if (name.compareTo("prg_4_en")==0) { // 'prg_4_en' の場合 prg_tbl[4][0] = data.toInt() ; // } // if (name.compareTo("prg_4_trg")==0) { // 'prg_4_trg' の場合 prg_tbl[4][1] = data.toInt() ; // } // if (name.compareTo("prg_4_acc")==0) { // 'prg_4_acc' の場合 prg_tbl[4][2] = data.toInt() ; // } // if (name.compareTo("prg_4_spd")==0) { // 'prg_4_spd' の場合 prg_tbl[4][3] = data.toInt() ; // } // if (name.compareTo("prg_4_tim")==0) { // 'prg_4_tim' の場合 prg_tbl[4][4] = data.toInt() ; // } // if (name.compareTo("prg_5_en")==0) { // 'prg_5_en' の場合 prg_tbl[5][0] = data.toInt() ; // } // if (name.compareTo("prg_5_trg")==0) { // 'prg_5_trg' の場合 prg_tbl[5][1] = data.toInt() ; // } // if (name.compareTo("prg_5_acc")==0) { // 'prg_5_acc' の場合 prg_tbl[5][2] = data.toInt() ; // } // if (name.compareTo("prg_5_spd")==0) { // 'prg_5_spd' の場合 prg_tbl[5][3] = data.toInt() ; // } // if (name.compareTo("prg_5_tim")==0) { // 'prg_5_tim' の場合 prg_tbl[5][4] = data.toInt() ; // } // } // // **************************************************************************** // * ステーションモードで サーバーを起動 * // **************************************************************************** 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 送信処理 * // ***************************************************************************** // ----------------------------------------------------------------------------- // - メイン_HTML 送信 - // ----------------------------------------------------------------------------- void send_MAIN_html(WiFiClient client) { String htmlwk ; // HTML 編集用 ワーク // htmlwk = html_pwpk ; // HTML をワークにコピー // // 変数を値に変換-----------------------------// htmlwk.replace("$pwr",String(duty)) ; // htmlwk.replace("$pwmin",String(base_val)) ; // # ifdef DEBUG_WiFi // Serial.print("radio_local = "); // Serial.println(local); // Serial.print("pwr = "); // Serial.println(duty); // #endif // if (local) { // htmlwk.replace("$checked_lo","checked") ; // htmlwk.replace("$checked_rm","") ; // } else { // htmlwk.replace("$checked_lo","") ; // htmlwk.replace("$checked_rm","checked") ; // } // if (dir_bkwd) { // htmlwk.replace("$checked_fw","") ; // htmlwk.replace("$checked_bw","checked") ; // }else { // htmlwk.replace("$checked_fw","checked") ; // htmlwk.replace("$checked_bw","") ; // } // // // HTML 送信----------------------------------// send_html(client,htmlwk) ; // HTML 送信 } // // // ---------------------------------------------------------------------------- // - XHR RESPONSE_HTML 送信 - // ---------------------------------------------------------------------------- void send_resp_html(WiFiClient client) { // String htmlwk ; // HTML 編集用 ワーク // htmlwk = html_resp ; // htmlwk に HTML をコピー // // 変数を値に変換-----------------------------// htmlwk.replace("$pwr",String(duty)) ; // // send_html(client,htmlwk) ; // HTML 送信処理 # ifdef DEBUG_WiFi // Serial.print("xhr value :"); Serial.println(duty); #endif // } // // // ----------------------------------------------------------------------------- // - メイン設定_HTML 送信 - // ----------------------------------------------------------------------------- void send_MCONF_html(WiFiClient client) { // String htmlwk ; // HTML 編集用ワーク // htmlwk = html_MCONF ; // html を ワークにコピー // // 変数を値に変換-----------------------------// if (prg_tbl[0][0]) { // loop チェックマーク htmlwk.replace("$checked_loop","checked") ; // } else { // htmlwk.replace("$checked_loop","") ; // } // htmlwk.replace("$loopnum",String(prg_tbl[0][1])) ; // loop 間隔 // 設定1 ----------------------------------// htmlwk.replace("$acc1",String(prg_tbl[1][2])) ; // 設定1 加速度 htmlwk.replace("$spd1",String(prg_tbl[1][3])) ; // 設定1 加速度 htmlwk.replace("$tim1",String(prg_tbl[1][4])) ; // 設定1 加速度 // 設定2 ----------------------------------/// if (prg_tbl[2][0]) { // 設定 2 許可 htmlwk.replace("$en2","checked") ; // } else { // htmlwk.replace("$en2","") ; // } // if (prg_tbl[2][1] == 0) { // 設定 2 起点 htmlwk.replace("$trg2_sel0","selected") ; // htmlwk.replace("$trg2_sel1","") ; // } else if (prg_tbl[2][1] == 1) { // htmlwk.replace("$trg2_sel0","") ; // htmlwk.replace("$trg2_sel1","selected") ; // } // htmlwk.replace("$acc2",String(prg_tbl[2][2])) ; // 設定2 加速度 htmlwk.replace("$spd2",String(prg_tbl[2][3])) ; // 設定2 加速度 htmlwk.replace("$tim2",String(prg_tbl[2][4])) ; // 設定2 加速度 // // 設定3 ----------------------------------/// if (prg_tbl[3][0]) { // 設定 2 許可 htmlwk.replace("$en3","checked") ; // } else { // htmlwk.replace("$en3","") ; // } // if (prg_tbl[3][1] == 0) { // 設定 3 起点 htmlwk.replace("$trg3_sel0","selected") ; // htmlwk.replace("$trg3_sel1","") ; // } else if (prg_tbl[3][1] == 1) { // htmlwk.replace("$trg3_sel0","") ; // htmlwk.replace("$trg3_sel1","selected") ; // } // htmlwk.replace("$acc3",String(prg_tbl[3][2])) ; // 設定3 加速度 htmlwk.replace("$spd3",String(prg_tbl[3][3])) ; // 設定3 加速度 htmlwk.replace("$tim3",String(prg_tbl[3][4])) ; // 設定3 加速度 // // 設定4 ----------------------------------/// if (prg_tbl[4][0]) { // 設定 4 許可 htmlwk.replace("$en4","checked") ; // } else { // htmlwk.replace("$en4","") ; // } // if (prg_tbl[4][1] == 0) { // 設定 4 起点 htmlwk.replace("$trg4_sel0","selected") ; // htmlwk.replace("$trg4_sel1","") ; // } else if (prg_tbl[4][1] == 1) { // htmlwk.replace("$trg4_sel0","") ; // htmlwk.replace("$trg4_sel1","selected") ; // } // htmlwk.replace("$acc4",String(prg_tbl[4][2])) ; // 設定4 加速度 htmlwk.replace("$spd4",String(prg_tbl[4][3])) ; // 設定4 加速度 htmlwk.replace("$tim4",String(prg_tbl[4][4])) ; // 設定4 加速度 // // 設定5 ----------------------------------/// if (prg_tbl[5][0]) { // 設定 5 許可 htmlwk.replace("$en5","checked") ; // } else { // htmlwk.replace("$en5","") ; // } // if (prg_tbl[5][1] == 0) { // 設定 5 起点 htmlwk.replace("$trg5_sel0","selected") ; // htmlwk.replace("$trg5_sel1","") ; // } else if (prg_tbl[5][1] == 1) { // htmlwk.replace("$trg5_sel0","") ; // htmlwk.replace("$trg5_sel1","selected") ; // } // htmlwk.replace("$acc5",String(prg_tbl[5][2])) ; // 設定5 加速度 htmlwk.replace("$spd5",String(prg_tbl[5][3])) ; // 設定5 加速度 htmlwk.replace("$tim5",String(prg_tbl[5][4])) ; // 設定5 加速度 // // HTML 送信----------------------------------// 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 // } // // // ***************************************************************************** // * メイン処理 * // ***************************************************************************** // ---------------------------------------------------------------------------- // - PWPK メイン画面の クライアントからのフォームデータ 処理 - // ---------------------------------------------------------------------------- int proc_main(String &line) { String s_work ="" ; bool workflg = false ; int val ; int xhr = 0 ; // remote/local のラジオボタンが設定された時の処理 -------------------------- if (line.indexOf("GET /?remote") != -1) { // s_work = getvalue_s(line,"?remote=") ; // remote に続く文字列を取得 if (s_work=="local") { // local の場合 local = true ; // local フラグを ON } else { // remote の場合 local = false ; // local フラグを OFF localen = false ; // locavollen フラグを OFF } // } // // 進行方向が操作された場合の処理 -------------------------------------- if (line.indexOf("GET /?dir") != -1) { // s_work = getvalue_s(line,"?dir=") ; // dir に続く文字列を取得 if (!local) { // 遠隔時 if (!running) { // 走行中でない時 workflg = dir_bkwd ; // 現在の状態を一時保存 if (s_work=="foward") { // 進行方向を設定 dir_bkwd = false ; // } else { // dir_bkwd = true ; // } // if (workflg != dir_bkwd) { // 状態が変わった場合に変更 dir_change = true ; // } // } // } // } // // 出力値がセットされた場合の処理 ----------------------------------------- if (line.indexOf("GET /?pwr_v") != -1) { // val = getvalue_i(line,"?pwr_v=") ; // gw2 に続く数値を変数にセット if (!local) { // if (val>256) val = 255 ; // 255 にクリップ duty = val ; // デューティを設定 } // } // // スライダーが操作された場合の処理 ----------------------------------------- if (line.indexOf("GET /?slid") != -1) { // val = getvalue_i(line,"?slid=") ; // gw2 に続く数値を変数にセット if (!local) { // if (val>256) val = 255 ; // duty = val ; // } // xhr = 1 ; // スライダー操作時は レスポンス } // // 準備/解除がセットされた場合の処理 ---------------------------------------- if (line.indexOf("GET /?ready") != -1) { // if (!local) { // if (ready == false) { // ready = true ; // base_val = base ; // 最低速度を 設定 rdy_change = true ; // if (duty < base_val) // duty = base_val ; // }else{ // ready = false ; // base_val = 0 ; // 最低速度を 0 にする。 rdy_change = true ; // duty = base_val ; // } // } // } // // 発車/停車がセットされた場合の処理 ---------------------------------------- if (line.indexOf("GET /?start") != -1) { // if (!local) { // start_sw = true ; // } // xhr = 1 ; // start 時は、XHR 応答 } // // ポーリング要求があった場合の処理 ----------------------------------------- if (line.indexOf("GET /?pol") != -1) { // xhr = 1 ; // ポーリング時、XHR 応答 } // // 運行設定の処理 ----------------------------------------------------------- if (line.indexOf("GET /?mconf") != -1) { // 運行設定の場合、 html_mode=MAIN_CONF; // HTML を 運行設定用にする } // // WiFi設定の処理 ----------------------------------------------------------- if (line.indexOf("GET /?config") != -1) { // WiFi設定の場合、 html_mode=WIFI_CONF; // HTML を WiFi設定 にする } // // -------------------------------------------------------------------------- return xhr ; // 戻り値は、 xhr かどうか } // // // ---------------------------------------------------------------------------- // - メイン設定の クライアントからのフォームデータ 処理 - // ---------------------------------------------------------------------------- void set_mconf2param(String &line) { String s_work ="" ; // クライアントからのデータを グローバル変数にセットする。 ------------------ if (line.indexOf("set=") != -1) { // set if (line.indexOf("loop=") != -1) { // prg_loop チェック有 prg_tbl[0][0] = true ; // } else { // チェック無し prg_tbl[0][0] = false ; // } // if (line.indexOf("loopnum=") != -1) { // prg_loop_num prg_tbl[0][1] = getvalue_i(line,"loopnum=") ; // loopnum に続く文字列を取得 } if (line.indexOf("acc1=") != -1) { // prg_1_acc prg_tbl[1][2] = getvalue_i(line,"acc1=") ; // acc1 に続く数値を変数にセット } if (line.indexOf("spd1=") != -1) { // prg_1_spd prg_tbl[1][3] = getvalue_i(line,"spd1=") ; // spd1 に続く数値を変数にセット } if (line.indexOf("tim1=") != -1) { // prg_1_tim prg_tbl[1][4] = getvalue_i(line,"tim1=") ; // tim1 に続く数値を変数にセット } if (line.indexOf("chk2=") != -1) { // prg_2_en チェック有 prg_tbl[2][0] = true ; // } else { // チェック無し prg_tbl[2][0] = false ; // } if (line.indexOf("trg2=") != -1) { // prg_2_trg prg_tbl[2][1] = getvalue_i(line,"trg2=") ; // trg2 に続く数値を変数にセット } if (line.indexOf("acc2=") != -1) { // prg_2_acc prg_tbl[2][2] = getvalue_i(line,"acc2=") ; // acc2 に続く数値を変数にセット } if (line.indexOf("spd2=") != -1) { // prg_2_spd prg_tbl[2][3] = getvalue_i(line,"spd2=") ; // spd2 に続く数値を変数にセット } if (line.indexOf("tim2=") != -1) { // prg_2_tim prg_tbl[2][4] = getvalue_i(line,"tim2=") ; // tim2 に続く数値を変数にセット } if (line.indexOf("chk3=") != -1) { // prg_3_en チェック有 prg_tbl[3][0] = true ; // } else { // チェック無し prg_tbl[3][0] = false ; // } if (line.indexOf("trg3=") != -1) { // prg_3_trg prg_tbl[3][1] = getvalue_i(line,"trg3=") ; // trg3 に続く数値を変数にセット } if (line.indexOf("acc3=") != -1) { // prg_3_acc prg_tbl[3][2] = getvalue_i(line,"acc3=") ; // acc3 に続く数値を変数にセット } if (line.indexOf("spd3=") != -1) { // prg_3_spd prg_tbl[3][3] = getvalue_i(line,"spd3=") ; // spd3 に続く数値を変数にセット } if (line.indexOf("tim3=") != -1) { // prg_3_tim prg_tbl[3][4] = getvalue_i(line,"tim3=") ; // tim3 に続く数値を変数にセット } if (line.indexOf("chk4=") != -1) { // prg_4_en チェック有 prg_tbl[4][0] = true ; // } else { // チェック無し prg_tbl[4][0] = false ; // } if (line.indexOf("trg4=") != -1) { // prg_4_trg prg_tbl[4][1] = getvalue_i(line,"trg4=") ; // trg4 に続く数値を変数にセット } if (line.indexOf("acc4=") != -1) { // prg_4_acc prg_tbl[4][2] = getvalue_i(line,"acc4=") ; // acc4 に続く数値を変数にセット } if (line.indexOf("spd4=") != -1) { // prg_4_spd prg_tbl[4][3] = getvalue_i(line,"spd4=") ; // spd4 に続く数値を変数にセット } if (line.indexOf("tim4=") != -1) { // prg_4_tim prg_tbl[4][4] = getvalue_i(line,"tim4=") ; // tim4 に続く数値を変数にセット } if (line.indexOf("chk5=") != -1) { // prg_5_en チェック有 prg_tbl[5][0] = true ; // } else { // チェック無し prg_tbl[5][0] = false ; // } if (line.indexOf("trg5=") != -1) { // prg_5_trg prg_tbl[5][1] = getvalue_i(line,"trg5=") ; // trg5 に続く数値を変数にセット } if (line.indexOf("acc5=") != -1) { // prg_5_acc prg_tbl[5][2] = getvalue_i(line,"acc5=") ; // acc5 に続く数値を変数にセット } if (line.indexOf("spd5=") != -1) { // prg_5_spd prg_tbl[5][3] = getvalue_i(line,"spd5=") ; // spd5 に続く数値を変数にセット } if (line.indexOf("tim5=") != -1) { // prg_5_tim prg_tbl[5][4] = getvalue_i(line,"tim5=") ; // tim5 に続く数値を変数にセット } if (line.indexOf("save=") != -1) { // prg_5_en チェック有 Serial.println("write main config ") ; wr_config() ; // } Serial.println("set html_mode MAIN") ; html_mode = MAIN ; // } if (line.indexOf("rtn=") != -1) { // 戻るの場合 Serial.println("retuen MAIN mode") ; html_mode = MAIN ; // } } // ----------------------------------------------------------------------------- // - グローバル変数の内容を設定ファイルに書き出す - // ----------------------------------------------------------------------------- void wr_config() { char s_work[1024] ; File fp ; Serial.println("make m_config data") ; // String に 変数の内容を書き込む ------------------------------------------- sprintf(s_work,"prg_loop : %d\n",prg_tbl[0][0] ) ; // m_config = String(s_work) ; // sprintf(s_work,"prg_loopnum : %d\n",prg_tbl[0][1] ) ; // m_config += String(s_work) ; // sprintf(s_work,"prg_1_acc : %d\n",prg_tbl[1][2] ) ; // m_config += String(s_work) ; // sprintf(s_work,"prg_1_spd : %d\n",prg_tbl[1][3] ) ; // m_config += String(s_work) ; // sprintf(s_work,"prg_1_tim : %d\n",prg_tbl[1][4] ) ; // m_config += String(s_work) ; // sprintf(s_work,"prg_2_en : %d\n",prg_tbl[2][0] ) ; // m_config += String(s_work) ; // sprintf(s_work,"prg_2_trg : %d\n",prg_tbl[2][1] ) ; // m_config += String(s_work) ; // sprintf(s_work,"prg_2_acc : %d\n",prg_tbl[2][2] ) ; // m_config += String(s_work) ; // sprintf(s_work,"prg_2_spd : %d\n",prg_tbl[2][3] ) ; // m_config += String(s_work) ; // sprintf(s_work,"prg_2_tim : %d\n",prg_tbl[2][4] ) ; // m_config += String(s_work) ; // sprintf(s_work,"prg_3_en : %d\n",prg_tbl[3][0] ) ; // m_config += String(s_work) ; // sprintf(s_work,"prg_3_trg : %d\n",prg_tbl[3][1] ) ; // m_config += String(s_work) ; // sprintf(s_work,"prg_3_acc : %d\n",prg_tbl[3][2] ) ; // m_config += String(s_work) ; // sprintf(s_work,"prg_3_spd : %d\n",prg_tbl[3][3] ) ; // m_config += String(s_work) ; // sprintf(s_work,"prg_3_tim : %d\n",prg_tbl[3][4] ) ; // m_config += String(s_work) ; // sprintf(s_work,"prg_4_en : %d\n",prg_tbl[4][0] ) ; // m_config += String(s_work) ; // sprintf(s_work,"prg_4_trg : %d\n",prg_tbl[4][1] ) ; // m_config += String(s_work) ; // sprintf(s_work,"prg_4_acc : %d\n",prg_tbl[4][2] ) ; // m_config += String(s_work) ; // sprintf(s_work,"prg_4_spd : %d\n",prg_tbl[4][3] ) ; // m_config += String(s_work) ; // sprintf(s_work,"prg_4_tim : %d\n",prg_tbl[4][4] ) ; // m_config += String(s_work) ; // sprintf(s_work,"prg_5_en : %d\n",prg_tbl[5][0] ) ; // m_config += String(s_work) ; // sprintf(s_work,"prg_5_trg : %d\n",prg_tbl[5][1] ) ; // m_config += String(s_work) ; // sprintf(s_work,"prg_5_acc : %d\n",prg_tbl[5][2] ) ; // m_config += String(s_work) ; // sprintf(s_work,"prg_5_spd : %d\n",prg_tbl[5][3] ) ; // m_config += String(s_work) ; // sprintf(s_work,"prg_5_tim : %d\n",prg_tbl[5][4] ) ; // m_config += String(s_work) ; // Serial.println("m_config_data make end ") ; // 設定ファイルに書き込む ---------------------------------------------------- Serial.println("now write main config ...........") ; fp = SPIFFS.open("/mconf.txt",FILE_WRITE) ; // 設定ファイルを開く if (!fp) { Serial.println(" 設定ファイル オープンエラー !!") ; } else { Serial.println("/mconf.txt open complete ") ; // 初期設定ファイル書き込み ------------------------------------------------- if(fp.print(m_config)) { // ファイルに書き込み Serial.println("m_config written") ; // 終了メッセージ } else { // Serial.println("m_config write error !!") ; // 失敗メッセージ } // fp.close() ; // ファイルクローズ } // } // // ---------------------------------------------------------------------------- // - 定期割込み処理 - // ---------------------------------------------------------------------------- void execTicker() { ticker_val = true ; // フラグを True にするだけ。 } // 定期処理 (定期割込みフラグが立っていた時の処理) ------------------------ void do_JOB() { bool workflg = false ; // +--------------------------------------------------------------------- // | 制御盤情報の取得 | // +--------------------------------------------------------------------- // loxal の場合 制御盤情報を取得する。----------------------------------- if (local == true) { // 出力用ボリューム値を取得 ------------------------------------------- vol_value = analogRead(PWR_VOL); // 制御盤の操作が許可されていた場合 ----------------------------------- if (localen == true) { // 進行方向スイッチのチェック --------------------------------------- if (!running) { // 走行中は切り替え不可 workflg = dir_bkwd ; // 現在の状態を一時保存 if (!digitalRead(SW_FWD)) { // SW_FWD : Low Active dir_bkwd = 0 ; // } // if (!digitalRead(SW_BWD)) { // SW_BWD : Low Activ dir_bkwd = 1 ; // } // if (workflg != dir_bkwd) { // 状態が変わった場合に変更 dir_change = true ; } // } // // // 準備/解除スイッチのチェック --------------------------------------- if (!digitalRead(SW_READY)) { // SW_READY が押された時 (Low Active) if (pre_rdy == false ) { // 前回割り込み時、SW が OFF if (ready == false) { // かつ LED常時点灯になっていない場合 ready = true ; // ON にする base_val = base ; // 最低速度を 設定 rdy_change = true ; // 準備要求状態変化フラグを ON } else { // LED常時点灯中の場合 ready = false ; // OFF にする base_val = 0 ; // 最低速度を 0 にする。 rdy_change = true ; // 準備要求状態変化フラグを ON } // } // pre_rdy = true ; // 前回割り込み情報を更新 } else { // pre_rdy = false ; // } // // // 発車/停車が押下された場合の処理 ------------------------------------------- if (!digitalRead(SW_START)) { // SW_START が押された時 ( Low Active) if (pre_strt == false) { // 前回割込み時、SW が OFF start_sw = true ; // 発車要求フラグを ON } // pre_strt = true ; // 前回割り込み情報を更新 } else { // pre_strt = false ; // } // // // PWM の デューティを設定 ---------------------------------------------- if (prg_run == false) // 自動走行でない場合 duty = ((vol_value*(255-base_val))/4095)+base_val ; // ボリュームの値で 出力制御 // Local だが、制御盤の操作が許可されていない場合 -------------------------- } else { duty = base_val ; // 出力 OFF // ボリューム が 0 の場合 if (vol_value == 0) // ボリュームが 0 に戻されたら localen = true ; // 制御盤の操作を許可する。 } // // remote の場合 ------------------------ } else { // 準備/解除スイッチのチェック 押されたら Local にする -------------------- if (!digitalRead(SW_READY)) { // SW_START が押された時 ( Low Active) if (pre_rdy == false) { // 前回割込み時、SW が OFF local = true ; // Local(制御盤操作可能) にする localen = false ; // 制御盤操作許可は OFF } pre_rdy = true ; // 前回割り込み情報を更新 } else { pre_rdy = false ; } } // +------------------------------------------------------------------------- // | 自動運転制御 | // +------------------------------------------------------------------------- // 発車 処理 (自動 加減速 開始) REMOTE/LOCAL 共通処理 ---------------------- if (start_sw == true) { // 発車要求スイッチ押下状態 が 真の場合 if (prg_run == false) { // 自動運行中でなければ、 prg_start = true ; // 自動運行開始指示。 } else { // 自動運行中の場合 if (wait_sw) { // STARTスイッチ待ちなら prg_next = true ; // 次No.の実行を指示 st_on = true ; // ステータス LED ON (更新) } else { // でなければ start = false ; // 発車要求フラグを OFF stop = true ; // 停車要求フラグを ON } // } // start_sw = false ; // 発車要求スイッチ状態を OFF } // // // 自動運転開始指示時 ----------------// if (prg_start == true) { // 自動運行開始時。(まだ動いていない時) prg_no = 1 ; // 実行する 運動設定 No. を '1' に設定。 rate = prg_tbl[1][2] ; // 加速度設定 target = prg_tbl[1][3] ; // 目標速度設定 prg_tim = prg_tbl[1][4] ; // 運行時間設定 prg_loopnum = prg_tbl[0][1] ; // ループ回数を取得。 if (target < base_val) // 目標速度が 最低速度より小さい時 target = base_val ; // 目標速度は 最低速度 start = true ; // 発車要求 stop = false ; // wait_sw = false ; // st_on = true ; // LED 点灯設定 st_val = prg_no ; // ステータス LED 表示番号設定 prg_start = false ; // prg_run = true ; // 自動運行フラグをセット。 Serial.print("prg_no :") ; Serial.print(prg_no) ; start_time = millis(); // 開始時刻を取得 } // // // 自動運行中の処理 --------------------------------------------------------- if (prg_run == true) { // 自動運行実行中の場合 now_time = millis() ; // 現在時刻を取得 if (prg_tim <= // 経過時間が運行時間以上になったら ((now_time - start_time)/100) ) { // time_ovr = true ; // 運行時間オーバー } // // // 運行時間経過時、次の運行No.を選択// if (!wait_sw & time_ovr) { // 運行時間オーバーでスイッチ待ちでない時 nextno = prg_no + 1 ; // 次の運行No.を設定。 while (nextno != prg_no) { // No.が 一周するまでチェック if (nextno > 5) { // No.が上限を超えた場合、 if ( (prg_tbl[0][0] == 1) // ループ En で && (prg_loopnum > 1)) { // 繰り返し回数が 1以下でなければ nextno = 1 ; // No. を最初にする。 prg_loopnum = prg_loopnum -1 ;// Serial.print("loopnum:") ; Serial.println(prg_loopnum) ; } else { // ループ En でないか、繰り返し回数 // に達してれば nextno = prg_no ; // No.を現状にして now_time = millis() ; // 現在時刻を取得 now_time = now_time - start_time ;// 経過時間を取得 Serial.print(" | time : "); // Serial.println(now_time) ; // stop = true ; // 停車要求 break ; // while を抜ける } } // if (prg_tbl[nextno][0] == 0) { // 選択したNo.が有効(En)でなければ、 nextno = nextno + 1 ; // 次の No. } else { // 選択したNo.が有効(En)な時、 prg_no = nextno ; // 運行No.を選択したNo.に更新 if (prg_tbl[prg_no][1] == 0) // 起点が前No.の続きなら、 prg_next = true ; // 次No.の運行を指示 else{ // 起点がスイッチ押下なら、 wait_sw = true ; // スイッチ待ちフラグを ON st_blink = true ; // ステータス点滅設定 st_bl_intvl = 5 ; // 点滅間隔設定 } // break ; // 次No.選択を抜ける。 } // } // time_ovr = false ; // } // // // 設定更新指示時 ------------------// if (prg_next == true) { // 設定更新の場合 rate = prg_tbl[prg_no][2] ; // 加速度設定 target = prg_tbl[prg_no][3] ; // 目標速度設定 prg_tim = prg_tbl[prg_no][4] ; // 運行時間設定 if (target < base_val) // 目標速度が 最低速度より小さい時 target = base_val ; // 目標速度は 最低速度 start = true ; // 発車要求 stop = false ; // wait_sw = false ; // st_on = true ; // LED 点灯設定 st_val = prg_no ; // ステータス LED 表示番号設定 now_time = millis() ; // 現在時刻を取得 now_time = now_time - start_time ;// 経過時間を取得 Serial.print(" | time : ") ; Serial.println(now_time) ; Serial.print("prg_no :") ; Serial.print(prg_no) ; start_time = millis(); // 開始時刻を取得 prg_next = false ; // 設定更新終了 } // // // 発車要求時 ----------------------// if (start == true) { // 発車要求フラグ が 真の場合 autorun = true ; // 自動走行中のフラグを ON // 速度が目標値未満の時 ----------// if (duty < target) { // 現状が目標デューティ未満の時 if (duty < base) // LED常時点灯時の値未満の時は duty = base ; // LED常時点灯時の値に更新 if ((target - duty) < rate) // 目標値との差分が増減値未満の時 duty = target ; // 出力を目標値に更新 else // 増減値以上の場合 duty = duty + rate ; // 出力を 増減値分加算 // 速度が目標値より大きい時 ------// } else if (duty > target){ // 現状が目標デューティより大きい時 if ((duty - target) < rate) // 目標値との差分が増減値未満の時 duty = target ; // 出力を目標値に更新 else // 増減値以上の時 duty = duty - rate ; // 出力を 増減値分減算 // 目標値となった時 --------------// } else { // 目標デューティに達したら now_time = millis() ; // 現在時刻を取得 now_time = now_time - start_time ;// 経過時間を取得 Serial.print(" duty:") ; Serial.print(duty) ; Serial.print(" | time : "); // Serial.print(now_time) ; // Serial.print(" | ") ; // start = false ; // 発車要求を解除 } // } // // // 停車要求時 ----------------------// if (stop == true) { // 停車要求フラグが真の場合 autorun = true ; // 自動走行中のフラグを ON if (duty > base_val){ // 現状が、最低速度より大きい時 if ((duty - base_val) < rate) // 最低速度との差分が増減値未満の時 duty = base_val ; // 出力を 最低族度に設定 else // 増減値以上の時 duty = duty - rate ; // 出力を 増減値 分減算 } else { // 最低速度以下の時 stop = false ; // 停車要求を OFF autorun = false; // 自動走行中フラグを OFF prg_run = false; // 自動運行中フラグを OFF if (ready == true) { // LED常時点灯の場合 st_blink = true ; // ステータス点滅 ON st_val = 7 ; // ステータス値を 7 st_bl_intvl = 5 ; // 点滅間隔 5 } else { // 常時点灯ではない場合 st_on = true ; // ステータスLED 消灯 st_val = 0 ; // } // } // } // // 自動運行中でない時 ----------------// } else { // 自動運行実行中ではない時 if (rdy_change) { // 準備要求状態変化フラグがONの時 if (ready) { // 常時点灯なら、 st_blink = true ; // LED点滅を設定 st_val = 7 ; // st_bl_intvl = 5 ; // } else { // 常時点灯でなければ st_on = true ; // LED消灯を設定 st_val = 0 ; // } // rdy_change = false ; // } // } // // // 走行中フラグを更新 ------------------------------------------------------- if (duty > base_val) // 最低速度より大きな Duty の時 running = true ; // 走行中フラグを ON else // 最低速度以下の時 running = false ; // 走行中フラグを OFF // // +=========================================================================+ // | 操作盤制御 | // +=========================================================================+ // 進行方向 設定 ------------------------------------------------------------- if (dir_change) { // 進行方向が変化した時の設定 ledcWrite(0, 0) ; // 切り替え前に PWM出力を停止 delay(10); // digitalWrite(LED_FWD,!dir_bkwd) ; // 前進用 LED 設定 digitalWrite(LED_BWD,dir_bkwd) ; // 後退用 LED 設定 digitalWrite(DIR_OUT,dir_bkwd) ; // 進行方向用リレー 設定 delay(10); // ledcWrite(0, duty) ; // PWM出力を元に戻す。 dir_change = false ; } // // // ステータス LED 制御 ------------------------------------------------------- // ( ステータス LED を点灯 ) ------------// if (st_on == true) { // ステータス 点灯要求時 digitalWrite(LED_ST3, (st_val & 0x01) != 0) ; // LED 設定 digitalWrite(LED_ST2, (st_val & 0x02) != 0) ; // digitalWrite(LED_ST1, (st_val & 0x04) != 0) ; // st_on = false ; // st_blink = false ; // } // // // ( ステータス LED を点滅 ) ------------// if (st_blink == true) { // 点滅設定時 if (st_bl_off == true) { // 消灯状態時 if (st_bl_cnt == 0) { // カウント値が 0 なら st_bl_cnt = st_bl_intvl ; // カウント値を初期値にする st_bl_off = false ; // LED を点灯状態にする digitalWrite(LED_ST3, (st_val & 0x01) != 0) ; // LED 設定 digitalWrite(LED_ST2, (st_val & 0x02) != 0) ; // digitalWrite(LED_ST1, (st_val & 0x04) != 0) ; // } else { // カウント値が 0 でなければ st_bl_cnt = st_bl_cnt -1 ; // -1 } // } else { // 点灯状態の時 if (st_bl_cnt == 0) { // カウント値が 0 なら st_bl_cnt = st_bl_intvl ; // カウント値を初期値にする st_bl_off = true ; // LED を消灯状態にする digitalWrite(LED_ST3, 0) ; // digitalWrite(LED_ST2, 0) ; // digitalWrite(LED_ST1, 0) ; // } else { // カウント値が 0 でなければ st_bl_cnt = st_bl_cnt -1 ; // -1 } // } // } // // // PWM デューティを設定 ---------------------------------------------------- ledcWrite(0, duty) ; // PWM デューティを設定 // // +=========================================================================+ // | 管理情報 | // +=========================================================================+ // 割り込み処理の実行回数をカウント ------------------------------------------ loopcnt++ ; // ループ回数 インクリメント // // 実行回数が 10 回目の場合 (1秒毎) ------------------------------------------ if (loopcnt ==10) { // # ifdef DEBUG_Hard // デバッグ用出力 Serial.println("") ; // Serial.print( "PWR_VOL :") ; Serial.println(vol_value) ; Serial.print( "duty :") ; Serial.println(duty) ; Serial.print( "running :") ; Serial.println(running) ; Serial.print( "autorun :") ; Serial.println(autorun) ; Serial.print( "stop :") ; Serial.println(stop ) ; Serial.print( "ready :") ; Serial.println(ready) ; Serial.print( "start :") ; Serial.println(start) ; Serial.print( "prg_start:") ; Serial.println(prg_start) ; Serial.print( "prg_next :") ; Serial.println(prg_next ) ; Serial.print( "prg_run :") ; Serial.println(prg_run ) ; Serial.print( "prg_tim :") ; Serial.println(prg_tim ) ; #endif // // loopcnt = 0; // ループ回数をクリア } // ticker_val = false ; // 処理を実行したら、定期割込みフラグ // を false にする。 } // //
以下、メモ
<WiFi設定 HTML> "softAPでWiFi設定" からの変更部分
・"戻る"ボタンを追加。
<PWPK設定 HTML>
・新規追加
・自動走行時の走行パターン(加速度,速度,走行時間等を 最大5パターン)設定可能
<MAIN HTML>
"パワーパック_改" からの変更部分
・WiFi設定、運行設定のボタンを追加・スライダーの MIN 値を変数化(LED常時点灯時用)
<MAIN スケッチ>
・詳細は コメント参照。
(行#1~4)
include文。SPIFFS, Ticker を使用。
(行#9~53)
WiFi設定用 変数等を定義。
APモード時の SSID は "ESP32_AP", パスワードは "password"
HTML の ファイル名もここで定義。
(行#54~135)
パワーパック制御、自動運行用の変数等を定義。
LED,SW に接続するIOピン番号, PWM 周波数 もここで定義。
(行#139~210)
setup 関数。以下の順に実行
・IO PIN 設定
・LED 全点灯 (設定中であることがわかる様に)
・シリアル開始
・SPIFFS開始
・各 HTML ファイルを読み込み
・WiFi設定ファイルを読み込み
・WiFi設定内容により、WiFiのモード(AP or STA) 、
・HTMLモード、画面(WiFi設定 or メイン) を決定。
・サーバーを起動
・PWPK設定を読み込み
・PWM 初期設定
・LED を初期状態に設定 (初期設定終了がわかる様に)
・周期割り込みを起動
・LED 全点灯 (設定中であることがわかる様に)
・シリアル開始
・SPIFFS開始
・各 HTML ファイルを読み込み
・WiFi設定ファイルを読み込み
・WiFi設定内容により、WiFiのモード(AP or STA) 、
・HTMLモード、画面(WiFi設定 or メイン) を決定。
・サーバーを起動
・PWPK設定を読み込み
・PWM 初期設定
・LED を初期状態に設定 (初期設定終了がわかる様に)
・周期割り込みを起動
(行#216~300)
loop 関数。以下の順に実行
・定期割込みフラグが立っていれば、定期処理実行。
・クライアントからの接続があれば、
・クライアントからの接続があれば、
・クライアントからのデータを1行分取得
・"GET /?" であれば、HTMLモードによりフォームデータの解析を実行。
・最終行であれば、HTMLモードにより送信するHTMLを選択して送信。
・WiFiのモードに変更がある場合は、HTMLにリブートメッセージを追加して送信。
・HTML送信後、クライアントを切断。
・WiFiのモードに変更があった場合、リブートを実行。・"GET /?" であれば、HTMLモードによりフォームデータの解析を実行。
・最終行であれば、HTMLモードにより送信するHTMLを選択して送信。
・WiFiのモードに変更がある場合は、HTMLにリブートメッセージを追加して送信。
・HTML送信後、クライアントを切断。
この時、HTML送信直後にリブートを行うと、クライアントが受け取れない
ことがある為、Delay を挿入している。(時間は適当)
ことがある為、Delay を挿入している。(時間は適当)
<WiFi設定 スケッチ>
(行#1~137)
rd_config() : wifi設定をリードして変数に設定。
(行#138~149)
start_AP_server() : アクセスポイントモードでのサーバー起動。
(行#153~176)
disp_modi() : デバッグ用表示
(行#180~331)
set_form2param() : クライアントからのフォームデータを変数に設定し、ファイルに書き出す。
(行#339~374)
send_CONF_html() : WiFi設定用HTML送信。
<PWPK処理 スケッチ>
(行#1~15)
rd_SPIFFS() : SPIFFS ファイルを読み込む
(行#20~151)
rd_mainconf() : pwpk設定をリードして変数に設定。
(行#155~179)
start_STA_server() : ステーションモードでサーバー起動。
(行#185~237)
send_MAIN_html() : MAIN HTML 送信
(行#241~328)
send_MCONF_html() : PWPK設定 HTML 送信
(行#332~343)
send_html() : HTML送信処理
(行#348~440)
proc_main() : MAIN HTML用のクライアントからのフォームデータ処理。
(行#444~627)
set_mconf2param() : PWPK設定 HTML用のクライアントからのフォームデータを変数に設定し、ファイルに書き出す。
(行#631~633)
execTicker() : 定期割込み処理。
(行#636~982)
do_JOB() :
割込み発生時の処理。
・制御盤情報の取得 (スイッチ状態のリード等)してフラグセット。
・自動運転制御。
各フラグの状態から、走行設定を決めて制御フラグをセット
・操作盤制御。
制御フラグに従い、IO出力(LED ON/OFF, PWM Duty設定等) を行う。
の順に実行。
定期割込みが 100mS 毎に発生する為、運行時間は処理回数でカウントしたところ、実行時間のばらつきが多きかった。割り込み処理間隔が 100mS 以上になる場合があると思われる。この為、millis() で経過時間を測定して運行時間を計算する様にした。
・制御盤情報の取得 (スイッチ状態のリード等)してフラグセット。
・自動運転制御。
各フラグの状態から、走行設定を決めて制御フラグをセット
・操作盤制御。
制御フラグに従い、IO出力(LED ON/OFF, PWM Duty設定等) を行う。
の順に実行。
定期割込みが 100mS 毎に発生する為、運行時間は処理回数でカウントしたところ、実行時間のばらつきが多きかった。割り込み処理間隔が 100mS 以上になる場合があると思われる。この為、millis() で経過時間を測定して運行時間を計算する様にした。
0 件のコメント:
コメントを投稿