HOME >> 鉄道模型実験室 > 登山鉄道レイアウトとモニタ式操作盤 ロジックミスの修正

鉄道模型実験室 No.226  登山鉄道レイアウトとモニタ式操作盤 ロジックミスの修正    

 登山鉄道レイアウトの操作盤について、以前検討したモニタ方式の操作画面から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);    //速度指示
 }

 

■ さて対応策は?

 このロジックの間違いをどのように修正しようか迷いました。

  1. 新たな変数を設けて、トグルスイッチの様な動きをさせる。 でも作動させるタイミングがESP32 とMEGA とが合わない恐れがある。 
  2. ESP32で速度変数の増減処理を実施し、その数値をシリアル通信によってMEGAに送信する。
  3. ESP32にはD/A変換可能なポートがあるので、一旦アナログに変換してMEGAに渡す。 精度は問わない。

 検討した結果、第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