Nゲージ用 PWM制御パワーパックの改良/機能追加を行う。
機能:(前回作成分も含む)
1. ボリュームによる 速度制御 (PWM 制御)
2. 前進/後進 の 切り替え
3. LED 常時点灯 (列車が動かない程度で PWM制御)
4. ボタンによる 発車 / 停車 (自動加減速)
5. 上記機能の WEB 操作 ( WEB操作/コントローラ 切り換え )
6.USB-シリアル変換モジュール接続
回路:
PWM パワーパック 回路図2
前回 から 各種 スイッチ、LED を追加。
USB-シリアル変換モジュール接続用のコネクタを追加。
(以前作成した 開発ボード の 変換モジュール(自動書き込み回路付き) を接続することを想定)
< 回路図 での メモ >
12V-3.3V 変換回路で、 出力側 100uF (積層セラミック) は、リップルが大きかった為に実装した。
ポリスイッチ (PSW1 0.65A) は、線路等でのショート対策。
ショットキーダイオード(D7,D8) は、逆起電力対策。
外観:
ケースは CDケースを加工して作成したので、シースルー。
WEB画面:
スケッチ、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% ; } 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='0' 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> <script> var polling = null ; function setval(pwr){ if (polling == null) clearInterval(polling); pollint = null ; var xhr = new XMLHttpRequest(); xhr.open("get", "?slid="+pwr ); xhr.setRequestHeader('Cache-Control', 'no-cache'); xhr.setRequestHeader('If-Modified-Since', 'Thu, 01 Jun 1970 00:00:00 GMT'); xhr.responseType = 'document' ; xhr.onreadystatechange = function() { if( (xhr.readyState == 4) && (xhr.status == 200) ) { document.getElementById('pwr_v').value = parseInt(xhr.response.getElementById("output1").innerHTML) ; document.getElementById('o1').innerHTML = xhr.response.getElementById("output1").innerHTML; } } ntimeout = function(e) { xhr.abort() ; } xhr.send(); } function getval(){ var xhrget = new XMLHttpRequest(); xhrget.open("get", "?pol" ); xhrget.setRequestHeader('Cache-Control', 'no-cache'); xhrget.setRequestHeader('If-Modified-Since', 'Thu, 01 Jun 1970 00:00:00 GMT'); xhrget.responseType = 'document' ; xhrget.onreadystatechange = function() { if( (xhrget.readyState == 4) && (xhrget.status == 200) ) { document.getElementById('o1').innerHTML = xhrget.response.getElementById("output1").innerHTML; document.getElementById('pwr_s').value = parseInt(xhrget.response.getElementById("output1").innerHTML); document.getElementById('pwr_v').value = parseInt(xhrget.response.getElementById("output1").innerHTML); } } ntimeout = function(e) { xhrget.abort() ; } xhrget.send(); } function sw_start() { var xhr_start = new XMLHttpRequest(); xhr_start.open("get", "?start" ); xhr_start.setRequestHeader('Cache-Control', 'no-cache'); xhr_start.setRequestHeader('If-Modified-Since', 'Thu, 01 Jun 1970 00:00:00 GMT'); xhr_start.responseType = 'document' ; xhr_start.onreadystatechange = function() { if( (xhr_start.readyState == 4) && (xhr_start.status == 200) ) { if (polling == null) polling = setInterval(getval,100) ; } } ntimeout = function(e) { xhr_start.abort() ; } xhr_start.send(); } function disp_ctrl( radioid ) { if(radioid == 'remote') { document.getElementById('dir_fw').disabled = false; document.getElementById('dir_bw').disabled = false; document.getElementById('pwr_v').disabled = false; document.getElementById('set').disabled = false; document.getElementById('pwr_s').disabled = false; document.getElementById('ready').disabled = false; document.getElementById('start').disabled = false; if (polling == null) clearInterval(polling); pollint = null ; } else { document.getElementById('dir_fw').disabled = true; document.getElementById('dir_bw').disabled = true; document.getElementById('pwr_v').disabled = true; document.getElementById('set').disabled = true; document.getElementById('pwr_s').disabled = true; document.getElementById('ready').disabled = true; if (polling == null) polling = setInterval(getval,100) ; } } window.onload = function() { if(document.getElementById("rad_rm").checked) { document.getElementById('dir_fw').disabled = false; document.getElementById('dir_bw').disabled = false; document.getElementById('pwr_v').disabled = false; document.getElementById('set').disabled = false; document.getElementById('pwr_s').disabled = false; document.getElementById('ready').disabled = false; document.getElementById('start').disabled = false; if (polling == null) clearInterval(polling); pollint = null ; } else if(document.getElementById("rad_lo").checked) { document.getElementById('dir_fw').disabled = true; document.getElementById('dir_bw').disabled = true; document.getElementById('pwr_v').disabled = true; document.getElementById('set').disabled = true; document.getElementById('pwr_s').disabled = true; document.getElementById('ready').disabled = true; document.getElementById('start').disabled = true; polling = setInterval(getval,100) ; } } </script> </body> </html>
<!DOCTYPE html><html lang='ja'> <head> <title>Color LED Controller</title></head> <body> <output id='output1'> $pwr</output> </body> </html>
/* * WiFi POWER PACK * PWM Control */ #include <WiFi.h> #include "FS.h" #include <SPIFFS.h> #include <Ticker.h> // #define DEBUG_WiFi // #define DEBUG_Hard // LAN (WiFI) 関連定義 ------------------------------------------ const char* ssid = "hogehoge"; const char* password = "hogehogepaswd"; IPAddress ip(192, 168, 1, 32); // for fixed IP Address IPAddress gateway(192,168, 1, 1); // IPAddress subnet(255, 255, 255, 0); // IPAddress DNS(192, 168, 1, 90); // WiFiServer server(80); // グローバル変数定義 --------------------------------------------------------- String html_1 ; // HTML 格納用 String resp_1 ; // XHR 応答用 bool local = true ; // local フラグ bool localen = false ; // 制御盤操作許可 bool dir_bkwd = 0 ; // 進行方向フラグ byte duty = 0 ; // PWM デューティ設定 (0~255) int vol_value = 0 ; // 制御盤ボリューム値 (0~4095) int vol_duty = 0 ; // ボリューム値の DUTY換算値 int loopcnt = 0 ; // 定期割り込み回数カウント用 bool ticker_val = false ; // 定期割り込みフラグ bool pre_rdy = false ; // 準備要求スイッチ状態保持用 bool ready = false ; // 準備要求フラグ ( LED 常時点灯要求) bool pre_strt = false ; // 発車要求スイッチ状態保持用 bool start = false ; // 発車要求フラグ bool stop = false ; // 停車要求フラグ bool running = false ; // 走行中フラグ bool autorun = false ; // 自動走行中フラグ int base = 25 ; // 準備時 (LED点灯時) の duty 値 int target = 145 ; // 目標デューティ int rate = 5 ; // 増減速の割合 (1/10 S 当たりの 増加 duty値) Ticker ticker; // ------ Define for IO Port -------------------------------------------------- #define PWR_VOL A7 // ADC1 A7 (IO35) #define PWR_OUT 2 // Degital Output IO2 #define DIR_OUT 4 // Degital Output IO4 (0:FWD,1:BWD) #define SW_FWD 27 // Degital Input IO27 #define SW_BWD 14 // Degital Input IO14 #define SW_READY 13 // Degital Input IO13 #define SW_START 16 // Degital Input IO16 #define LED_FWD 17 // Degital Output IO17 #define LED_BWD 12 // Degital Output IO12 #define LED_ST1 23 // Degital Output IO23 #define LED_ST2 19 // Degital Output IO19 #define LED_ST3 18 // Degital Output IO18 // ----- Define for LEDC ------------------------------------------------------ #define PWM_FEQ 20000 #define DUTY_bw 8 // ---------------------------------------------------------------------------- void setup() { int lpcnt = 0 ; pinMode(PWR_OUT,OUTPUT) ; // Set pin mode for SPEED control pinMode(DIR_OUT,OUTPUT) ; // Set pin mode for Dirction control pinMode(LED_FWD,OUTPUT) ; // Set pin mode for Forward LED pinMode(LED_BWD,OUTPUT) ; // Set pin mode for Backward LED pinMode(LED_ST1,OUTPUT) ; // Set pin mode for status 1 LED pinMode(LED_ST2,OUTPUT) ; // Set pin mode for status 2 LED pinMode(LED_ST3,OUTPUT) ; // Set pin mode for status 3 LED // セットアップ中、LED を点灯させる digitalWrite(LED_FWD,1) ; digitalWrite(LED_BWD,1) ; digitalWrite(LED_ST1,1) ; digitalWrite(LED_ST2,1) ; digitalWrite(LED_ST3,1) ; Serial.begin(115200); // シリアル開始 SPIFFS.begin(); // SPIFFSを開始 WiFi.config(ip, gateway, subnet, DNS); // Set fixed IP address delay(100); // We start by connecting to a WiFi network ----------------------------- WiFi.begin(ssid, password); Serial.println(); Serial.print("Connecting to "); Serial.println(ssid); // WiFi 5秒間 で接続できなければ、リスタートを行う。 while (WiFi.status() != WL_CONNECTED) { delay(500); lpcnt+= 1 ; if (lpcnt>10) { ESP.restart(); } Serial.print("."); } Serial.println(""); Serial.println("WiFi connected."); Serial.print("IP address: "); Serial.println(WiFi.localIP()); server.begin(); // HTMLファイルの読み込み --------------------------------------- File index1 = SPIFFS.open("/pwpk.html", "r"); if(!index1) Serial.println("file open failed"); else{ html_1 = index1.readString(); //index.htmlをstringで読み込み index1.close(); //ファイルを閉じる } // XHR 応答ファイルの読み込み ------------------------------------ File index2 = SPIFFS.open("/pwpk_resp.html", "r"); if(!index2) Serial.println("file open failed"); else{ resp_1 = index2.readString(); //index.htmlをstringで読み込み index2.close(); //ファイルを閉じる } // for PWM Control --------------------------------------------------- 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) ; // for Ticker ticker.attach_ms(100, execTicker) ; // 割り込み間隔と割り込み処理を設定。 } void loop(){ WiFiClient client = server.available(); // listen for incoming clients int pos ; int val = 0 ; int xhr ; String cmd = "" ; String htmlwk = "" ; String respwk = "" ; if (ticker_val) { // 定期割込みフラグが true だったら、定期処理を実行。 do_JOB() ; } if (client) { // if you get a client, # ifdef DEBUG_WiFi Serial.println("***** Client access start *****"); // print a message out the serial port #endif xhr = 0 ; while (client.connected()) { // loop while the client's connected if (client.available()) { // if there's bytes to read from the client, String line = client.readStringUntil('\n'); // Get Line data until '\n' # ifdef DEBUG_WiFi Serial.println(line); #endif // remote/local のラジオボタンが設定された時の処理 ----------------------------- if ((pos= line.indexOf("GET /?remote")) != -1) { pos += 13 ; while(line.charAt(pos) !=' ') { // remote か local かを取得する cmd += line.charAt(pos++) ; } if (cmd=="local") { // local の場合 local = true ; // local フラグを ON } else { // remote の場合 local = false ; // local フラグを OFF localen = false ; // locavollen フラグを OFF } } // 進行方向が操作された場合の処理 -------------------------------------- if ((pos= line.indexOf("GET /?dir")) != -1) { if (!local) { if (!running) { pos += 10 ; while(line.charAt(pos) !=' ') { cmd += line.charAt(pos++) ; } if (cmd=="foward") { dir_bkwd = false ; } else { dir_bkwd = true ; } digitalWrite(LED_FWD,!dir_bkwd) ; digitalWrite(LED_BWD,dir_bkwd) ; digitalWrite(DIR_OUT,dir_bkwd) ; } } } // 出力値がセットされた場合の処理 ----------------------------------------- if ((pos= line.indexOf("GET /?pwr_v")) != -1) { if (!local) { pos += 12 ; while((line.charAt(pos) >='0') & (line.charAt(pos) <='9')) { cmd += line.charAt(pos++) ; } val = cmd.toInt() ; if (val>256) val = 255 ; vol_duty = val ; } } // スライダーが操作された場合の処理 --------------------------------------------- if ((pos= line.indexOf("GET /?slid")) != -1) { if (!local) { pos += 11 ; while((line.charAt(pos) >='0') & (line.charAt(pos) <='9')) { cmd += line.charAt(pos++) ; } val = cmd.toInt() ; if (val>256) val = 255 ; vol_duty = val ; } xhr=1; } // 準備/解除がセットされた場合の処理 ----------------------------------------------- if ((pos= line.indexOf("GET /?ready")) != -1) { if (!local) { if (ready == false) { ready = true ; digitalWrite(LED_ST1 ,1) ; }else{ ready = false ; digitalWrite(LED_ST1 ,0) ; } } } // 発車/停車がセットされた場合の処理 ----------------------------------------------- if ((pos= line.indexOf("GET /?start")) != -1) { if (!local) { if (running == false) { start = true ; stop = false ; digitalWrite(LED_ST2 ,1) ; } else { start = false ; stop = true ; digitalWrite(LED_ST2 ,0) ; } } xhr=1; } // ポーリング要求があった場合の処理 --------------------------------------------- if ((pos= line.indexOf("GET /?pol")) != -1) { xhr=1; // XHR 応答フラグ を ON } // HTTP リクエストの終わりを受信した場合の処理 ------------------------------- if (line.length() == 1 && line[0] == '\r'){ // end of HTTP request // HTML 送信の場合 --------------------------------------------------------- if (xhr == 0) { htmlwk = html_1 ; htmlwk.replace("$pwr",String(vol_duty)) ; # ifdef DEBUG_WiFi Serial.print("radio_local = "); Serial.println(local); Serial.print("pwr = "); Serial.println(vol_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","") ; } send_html(client,htmlwk) ; // send response to client // XHR 応答を送信する場合 -------------------------------------------------------- } else { respwk = resp_1 ; respwk.replace("$pwr",String(vol_duty)) ; send_html(client,respwk) ; // send response to client # ifdef DEBUG_WiFi Serial.print("xhr value :"); Serial.println(vol_duty); #endif } break; // break while loop } } } delay(1); // give the web browser time to receive the data // close the connection: client.stop(); // # ifdef DEBUG_WiFi Serial.println("Client Disconnected."); 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) ; # ifdef DEBUG_WiFi Serial.println( " --- send html --- "); #endif } // 定期割込み処理 --------------------------------------------------------- void execTicker() { ticker_val = true ; // フラグを True にするだけ。 } // 定期処理 (定期割込みフラグが立っていた時の処理) ------------------------ void do_JOB() { // loxal の場合 制御盤情報を取得し、制御を行う。 ------------------------ if (local == true) { // 出力用ボリューム値を取得 ------------------------------------------- vol_value = analogRead(PWR_VOL); // 制御盤の操作が許可されていた場合 ----------------------------------- if (localen == true) { // 進行方向スイッチのチェック --------------------------------------- if (!running) { // 走行中は切り替え不可 if (!digitalRead(SW_FWD)) { // SW_FWD : Low Active dir_bkwd = 0 ; } if (!digitalRead(SW_BWD)) { // SW_BWD : Low Activ dir_bkwd = 1 ; } 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出力を元に戻す。 } // 準備/解除スイッチのチェック --------------------------------------- if (!digitalRead(SW_READY)) { // SW_READY が押された時 (Low Active) if (pre_rdy == false ) { // 前回割り込み時、SW が OFF if (ready == false) { // かつ LED常時点灯になっていない場合 ready = true ; // ON にする digitalWrite(LED_ST1 ,1) ; } else { // LED常時点灯中の場合 ready = false ; // OFF にする digitalWrite(LED_ST1 ,0) ; } } pre_rdy = true ; // 前回割り込み情報を更新 } else { pre_rdy = false ; } // 発車/停車が押下された場合の処理 ----------------------------------------------- if (!digitalRead(SW_START)) { // SW_START が押された時 ( Low Active) if (pre_strt == false) { // 前回割込み時、SW が OFF if (running == false) { // かつ、走行中でない場合 start = true ; // 発車要求フラグを ON stop = false ; // digitalWrite(LED_ST2 ,1) ; // } else { // 走行中の場合 start = false ; // 停車要求フラグを ON stop = true ; // digitalWrite(LED_ST2 ,0) ; } } pre_strt = true ; // 前回割り込み情報を更新 } else { pre_strt = false ; } // PWM の デューティを設定 ---------------------------------------------- if (autorun == false) // 自動走行でない場合 vol_duty = ((vol_value*255)/4095) ; // ボリュームの値で 出力制御 // Local だが、制御盤の操作が許可されていない場合 -------------------------- } else { vol_duty = 0 ; // 出力 OFF // ボリューム が 0 の場合 if (vol_value == 0) // ボリュームが 0 に戻されたら localen = true ; // 制御盤の操作を許可する。 } // 割り込み処理の実行回数をカウント --------------------------------------- loopcnt++ ; // 実行回数が 10 回目の場合 (1秒毎) --------------------------------------- // remote の場合 ------------------------ } else { // 準備/解除スイッチのチェック 押されたら Local にする -------------------- if (!digitalRead(SW_READY)) { // SW_START が押された時 ( Low Active) if (pre_rdy == false) { // 前回割込み時、SW が OFF local = true ; // Local(制御盤操作可能) にする localen = false ; // 制御盤操作許可は OFF } pre_rdy = true ; // 前回割り込み情報を更新 } else { pre_rdy = false ; } } // 発車 処理 (自動 加減速) REMOTE/LOCAL 共通処理 if (start == true) { // 発車要求フラグ が 真の場合 autorun = true ; // if (vol_duty < target) // 目標デューティまで、 vol_duty = vol_duty + rate ; // 出力を RATE 分加算 // 加速終了 (定常走行) else { // 目標デューティに達したら LED_ST3 点灯 start = false ; digitalWrite(LED_ST3 ,1) ; } } // 停車 処理 (自動 加減速) if (stop == true) { // 停車要求フラグが真の場合 autorun = true ; // if (vol_duty > 0){ // 停車するまで vol_duty = vol_duty - rate ; // RATE 分を減算 if (vol_duty < 0) vol_duty = 0 ; } else { stop = false ; // 停車したら、 autorun = false; // 自動走行中フラグを OFF localen = false; // 制御盤操作許可を OFF (ボリュームが 0 でない場合の為) digitalWrite(LED_ST3 ,0) ; // LED_ST3 消灯 } } // 走行中フラグを更新 if (vol_duty > 0) running = true ; else running = false ; // 常時点灯処理 if (ready == true) // 常時点灯時、BASE を加算 duty = base + ((255-base)*vol_duty)/255 ; else duty = vol_duty ; // デバッグ用出力 -------------------------------------- if (loopcnt ==1) { # ifdef DEBUG_Hard Serial.println("") ; Serial.print( "PWR_VOL :") ; Serial.println(vol_value) ; Serial.print( "vol_duty :") ; Serial.println(vol_duty) ; 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) ; #endif // 実行回数をリセット loopcnt = 0; } ledcWrite(0, duty) ; // PWM デューティを設定 ticker_val = false ; // 処理を実行したら、フラグを false にする。 }
以下、メモ
<HTML 本体>
- 制御盤(local) と 遠隔(remote) の ラジオスイッチ:
制御盤選択時は、WEBからのボタン,スライダー等は java script で グレーアウト - スライダー:
スライダーは、XHR で 逐次値を送信し、レスポンスされた値を 現在出力、出力設定の値に表示。 - 発車/停車 ボタン:
type を button として XHR で 押されたことを通知。
レスポンスがあったら、ポーリングを開始して 現在出力、出力設定の値、スライダーの値に表示。(ポーリングについては、以下に記述 ) - ポーリング:
制御盤(Local) 選択時、発車/停車ボタン押下時に開始。
100mS 毎に XHR で出力値を要求。(100mS毎は多いか?)
応答値を 現在出力、出力設定の値、スライダーの値に表示。
スライダー等、値に表示する場合、応答値(文字列) を 数値に変換する必要がある。以下の様に、parseInt() を使用する。
document.getElementById('pwr_s').value = parseInt(xhrget.response.getElementById("output1").innerHTML); - 各要素の初期値は、java script の window.onload で設定。
- 変数( $*** ) は、スケッチで 値(数値や文字列) に変換する。
- 応答の値の変数($pwr) は スケッチで 値 に変換する。
- スケッチ内にコメントを記載。以下、主な仕様, 挙動等。
- クライアント処理内では、フラグの設定等のみで、実際の操作は定期処理内で実施。
- 定期処理(1回/100mS) で 制御盤のスイッチ等の状態リード, LED 点灯, 出力制御等を実行。
- 遠隔(remote) 時、準備スイッチ押下で 制御盤(Local) に遷移させる。
この為、WEB上の表示は 遠隔(remote)のまま(グレーアウトしていない)状態でも Local となる場合がある為、クライアントの処理内でも local でないことを条件に追加。 - 進行方向の変更は、走行中でない時のみに限定。
- 準備/解除 スイッチ で 列車が動かない程度に出力。(LED の常時点灯, トグル動作)
- 発車/停車 スイッチ は、停車時に押下で 自動で加速して定常走行となる。
- 定常走行 時に押下で 自動で減速して停車する。
- 発車/停車時の 加速度(rate), 定常時出力(target) は 変数定義の初期値で設定。
- ボリューム設定で走行中に 発車/停車 スイッチを押下した場合は 自動で停車。ボリュームを '0' にするまで、操作不可。
0 件のコメント:
コメントを投稿