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 件のコメント:
コメントを投稿