目的:
Nゲージ用 PWM制御パワーパックの改良/機能追加として、以下を行う。
(1) 各設定のダウンロード/アップロード機能追加
(2) WiFi 設定時に WiFIを再起動するかどうかの設定 を追加
(3) WiFi ハングアップ対応
追加機能:
パワーパック改2 からの追加機能は、以下の通り。
- 各設定のダウンロード/アップロード機能追加
WiFi 設定のダウンロード、アップロード 機能を追加。
( SPIFFSのテキストファイルをダウンロードする
テキストファイルをアップロードする
と同じ )
自動運行設定 のダウンロード、アップロード機能を追加。
( WiFi 設定と同様 )
- WiFi 設定ボタンを押下した時に WiFi を再起動するかどうかの設定を追加。
- Arduino core for the ESP32 の Ver 1.0.2 で、XHR多重発行時に WiFi が ハングアップするケースが有る為、対応を行う。
(1) 多重発行の抑止
・XHR応答受信後、100mS 経過以上で 次の XHR を発行可能とする。
・
(2) WiFi ハングアップ時、操作盤からの操作で WiFi を再起動。
パワーパック ハードウェア:
ハードウェア(回路) はこ
こちら。
(
パワーパック改 から、RESERV 用スイッチ (SW2) をモード設定用に変更。)
WEB画面:
WiFi設定画面 ( WiFi接続先, ESP32 の IPアドレス等を設定する )
PWPK設定画面 ( 自動運行の設定を行う )
PWPKメイン画面 ( PWPK の操作画面 )
スケッチ、HTML等 ファイル構成:
各ファイルは以下の様に分割。
( ファイルの分割は、まだうまく整理できていない。今後見直し要。
まだ、バグ等があると思われるため、参考にする場合は十分確認願います。)
スケッチの拡張子は全て .ino
ファイル一式は
こちら。(zipファイル)
HTML : PWPK MAIN HTML (pwpk.html)
PWPK設定 HTML (pwpk_conf.html)
PWPK XHR 応答 HTML (pwpk_resp.html)
WiFi設定 HTML (wifi_conf.html)
WiFi XHR 応答 HTML (wifi_resp.html)
スケッチ : MAIN (pwpk_4.ino : 変数定義, setup, loop 関数)
WIFI設定 (wifi_config.ino : 主に WiFI 設定用 の関数)
PWPK処理 (pwpk.ino : 主に PWPK処理、PWPK 設定用 の関数)
HTML
<!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 ;
var sendbusy = 0 ;
// スライダー操作時に実行する -------------------------------------------------------------
function setval(pwr){
if (sendbusy == 0) {
sendbusy = 1 ;
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.timeout = 5000; // time in milliseconds
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;
setTimeout( function() { sendbusy = 0 ; },100) ;
}
}
xhr.ontimeout = function(e) {
xhr.abort() ;
setTimeout( function() { sendbusy = 0 ; },100) ;
}
xhr.send();
}
}
// ポーリング時に実行する ----------------------------------------------------------------
function getval(){
if (sendbusy == 0) {
sendbusy = 1 ;
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.timeout = 5000; // time in milliseconds
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);
if (xhrget.response.getElementById("output2").innerHTML == 1) {
document.getElementById('dir_fw').checked = false;
document.getElementById('dir_bw').checked = true ;
} else {
document.getElementById('dir_fw').checked = true ;
document.getElementById('dir_bw').checked = false;
}
if (xhrget.response.getElementById("output3").innerHTML == 1) {
document.getElementById('rad_lo').checked = true ;
document.getElementById('rad_rm').checked = false;
disp_ctrl("local") ;
} else {
document.getElementById('rad_lo').checked = false;
document.getElementById('rad_rm').checked = true ;
disp_ctrl("remote") ;
}
setTimeout( function() { sendbusy = 0 ; },100) ;
}
}
xhrget.ontimeout = function(e) {
xhrget.abort() ;
setTimeout( function() { sendbusy = 0 ; },100) ;
}
xhrget.send();
}
}
// ---------------------------------------------------------------------------------------
// 発車/停車 を押下された時に実行する -----------------------------------------------------
function sw_start() {
while (1) {
if (sendbusy == 0) {
sendbusy = 1 ;
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.timeout = 5000; // time in milliseconds
xhr_start.onreadystatechange = function() {
if( (xhr_start.readyState == 4) && (xhr_start.status == 200) ) {
if (polling == null) polling = setInterval(getval,200) ;
clearInterval(polling);
polling = setInterval(getval,200) ;
setTimeout( function() { sendbusy = 0 ; },100) ;
}
}
xhr_start.ontimeout = function(e) {
xhr_start.abort() ;
setTimeout( function() { sendbusy = 0 ; },100) ;
}
xhr_start.send();
break ;
} else {
}
}
}
// ---------------------------------------------------------------------------------------
// Remote/Local 切り替え時に実行する -----------------------------------------------------
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;
clearInterval(polling);
polling = setInterval(getval,1000) ;
} 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;
document.getElementById('start').disabled = true;
clearInterval(polling);
polling = setInterval(getval,200) ;
}
}
// ---------------------------------------------------------------------------------------
// 最初に実行する ------------------------------------------------------------------------
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;
polling = setInterval(getval,1000) ;
} 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,200) ;
}
}
// ---------------------------------------------------------------------------------------
</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; }
#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%}
#dlul {font-size: 8pt; text-align:left ; height:12pt; float:left; margin:10px 0px 0px 25% ; border:dotted 1px #800080 }
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>
<div id="dlul">
<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>
</form>
</div>
<!-- JAVA SCRIPT ========================================================= -->
<script>
function disp_ctrl_0(enable) {
if (enable == true) {
document.getElementById('loopnum').disabled = false ;
}else {
document.getElementById('loopnum').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 ;
}
}
// 設定ファイルのダウンロード ---------------------------------------------------------
function confdl() {
"use strict";
var xhr = new XMLHttpRequest();
xhr.open("get", "?mcnfld=DLD");
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 = "pwpkcnf.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", "?mcnful"); // 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) ;
// テキストを解析して、各要素に値を代入する ----------------------------
// -- 読み込んだ設定ファイルから 繰り返し設定を取得して 要素に代入
pos = reader.result.indexOf("prg_loop") ;
pos = reader.result.indexOf(":",pos) ;
res = reader.result.substr(pos+1).split("\n") ;
if (res[0] == 1) {
document.getElementById('loop').checked = true ;
disp_ctrl_0(true) ;
} else
document.getElementById('loop').checked = false ;
// 読み込んだ設定ファイルから 繰り返し回数を取得して 要素に代入
pos = reader.result.indexOf("prg_loopnum") ;
pos = reader.result.indexOf(":",pos) ;
res = reader.result.substr(pos+1).split("\n") ;
document.getElementById('loopnum').value = res[0].trim() ;
// 読み込んだ設定ファイルから 設定1の加速度 を取得して 要素に代入
pos = reader.result.indexOf("prg_1_acc") ;
pos = reader.result.indexOf(":",pos) ;
res = reader.result.substr(pos+1).split("\n") ;
document.getElementById('acc1').value = res[0].trim() ;
// 読み込んだ設定ファイルから 設定1の目標速度 を取得して 要素に代入
pos = reader.result.indexOf("prg_1_spd") ;
pos = reader.result.indexOf(":",pos) ;
res = reader.result.substr(pos+1).split("\n") ;
document.getElementById('spd1').value = res[0].trim() ;
// 読み込んだ設定ファイルから 設定1の時間 を取得して 要素に代入
pos = reader.result.indexOf("prg_1_tim") ;
pos = reader.result.indexOf(":",pos) ;
res = reader.result.substr(pos+1).split("\n") ;
document.getElementById('tim1').value = res[0].trim() ;
// -- 読み込んだ設定ファイルから 設定2のイネーブル を取得して 要素に代入
pos = reader.result.indexOf("prg_2_en") ;
pos = reader.result.indexOf(":",pos) ;
res = reader.result.substr(pos+1).split("\n") ;
if (res[0] == 1) {
document.getElementById('chk2').checked = true ;
disp_ctrl_2(true) ;
} else
document.getElementById('chk2').checked = false ;
// 読み込んだ設定ファイルから 設定2の起点 を取得して 要素に代入
pos = reader.result.indexOf("prg_2_trg") ;
pos = reader.result.indexOf(":",pos) ;
res = reader.result.substr(pos+1).split("\n") ;
document.getElementById('trg2').value = res[0].trim() ;
// 読み込んだ設定ファイルから 設定2の加速度 を取得して 要素に代入
pos = reader.result.indexOf("prg_2_acc") ;
pos = reader.result.indexOf(":",pos) ;
res = reader.result.substr(pos+1).split("\n") ;
document.getElementById('acc2').value = res[0].trim() ;
// 読み込んだ設定ファイルから 設定2の目標速度 を取得して 要素に代入
pos = reader.result.indexOf("prg_2_spd") ;
pos = reader.result.indexOf(":",pos) ;
res = reader.result.substr(pos+1).split("\n") ;
document.getElementById('spd2').value = res[0].trim() ;
// 読み込んだ設定ファイルから 設定2の時間 を取得して 要素に代入
pos = reader.result.indexOf("prg_2_tim") ;
pos = reader.result.indexOf(":",pos) ;
res = reader.result.substr(pos+1).split("\n") ;
document.getElementById('tim2').value = res[0].trim() ;
// -- 読み込んだ設定ファイルから 設定3のイネーブル を取得して 要素に代入
pos = reader.result.indexOf("prg_3_en") ;
pos = reader.result.indexOf(":",pos) ;
res = reader.result.substr(pos+1).split("\n") ;
if (res[0] == 1) {
document.getElementById('chk3').checked = true ;
disp_ctrl_3(true) ;
} else
document.getElementById('chk3').checked = false ;
// 読み込んだ設定ファイルから 設定3の起点 を取得して 要素に代入
pos = reader.result.indexOf("prg_3_trg") ;
pos = reader.result.indexOf(":",pos) ;
res = reader.result.substr(pos+1).split("\n") ;
document.getElementById('trg3').value = res[0].trim() ;
// 読み込んだ設定ファイルから 設定3の加速度 を取得して 要素に代入
pos = reader.result.indexOf("prg_3_acc") ;
pos = reader.result.indexOf(":",pos) ;
res = reader.result.substr(pos+1).split("\n") ;
document.getElementById('acc3').value = res[0].trim() ;
// 読み込んだ設定ファイルから 設定3の目標速度 を取得して 要素に代入
pos = reader.result.indexOf("prg_3_spd") ;
pos = reader.result.indexOf(":",pos) ;
res = reader.result.substr(pos+1).split("\n") ;
document.getElementById('spd3').value = res[0].trim() ;
// 読み込んだ設定ファイルから 設定3の時間 を取得して 要素に代入
pos = reader.result.indexOf("prg_3_tim") ;
pos = reader.result.indexOf(":",pos) ;
res = reader.result.substr(pos+1).split("\n") ;
document.getElementById('tim3').value = res[0].trim() ;
// -- 読み込んだ設定ファイルから 設定4のイネーブル を取得して 要素に代入
pos = reader.result.indexOf("prg_4_en") ;
pos = reader.result.indexOf(":",pos) ;
res = reader.result.substr(pos+1).split("\n") ;
if (res[0] == 1) {
document.getElementById('chk4').checked = true ;
disp_ctrl_4(true) ;
} else
document.getElementById('chk4').checked = false ;
// 読み込んだ設定ファイルから 設定4の起点 を取得して 要素に代入
pos = reader.result.indexOf("prg_4_trg") ;
pos = reader.result.indexOf(":",pos) ;
res = reader.result.substr(pos+1).split("\n") ;
document.getElementById('trg4').value = res[0].trim() ;
// 読み込んだ設定ファイルから 設定4の加速度 を取得して 要素に代入
pos = reader.result.indexOf("prg_4_acc") ;
pos = reader.result.indexOf(":",pos) ;
res = reader.result.substr(pos+1).split("\n") ;
document.getElementById('acc4').value = res[0].trim() ;
// 読み込んだ設定ファイルから 設定4の目標速度 を取得して 要素に代入
pos = reader.result.indexOf("prg_4_spd") ;
pos = reader.result.indexOf(":",pos) ;
res = reader.result.substr(pos+1).split("\n") ;
document.getElementById('spd4').value = res[0].trim() ;
// 読み込んだ設定ファイルから 設定4の時間 を取得して 要素に代入
pos = reader.result.indexOf("prg_4_tim") ;
pos = reader.result.indexOf(":",pos) ;
res = reader.result.substr(pos+1).split("\n") ;
document.getElementById('tim4').value = res[0].trim() ;
// -- 読み込んだ設定ファイルから 設定5のイネーブル を取得して 要素に代入
pos = reader.result.indexOf("prg_5_en") ;
pos = reader.result.indexOf(":",pos) ;
res = reader.result.substr(pos+1).split("\n") ;
if (res[0] == 1) {
document.getElementById('chk5').checked = true ;
disp_ctrl_5(true) ;
} else
document.getElementById('chk5').checked = false ;
// 読み込んだ設定ファイルから 設定5の起点 を取得して 要素に代入
pos = reader.result.indexOf("prg_5_trg") ;
pos = reader.result.indexOf(":",pos) ;
res = reader.result.substr(pos+1).split("\n") ;
document.getElementById('trg5').value = res[0].trim() ;
// 読み込んだ設定ファイルから 設定5の加速度 を取得して 要素に代入
pos = reader.result.indexOf("prg_5_acc") ;
pos = reader.result.indexOf(":",pos) ;
res = reader.result.substr(pos+1).split("\n") ;
document.getElementById('acc5').value = res[0].trim() ;
// 読み込んだ設定ファイルから 設定5の目標速度 を取得して 要素に代入
pos = reader.result.indexOf("prg_5_spd") ;
pos = reader.result.indexOf(":",pos) ;
res = reader.result.substr(pos+1).split("\n") ;
document.getElementById('spd5').value = res[0].trim() ;
// 読み込んだ設定ファイルから 設定5の時間 を取得して 要素に代入
pos = reader.result.indexOf("prg_5_tim") ;
pos = reader.result.indexOf(":",pos) ;
res = reader.result.substr(pos+1).split("\n") ;
document.getElementById('tim5').value = res[0].trim() ;
// XHR を送信。 (ファイルのテキストを ESP32 に送信 )
xhr_ul.send(reader.result);
}
}
window.onload = function() {
if(document.getElementById('loop').checked) {
document.getElementById('loopnum').disabled = false ;
}else{
document.getElementById('loopnum').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>
<output id='output2'> $dir</output>
<output id='output3'> $local</output>
</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; }
#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>
<!DOCTYPE html><html lang='ja'>
<head> <title>Color LED Controller</title></head>
<html> <body>
<output id='output'>$conf_text</output>
</body> </html>
スケッチ
MAIN (pwpk_4.ino : 変数定義, setup, loop 関数)
//+===========================================================================+
// | PWPK Control |
// | |
// | Rev. 0.4 |
//+===========================================================================+
//
#include <WiFi.h> // WiFi 使用の為
#include "FS.h" // SPIFFS 使用の為
#include "SPIFFS.h" // SPIFFS 使用の為
#include <Ticker.h> //
//
#define DEBUG_HTML // Debug用 Serial 表示制御用
//#define DEBUG_HTML2 // Debug用 Serial 表示制御用
//#define DEBUG_WiFi // 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設定 ------------------------------------------------------
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
int set_reboot = 0 ; // 設定時リブート
//
// WiFi 動作用フラグ ----------------------------------------------------------
String foot_msg ="" ; // リブートメッセージ用
bool wifi_restartreq = false ; // WiFiリスタート要求フラグ
bool rebootreq = false ; // リブート要求フラグ
bool wifi_confdl = false ; // wifi 設定ダウンロード
//
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 ; // HTML 選択状態
int html_exec = MAIN ; // 実行中の HTML 選択状態
//
// -----------------------------------------------------------------------------
// | HTML ファイル名等 |
// -----------------------------------------------------------------------------
const char fname_wfCONF[] = "/wifi_conf.html" ; // WiFi 設定用 HTML ファイル名
const char fname_wfRESP[] = "/wifi_resp.html" ; // WiFi XHR レスポンスHTML
const char fname_pwpk[] = "/pwpk.html" ; // PWPK処理 HTML ファイル名
const char fname_mRESP[] = "/pwpk_resp.html" ; // PWPK XHR レスポンスHTML
const char fname_mCONF[] = "/pwpk_conf.html"; // PWPK 設定用 HTML ファイル名
//
String html_wfCONF ; // WiFi設定用 HTML 格納用
String html_wfRESP ; // WiFi XHR 応答用 HTML 格納用
String html_pwpk ; // PWPK処理HTML 格納用
String html_mCONF ; // PWPK設定用 HTML 格納用
String html_mRESP ; // PWPK XHR 応答用 HTML 格納用
//
// -----------------------------------------------------------------------------
// - PWPK処理用 -
// -----------------------------------------------------------------------------
// 運行設定用 変数定義 --------------------------------------------------------
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 ; // 現在時刻
//
bool pwpk_confdl = false ; // pwpk 設定ダウンロード
//
// ( 制御盤/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 MNT_MODE 32 // Degital Output IO32
#define PRG_MODE 33 // Degital Output IO33
//
// ----- 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
pinMode(MNT_MODE,INPUT) ; // Set pin mode
pinMode(PRG_MODE,INPUT) ; // Set pin mode
//
// セットアップ中、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 開始
//
// WiFi設定用 HTML ファイルの読み込み ---------------------------------------
res = rd_SPIFFS(fname_wfCONF,html_wfCONF) ; // html_wfCONF に html を格納
//
// WiFi XHR 応答ファイルの読み込み ------------------------------------------
res = rd_SPIFFS(fname_wfRESP,html_wfRESP) ; // html_wfRESP に html を格納
//
// PWPK HTML ファイルの読み込み ---------------------------------------------
res = rd_SPIFFS(fname_pwpk,html_pwpk) ; // html_pwpk に html を格納
//
// PWPK用設定 HTML ファイルの読み込み--- ------------------------------------
res = rd_SPIFFS(fname_mCONF,html_mCONF) ; // html_mCONF に html を格納
//
// PWPK XHR 応答ファイルの読み込み ------------------------------------------
res = rd_SPIFFS(fname_mRESP,html_mRESP) ; // html_mRESP に html を格納
//
// wifi 初期設定ファイルを読み込み、変数に格納し、wifi,画面モードを決定 -----
res = rd_wificonf() ; //
//
// 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 ; //
bool post_req = false ; // POST 要求フラグ
bool wifi_conful = false ; // WiFi 設定uploadフラグ
bool pwpk_conful = false ; // PWPK 設定uploadフラグ
char buf[257] ; // 受信バッファ
int n=0 ; // ワーク用変数
unsigned long tim = 0 ; // 開始時刻
//
if (ticker_val) { // 定期割込みフラグが true だったら、定期処理を実行。
do_JOB() ; //
} //
//
// HTML クライアント処理 ------------------------------------------------------
if (client) { //
# ifdef DEBUG_HTML //
tim = millis() ; //
Serial.print(" -- new client! ( "); //
Serial.print(tim) ; //
Serial.print(") | ") ; //
# endif //
while (client.connected()) { // client から接続されたとき
if (client.available()) { //
line = client.readStringUntil('\n'); // 1行分取得
# ifdef DEBUG_HTML2 //
Serial.println("") ; //
Serial.println(line) ; //
# endif //
// GET 処理を受信した場合 ---------------------------------------------
if (line.indexOf("GET /?") != -1) { // GET 処理
if (html_mode == WIFI_CONF){ // WiFi 初期設定時
xhr = set_form2wifiparam(line) ; // フォームデータを変数に格納
}else if (html_mode == MAIN_CONF) { // PWPK 初期設定時
xhr = set_mconf2param(line) ; // フォームデータを変数に格納
} else { // PWPK 操作時
xhr = proc_main(line) ; // フォームデータを変数に格納
} //
} //
if (line.indexOf("POST /") != -1) { // POST 要求の場合
post_req = true ; // POST要求フラグをセット
if (line.indexOf("?conful") != -1) { // wifi upload の場合
wifi_conful = true ; // wifi upload フラグセット
} //
if (line.indexOf("?mcnful") != -1) { // upload の場合
pwpk_conful = true ; // pwpk upload フラグセット
} //
} //
// 最終行(空行)を受信した時 -------------------------------------------
if (line.length() == 1 && line[0] == '\r'){ // 最終行判定
// POST 要求があった場合、データを取得/処理する ---------------------
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 (wifi_conful == true) { // wifi 設定upload の場合
#ifdef DEBUG_HTML2 //
Serial.println(" UP LOAD :") ; // 内容をシリアルに表示
Serial.print(line) ; // ( 他の処理は無し)
Serial.println("") ; //
#endif //
wifi_conful = false ; // アップロード処理終了
} else if (pwpk_conful == true) { // pwpk 設定upload の場合
#ifdef DEBUG_HTML2 //
Serial.println(" UP LOAD :") ; // 内容をシリアルに表示
Serial.print(line) ; // ( 他の処理は無し )
Serial.println("") ; //
#endif //
pwpk_conful = false ; // アップロード処理終了
} else if (html_mode == WIFI_CONF){ // WiFi 初期設定時
xhr = set_form2wifiparam(line) ; // フォームデータを変数に格納
}else if (html_mode == MAIN_CONF) { // PWPK 初期設定時
xhr = set_mconf2param(line) ; // フォームデータを変数に格納
} else { // PWPK 操作時
xhr = proc_main(line) ; // フォームデータのメイン処理
} //
} //
// 最終処理 ---------------------------------------------------------
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) { // WiFi 設定中なら
send_wfCONF_html(client) ; // WiFi 設定 HTML 送信
} else { // WiFi 設定中でなければ
send_PWPK_html(client) ; // PWPK処理 HTML 送信
html_exec = MAIN ; //
} // ( その後 リブート)
rebootreq = true ; //
} else { // sta_mode が変わらない場合
if (html_mode == WIFI_CONF) { // WiFi 設定中の時
if (xhr) { // XHR 応答の場合
send_wfRESP_html(client) ; // WiFi XHR応答
} else { // XHR 応答でなければ
send_wfCONF_html(client) ; // WiFi 設定 HTML 送信
} //
} else if (html_mode == MAIN_CONF) { // PWPK 設定中なら
if (xhr) { //
send_pwpkCONF_RESP(client) ; // PWPK 設定 応答 送信
} else { //
send_pwpkCONF_html(client) ; // PWPK 設定 HTML 送信
} //
} else { // PWPK 処理中なら
if (xhr) { // XHR 応答の場合
send_pwpkRESP_html(client) ; // PWPK XHR 応答HTML 送信
} else { // XHR 応答でなければ
send_PWPK_html(client) ; // PWPK処理 HTML 送信
} //
} //
html_exec = html_mode ; //
} //
break ; // ループ終了
} //
//-------------------------------------------------------------------
} //
} //
// 接続が切れた場合 ------------------------------------------------------
delay(5); //
client.stop(); //
# ifdef DEBUG_HTML //
tim = millis() ; //
Serial.print("client disonnected ("); //
Serial.print(tim) ; //
Serial.println(") ----------------------") ;//
# endif //
delay(50); //
} //
//
if (rebootreq) { // リブート要求時
Serial.println("------------------- リブートします------------------- ");
delay(500); //
ESP.restart() ; // リブート
} else { //
} //
//
// --------------------------------------------------------------------------
if (wifi_restartreq) { // WiFI リスタート要求時
Serial.println("------------------- WiFi リスタートします------------- ");
delay(500); //
if (stamode == false) { // APモード時 softAP WiFi 開始
start_AP_server() ; // APモードでサーバー起動
sta_exec = false ; //
} else { // STAモードの場合 Wifi 開始
start_STA_server() ; // APモードでサーバー起動
sta_exec = true ; //
} //
} else { //
} //
wifi_restartreq = false ; //
} //
//
// -----------------------------------------------------------------------------
// WiFi 設定関連 定義 --
// -----------------------------------------------------------------------------
// *****************************************************************************
// * 初期設定ファイル をリードし、グローバル変数に値をセットする *
// *****************************************************************************
int rd_wificonf() { //
String conf ; //
File fp ; // ファイルポインタ
int result = 0 ; // 戻り値
//
if (SPIFFS.exists("/config.txt")) { // 設定ファイル存在確認
// ファイルがあった場合 ----------------------//
result = rd_SPIFFS("/config.txt",conf) ; // confにconfig.txtを格納
} else { //
// ファイルが無かった場合 --------------------//
Serial.println("WiFi設定ファイルなし") ; // 無かったら、APモード
result = -1 ; //
} //
//
// ファイルが読み込めたら、グローバル変数にセットする
if (result == 0) //
# ifdef DEBUG // デバッグ用表示
Serial.println("--- config.txt --- ") ; //
Serial.println(conf ) ; //
# endif //
set_conf2wifiparam(conf) ; // conf の内容を変数に設定
// 初期設定ファイルの状態で 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 = data.toInt() ; //
} //
//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() ; // 数値に変換して代入
pos++ ; // '.' の次から
num=""; //
while(data.charAt(pos) != '.') { // '.' までの文字を取得
num += data.charAt(pos++) ; //
} //
ip[1] = num.toInt() ; // 数値に変換して代入
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() ; // 数値に変換して代入
//
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.println("") ; //
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.println("") ; //
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_form2wifiparam(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 ; //
wifi_restartreq = true ; // WiFiリスタート要求
} 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() ; // 数値に変換して返す
} //
//
// -----------------------------------------------------------------------------
// - グローバル変数の内容をString に出力 -
// -----------------------------------------------------------------------------
void getstr_wfconf(String &conf) { //
char s_work[128] ; //
File fp ; //
//
// String に 変数の内容を書き込む -------------------------------------------
sprintf(s_work,"wifi_ssid : %s\n" //
,wifi_ssid) ; //
conf = String(s_work) ; //
sprintf(s_work,"wifi_pass : %s\n" //
,wifi_pass) ; //
conf += 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]) ; //
conf += 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]) ; //
conf += 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]) ; //
conf += 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]) ; //
conf += String(s_work) ; //
sprintf(s_work,"wifi_mode : %s\n" //
,wifi_mode) ; //
conf += String(s_work) ; //
sprintf(s_work,"set_reboot: %d\n" //
,set_reboot) ; //
//
} //
//
// -----------------------------------------------------------------------------
// - グローバル変数の内容を設定ファイルに書き出す -
// -----------------------------------------------------------------------------
void wr_wificonfig() { //
char s_work[128] ; //
String conf ; //
File fp ; //
//
// String に 変数の内容を書き込む -------------------------------------------
getstr_wfconf(conf) ; //
//
// 設定ファイルに書き込む ----------------------------------------------------
fp = SPIFFS.open("/config.txt",FILE_WRITE) ; // 設定ファイルを開く
if (!fp) { //
Serial.println(" 設定ファイル オープンエラー !!") ; //
} else { //
// 初期設定ファイル書き込み -------------------------------------------------
if(fp.print(conf)) { // ファイルに書き込み
Serial.println("\"config.txt\" 書き込み終了") ; // 終了メッセージ
} else { //
Serial.println("\"config.txt\" 書き込み失敗 !!") ; // 失敗メッセージ
} //
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 送信処理
# ifdef DEBUG_HTML //
Serial.print("Send WiFi Config HTML | ") ; //
# endif //
} //
//
// ----------------------------------------------------------------------------
// - XHR RESPONSE_HTML 送信 -
// ----------------------------------------------------------------------------
void send_wfRESP_html(WiFiClient client) { //
String htmlwk ; // HTML 編集用 ワーク
String conf ; //
//
htmlwk = html_wfRESP ; // htmlwk に HTML をコピー
//
// 変数を値に変換----------------------------//
if (wifi_confdl) { // ダウンロードの場合
getstr_wfconf(conf) ; // 設定を文字列に変換
htmlwk.replace("$conf_text",conf) ; // 変数に 設定文字列をセット
wifi_confdl = false ; //
} else { // アップロードの場合
htmlwk.replace("$conf_text","") ; // 変数に文字列(ダミー)をセット
} //
// HTML を送信 ------------------------------//
send_html(client,htmlwk) ; // HTML 送信処理
# ifdef DEBUG_HTML //
Serial.print("Send WiFi XHR Resp | ") ; //
# endif //
# ifdef DEBUG_WiFi //
Serial.println("") ; //
Serial.println(" response :") ; //
Serial.print(htmlwk) ; //
Serial.println("") ; //
# endif //
//
} //
//
// *****************************************************************************
// * 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() { //
String s_work ; //
File fp ; // ファイルポインタ
int result = 0 ; // 戻り値
//
if (SPIFFS.exists("/mconf.txt")) { // 設定ファイル存在確認
// ファイルがあった場合 --------------------- //
result = rd_SPIFFS("/mconf.txt",s_work) ; // mconf.txt を読み込み
} else { //
// ファイルが無かった場合 ------------------- //
Serial.println("メイン設定ファイルなし") ; // 無かったら、APモード
result = -1 ; //
} //
//
// ファイルが読み込めたら、グローバル変数にセットする
if (result == 0) //
# ifdef DEBUG // デバッグ用表示
Serial.println("--- mconf.txt --- ") ; //
Serial.println(s_work ) ; //
# endif //
set_conf2pwpkparam(s_work) ; // 設定内容を変数に設定
//
return result ; //
} //
//
// ----------------------------------------------------------------------------
// - 設定ファイルの内容を グローバル変数に 設定する -
// ----------------------------------------------------------------------------
void set_conf2pwpkparam(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) ; // ':' までの文字を取得
if (npos == -1) break ; // 見つからなければ終了
s_name = conf.substring(pos,npos) ; //
s_name.trim() ; //
pos = npos+1 ; // ポインタを ':' の次へ
npos = conf.indexOf('\n',pos) ; // '\n' までの文字を取得
if (npos == -1) npos = conf.length() ; //
s_data = conf.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_PWPK_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 送信
# ifdef DEBUG_HTML //
Serial.print("Send Main HTML | ") ; //
# endif //
} //
//
// ----------------------------------------------------------------------------
// - XHR RESPONSE_HTML 送信 -
// ----------------------------------------------------------------------------
void send_pwpkRESP_html(WiFiClient client) { //
String htmlwk ; // HTML 編集用 ワーク
//
htmlwk = html_mRESP ; // htmlwk に HTML をコピー
//
// 変数を値に変換-------------------------------//
htmlwk.replace("$pwr",String(duty)) ; //
htmlwk.replace("$dir",String(dir_bkwd)) ; //
htmlwk.replace("$local",String(local)) ; //
//
send_html(client,htmlwk) ; // HTML 送信処理
# ifdef DEBUG_HTML //
Serial.print("Send Main XHR Resp | ") ; //
# endif //
# ifdef DEBUG_WiFi //
Serial.println("") ; //
Serial.print(" dir :") ; //
Serial.print(dir_bkwd) ; //
Serial.println("|") ; //
Serial.println(" response :") ; //
Serial.print(htmlwk) ; //
Serial.println("") ; //
#endif //
# ifdef DEBUG //
if (local) { //
Serial.print("local") ; //
} else { //
Serial.print("remot") ; //
} //
#endif //
} //
//
// -----------------------------------------------------------------------------
// - メイン設定_HTML 送信 -
// -----------------------------------------------------------------------------
void send_pwpkCONF_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 送信
# ifdef DEBUG_HTML //
Serial.print("Send Main Config HTML | ") ; //
# endif //
} //
//
// ----------------------------------------------------------------------------
// - PWPK XHR RESPONSE_HTML 送信 -
// ----------------------------------------------------------------------------
void send_pwpkCONF_RESP(WiFiClient client) { //
String htmlwk ; // HTML 編集用 ワーク
String conf ; //
//
htmlwk = html_wfRESP ; // htmlwk に HTML をコピー
//
// 変数を値に変換----------------------------//
if (pwpk_confdl) { // ダウンロードの場合
getstr_pwpkconf(conf) ; // 設定を文字列に変換
htmlwk.replace("$conf_text",conf) ; // 変数に 設定文字列をセット
pwpk_confdl = false ; //
} else { // アップロードの場合
htmlwk.replace("$conf_text","") ; // 変数に文字列(ダミー)をセット
} //
// HTML を送信 ------------------------------//
send_html(client,htmlwk) ; // HTML 送信処理
# ifdef DEBUG_HTML //
Serial.print("Send PWPK XHR Resp | ") ; //
# endif //
# ifdef DEBUG_WiFi //
Serial.println("") ; //
Serial.println(" response :") ; //
Serial.print(htmlwk) ; //
Serial.println("") ; //
# endif //
//
} //
//
// ----------------------------------------------------------------------------
// - 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) ; //
} //
//
// *****************************************************************************
// * メイン処理 *
// *****************************************************************************
// ----------------------------------------------------------------------------
// - 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 かどうか
} //
//
// ----------------------------------------------------------------------------
// - PWPK 設定画面の クライアントからのフォームデータ 処理 -
// ----------------------------------------------------------------------------
int set_mconf2param(String &line) { //
String s_work ="" ; //
int xhr = 0 ; //
//
// クライアントからのデータを グローバル変数にセットする。 ------------------
// 設定 の場合 ---------------------------------------------------------------
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_pwpkconf() ; //
} //
Serial.println("set html_mode MAIN") ; //
html_mode = MAIN ; //
} //
// 戻る 場合 -----------------------------------------------------------------
if (line.indexOf("rtn=") != -1) { // 戻るの場合
Serial.println("retuen MAIN mode") ; //
html_mode = MAIN ; //
} //
// ダウンロードの場合 --------------------------------------------------------
if (line.indexOf("mcnfld=") != -1) { //
pwpk_confdl = true ; //
xhr = 1 ; //
} //
//
return (xhr) ; //
} //
//
// -----------------------------------------------------------------------------
// - グローバル変数の内容をString に出力 -
// -----------------------------------------------------------------------------
void getstr_pwpkconf(String &conf) { //
char s_work[1024] ; //
File fp ; //
//
// String に 変数の内容を書き込む -------------------------------------------
sprintf(s_work,"prg_loop : %d\n",prg_tbl[0][0] ) ; //
conf = String(s_work) ; //
sprintf(s_work,"prg_loopnum : %d\n",prg_tbl[0][1] ) ; //
conf += String(s_work) ; //
sprintf(s_work,"prg_1_acc : %d\n",prg_tbl[1][2] ) ; //
conf += String(s_work) ; //
sprintf(s_work,"prg_1_spd : %d\n",prg_tbl[1][3] ) ; //
conf += String(s_work) ; //
sprintf(s_work,"prg_1_tim : %d\n",prg_tbl[1][4] ) ; //
conf += String(s_work) ; //
sprintf(s_work,"prg_2_en : %d\n",prg_tbl[2][0] ) ; //
conf += String(s_work) ; //
sprintf(s_work,"prg_2_trg : %d\n",prg_tbl[2][1] ) ; //
conf += String(s_work) ; //
sprintf(s_work,"prg_2_acc : %d\n",prg_tbl[2][2] ) ; //
conf += String(s_work) ; //
sprintf(s_work,"prg_2_spd : %d\n",prg_tbl[2][3] ) ; //
conf += String(s_work) ; //
sprintf(s_work,"prg_2_tim : %d\n",prg_tbl[2][4] ) ; //
conf += String(s_work) ; //
sprintf(s_work,"prg_3_en : %d\n",prg_tbl[3][0] ) ; //
conf += String(s_work) ; //
sprintf(s_work,"prg_3_trg : %d\n",prg_tbl[3][1] ) ; //
conf += String(s_work) ; //
sprintf(s_work,"prg_3_acc : %d\n",prg_tbl[3][2] ) ; //
conf += String(s_work) ; //
sprintf(s_work,"prg_3_spd : %d\n",prg_tbl[3][3] ) ; //
conf += String(s_work) ; //
sprintf(s_work,"prg_3_tim : %d\n",prg_tbl[3][4] ) ; //
conf += String(s_work) ; //
sprintf(s_work,"prg_4_en : %d\n",prg_tbl[4][0] ) ; //
conf += String(s_work) ; //
sprintf(s_work,"prg_4_trg : %d\n",prg_tbl[4][1] ) ; //
conf += String(s_work) ; //
sprintf(s_work,"prg_4_acc : %d\n",prg_tbl[4][2] ) ; //
conf += String(s_work) ; //
sprintf(s_work,"prg_4_spd : %d\n",prg_tbl[4][3] ) ; //
conf += String(s_work) ; //
sprintf(s_work,"prg_4_tim : %d\n",prg_tbl[4][4] ) ; //
conf += String(s_work) ; //
sprintf(s_work,"prg_5_en : %d\n",prg_tbl[5][0] ) ; //
conf += String(s_work) ; //
sprintf(s_work,"prg_5_trg : %d\n",prg_tbl[5][1] ) ; //
conf += String(s_work) ; //
sprintf(s_work,"prg_5_acc : %d\n",prg_tbl[5][2] ) ; //
conf += String(s_work) ; //
sprintf(s_work,"prg_5_spd : %d\n",prg_tbl[5][3] ) ; //
conf += String(s_work) ; //
sprintf(s_work,"prg_5_tim : %d\n",prg_tbl[5][4] ) ; //
conf += String(s_work) ; //
//
} //
//
// -----------------------------------------------------------------------------
// - グローバル変数の内容を設定ファイルに書き出す -
// -----------------------------------------------------------------------------
void wr_pwpkconf() { //
char s_work[1024] ; //
String conf ; //
File fp ; //
//
// String に 変数の内容を書き込む -------------------------------------------
getstr_pwpkconf(conf) ; //
//
// 設定ファイルに書き込む ----------------------------------------------------
fp = SPIFFS.open("/mconf.txt",FILE_WRITE) ; // 設定ファイルを開く
if (!fp) { //
Serial.println(" 設定ファイル オープンエラー !!") ; //
} else { //
Serial.println("/mconf.txt open complete ") ; //
// 初期設定ファイル書き込み -------------------------------------------------
if(fp.print(conf)) { // ファイルに書き込み
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 ; //
int work = 0 ; //
//
// +--------------------------------------------------------------------------
// | 制御盤情報の取得 |
// +--------------------------------------------------------------------------
//
// loxal の場合 制御盤情報を取得する。----------------------------------------
if (local == true) { //
if (!digitalRead(MNT_MODE)) { // MNT_MODE : Low Active
// 準備/解除スイッチの 状態での処理 --------//
if (!digitalRead(SW_READY)) { // SW_READY 押下時(Low Active)
if (pre_rdy == false ) { // 前回割り込み時、SW が OFF
// 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 ; //
} //
} //
pre_rdy = true ; // 前回割り込み情報を更新
} else { //
pre_rdy = false ; //
} //
} else { //
// 設定モードではない場合 ------------------------------------------------
// 出力用ボリューム値を取得 ----------------------------------------------
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
//wifi_restartreq = true ; // WiFiリスタート要求
} //
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 = 4 ; //
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 にする。
} //
//
以下、メモ
( 詳細は、各スケッチのコメント参照。
主に、パワーパック改2 からの変更箇所 について記す )
<PWPK MAIN HTML (pwpk.html)>
主な修正項目
WiFi ハングアップ対策
XHR 発行を 同時に 1つのみに制限。
ポーリング内容に remote/local, forward, backward を追加。
remote 時、ポーリング (低頻度) 実施
(行# 86,87,93,96,98,99,105)
スライダー操作時のXHR発行時、発行を同時に1つのみにする。(WiFi ハング対策)
(行# 113,114,120,127-143 )
ポーリング時のXHR発行時、発行を同時に1つのみにする。
ポーリング内容に remote/local, forward, backward を追加。
(行# 158,159,160,166,173,179,182-185)
発車/停止 押下時の XHR 発行を 他XHR と同時とならない様にする。
(行# 199,200)
Remote 時、ポーリングを低頻度(1回/1秒) で発行する。
Local 時は 1回/200m秒 にする。
<PWPK設定 HTML (pwpk_conf.html)>
(行# 158-170)
ダウンロード/アップロード用
(行# 241-272)
ダウンロード用 javascript。
(行# 275-458)
アップロード用 javascript。
<PWPK XHR 応答 HTML (pwpk_resp.html)>
(行# 6-7)
forward/backward, remote/local 状態 出力
<WiFi設定 HTML (wifi_conf.html)>
"
テキストファイルをアップロードする"と同じ
<WiFi XHR 応答 HTML (wifi_resp.html)>
"
テキストファイルをアップロードする"と同じ
<MAIN (pwpk_4.ino : 変数定義, setup, loop 関数)>
(行# 34)
WiFi 設定時、リブート有フラグ
(行# 36-40)
WiFi 用 各種フラグ定義
(行# 57-67)
HTML ファイル設定見直し
XHR応答用を WiFI設定 用と pwpk設定 用 に分けた。
(行# 96)
PWPK 用設定ダウンロードフラグ
(行# 144-145)
SW2 用の IOポート定義
(行# 164-165)
IO32,33 の ピンモード設定。 INPUT を設定が必用。
(行# 177-193)
各 HTML ファイルの読み込み
XHR応答用を WiFI設定 用と pwpk設定 用 に分けた。
(行# 241-246)
各変数定義追加
POST要求、アップロード、等の対応用。
(行# 267-276)
GET 要求時の処理
戻り値 (XHR がどうか) を追加。
(行# 277-285)
POST 要求時は フラグセット。
アップロードの場合はアップロードのフラグをセット。
(行# 289-324)
POST 処理。
(行# 290-301)
POST のデータを受信。
(行# 302-324)
POST 処理。
アップロード時、実際の処理は無し。
( HTML 上で 各要素に値をセットするのみの為 )
アップロード以外の時は、GET と同じ処理。
( 処理関数を、 GET/POST の両方に対応させている )
(行# 342-359)
各 HTML選択状態により、HTML を送信。
(行# 369,377)
Client 切断後、5mS 待って client.stop() 。
その後、50mS 待って クライアント処理終了。
ポーリング時の hangup 対策の為。( HTML での XHR 応答後の待ち時間との兼ね合いがある? hangup の頻度が下がるだけかも。)
(行# 388-400)
WiFi リスタート要求時の処理。
<WIFI設定 (wifi_config.ino : 主に WiFI 設定用 の関数)>
"
テキストファイルをアップロードする"とほぼ同じ。
若干の 変数、関数名見直し。
<PWPK処理 (pwpk.ino : 主に PWPK処理、PWPK 設定用 の関数)>
主に、設定のダウンロード、アップロードに対応
(行# 235-236)
ポーリング時の応答に Local/Remote, foward/backward の状態を追加。
(行# 354-384)
アップロード、ダウンロード時の XHR 応答 HTML 送信
(行# 601-606)
フォームデータ処理で ダウンロード時、フラグセット
(行# 610-696)
設定値のファイル書き込みを、 String への返還と設定ファイルの書き込みに分割。
(行# 716-733)
MNT_MODE 時に準備/解除 スイッチで WiFiをリスタートする処理を追加。
( WiFi ハング時に備える )
(行# 976)
LED常時点灯時は、LED_ST1 のみ点滅する様に変更。