HOME >> 鉄道模型実験室 > 登山鉄道レイアウトとモニタ式操作盤 ロジックミスの修正
登山鉄道レイアウトの操作盤について、以前検討したモニタ方式の操作画面からWiFiを使った通信によって操作できないか検討をしている。 検討した通信モジュールESP32を登山鉄道レイアウトにセットした。 でも、走行テストを実施すると、ロジックミスを犯していたことが判明した。
■ IPアドレスの固定化
ArduinoMEGA のスケッチを書込み、テスト運転を実施した。 でも、すんなりとは機能しなった。 タブレットのモニタ操作画面からアクセスするも、Webサーバからの反応がなかったのである。
Wi-Fiルータの管理画面にアクセスすると、サーバのIPアドレスが変わっていたのである。 このルータはDHCPサーバー機能があり、アクセスしてきたクライアントに自動的にIPアドレスを振り分けて設定する機能が有効となっている。 そして、その範囲も設定されている。 一旦接続を切るとこのアドレスが変更される恐れがあり、そのたびにアドレス指定を変更する必要が発生するのだ。
これでは面倒なので、Webサーバのアドレスを固定させることにした。 その方法は、
const IPAddress ip(192,xxx,xxx,yyy);
const IPAddress gateway(192,xxx,xxx,xxx);
const IPAddress subnet(255,255,255,0);
と指定しておき、
WiFi.config(ip,gateway,subnet);
delay(100);
を実行させておくだけでよいのである。 アドレスは。ローカルエリア内で使用できるローカルIPアドレスなので、最後のyyyの部分だけであり、ルータの使用する範囲外の数値を指定した 。 設定後ルータの管理画面でも確認したが、指定通りの番号が設定されていた。
■ ロジックミスの発見
これで万全とばかりに、テスト運転を実施した。
TOMIXのサン・モリッツ号とKATOのアレグラ号を走らせた。 特性が異なるアレグラ号はモタモタとした走りであり、いくらスピードアップのボタンを押しても、それ以上は早くならなかった。 他の機能は良好だったので、速度制限の値が小さかったのだと考えて、その値を 100 から 200 に変更した。
ところが、その結果はサン・モリッツ号の暴走として現れた。 速度調整については、最初から少しおかしいとは気になっていたが、これは絶対にどこかがおかしいと判断した。 アップとダウンの機能は働くものの、ストップするか、あるいは暴走するかのどちらかの状態であったのだ。
あらためて、スケッチの内容をチェックして、はじめてロジックの間違いに気が付いた・・・・・・・・・!。
*******************************************
ブラウザからMEGAまでの情報の伝達具合を見てみましょう。
(1) ブラウザの記述:
<a href="http://192.xxx.xxx.yyy/?speed=up" target="message"><img src="up.jpg" width="62" height="28"></a>
スピードアップのボタンを押すと、192.xxx.xxx.yyy アドレスのサーバに speed=up という情報を送信します。
(2) ESP32Webサーバの記述:
if (server.hasArg("speed")){
if (server.arg("speed").equals("up")){
digitalWrite(SPD, HIGH);
server.send(200, "text/html", "Speed UP !");
} else if (server.arg("speed").equals("down")){
digitalWrite(SPD, LOW);
server.send(200, "text/html", "Speed DOWN !");
}
}
すると、サーバはその情報をもとに、SPD というポートをHIGHにします。 このポートはMEGAの入力ポート接続しているので、その入力ポートもHIGH にします。
(3) ArduinoMEGA の記述:
if (spd == HIGH){ duty = duty + 5 ; if (duty >= 100 ){ duty = 100; } } else if (spd == LOW){ duty = duty - 5 ; if (duty <= 0){ duty = 0; } }
入力ポートがHIGH なので、duty の値を +5 します。 この記述はメインループ内に記述しているので、HIGH の状態ではループのたびに増加して行き、上限になったら初めて頭打ちとなります。
*************************************
ロジックの間違いは、ボタンのワンクリックで、連絡ポートの値をHIGH にしてしまう点です。 ワンクリックでの増減は一回だけ実施すれば良いのですが、上記のロジックでは、連続して実施してしまい、上限値か、あるいは下限値まで進めてしまいます。 これでは、狙いとするロジックになっていないのです。
****** ESP32Webサーバの記述変更 *******
if (server.hasArg("speed")){ if (server.arg("speed").equals("up")){ spd = spd + 10; //速度の計算 if (spd >= 255 ){ spd = 255; } dacWrite(SPD, spd); server.send(200, "text/html", "Speed UP !"); } else if (server.arg("speed").equals("down")){ spd = spd - 10; //速度の計算 if (spd <= 0 ){ spd = 0 ; } dacWrite(SPD, spd); server.send(200, "text/html", "Speed DOWN !"); } }
****** ArduinoMEGA の記述変更 *******
if (aut==LOW){ //手動運転モード if (mnt == LOW){ //パネル操作 pts1 = digitalRead(PTS1); //スイッチ類のチェック pts2 = digitalRead(PTS2); dswr = digitalRead(DSWR); dswl = digitalRead(DSWL); vol1 = analogRead(VOL1); duty=(vol1-500)/2; } else { //モニタ操作 pts1 = digitalRead(4); //スイッチ類のチェック pts2 = digitalRead(3); dswr = digitalRead(9); dswl = digitalRead(8); spd = analogRead(A4); duty = spd/2.65; } ledhyoji(); //パネル表示 if (pts1==HIGH){ //ポイント1操作 p1han_i(); delay(100); } else { p1tei_i(); delay(100); ******** 途中を省略 ********** } analogWrite(MPWM,duty); //速度指示 }
■ さて対応策は?
このロジックの間違いをどのように修正しようか迷いました。
検討した結果、第3の方法を選択しました。 ワンクリックの情報が生きているESP32にて、速度情報の増減処理を実施し、その後はアナログ情報として処理しようとするものですが、こうすると手直し部分が少ないと判断したからです。
まず、、ESP32 の出力ポートGPIO 26 をデジタル出力からアナログ出力に変更します。 即ち、digitalWrite( ) を dacWrite( ) に変えて対応します。 そして、アナログ値として出力された電圧を、MEGA側ではアナログ入力として受取り、A/D変換して情報を受け取ります。 その後、duty 値として計算し、供給電圧を制御するモータドライバのPWM制御を実施します。
このため、ハード回路は、MEGA 側の接続ポートをデジタル用の GPIO 10 からアナログ用のGPIO A4 に繋ぎ変えました。 上の写真に示す。
ハードでの変更はこの配線変更だけで対応出来ました。
************************************
一方、ソフトとしての対応は、速度情報の増減処理をMEGA側からESP32 側に変更し、その間の情報をデジタルからアナログに変更しました。 変更部分については右に示します。
ESP32では、ボタンの一回のクリックで、±10 の増減として速度変数 spd を変化させます。 変数の最少値は0で、最大値は255です。 これをA/D 変換して出力します。 これをArduinoMEGA 側でA/D変換して受け取り、PWMのduty 値として出力とします。 この時の計算を次の様に実施しました。
電圧の変換については、ESP32のD/A変換は、0〜255の指定で、0volt 〜3.3volt の電圧出力となります。 これをArduinoMEGA 側でA/D変換して受け取ると、0 〜 5 ボルトの入力電圧を 0 〜 1023 の数値に変換します。 さらに、PWMとして出力する時のduty値は、0〜255の値が指定出来ます。
即ち、最大値として計算していくと、 1023*3.3/5.0/255=2.65 となりますので、A/D変換された値を 1/2.65 して duty値としました。 パネル操作とモニタ操作においては、duty値を指定した analogWrite()を同じように記述しますので、最後の部分に記述を持ってきています。
**********************************************
修正結果については、次回に報告しましょう。
2022/11/8