HOME >> 鉄道模型工作室 > 新しいモニタ画面を作る その3
Processing を使った運転台コントローラを作るっている。 作成したモニタ画面をから取り込んだデータをもとに、走行させる鉄道模型の車速とPWM制御用のデューティ値を計算し、その機能も確認できた。 今回は、ポイントと信号機の操作機能を検討した。
if (30<mox && mox<90){ //本線転轍機チェック if (ten1 == 0){ ten1=1; myPort.write(201); delay(100); } else { ten1=0; myPort.write(202); delay(100); } }
■ ポイントと信号機の操作情報の送信と受信
操作画面での作動は確認済みなので、今度はその情報の送信と受信機能を設定する。 まず最初に、確認毎の送信情報を設定しよう。
操作画面 | 制御対象 | ArduinoGPIO | 機能 | 送信番号 |
本線転轍機 | ポイント1駆動回路 | GPIO 7 | ONで分岐 | 201 |
OFFで直進 | 202 |
|||
支線転轍機 | ポイント2駆動回路 | GPIO 6 | ONで分岐 | 203 |
OFFで直進 | 204 |
|||
本線信号機 | 本線信号機回路 | GPIO 5 | ONで赤信号 | 212 |
OFF青信号 | 211 |
|||
本線1信号機 | 本線1信号機回路 | GPIO 4 | ONで赤信号 | 214 |
OFF青信号 | 213 |
今回は、シリアル通信を使って送信するので、各機能ごとに送信する番号を設定すれば良いのである。 設定した番号を左に示す。
そして、この送信コマンドは、右のように記述した。 入力チェックの間に、シリアル通信コマンドを単純に挿入した。 これが間違いだったのある・・・・・・・・!
void loop(){ v=Serial.read(); if (v>0){ if (v>200){ switch(v){ case 201: digitalWrite(7,HIGH); break; case 202: digitalWrite(7,LOW); break; ********* 省略 ******** } } analogWrite(10,v); delay(10); } }
これに対応して受信側の Arduino のスケッチを右のように記述した。 場合分けが多いので switch 命令を使用して記述した。
■ テスト走行結果
先回と同様に、卓上レイアウトで走行させたが、結果は使い物にならなかった。 それは、列車が走行中に、ポイントや信号機を操作すると、突然暴走するからである。 すぐさまに原因は、delay(100) のコマンドと判断し、この部分を削除したものの、暴走現象を防止することは出来なかった。
*************************************************
この他にも、信号機の色が反対だったり、点灯しているランプの縁の色と大きさがおかしかったと、不具合があったが、暴走以外の不具合はすぐに手当が出来た。
さて、暴走防止をどうするか考えた時、今まで参考にして来たサンプルプログラムの処理方法を思い出して、その手法を参考にすることにした。 そして、トグル機能を廃止して、ボタン操作を二つのボタンに分離した単機能ボタンにすることにした。
■ スケッチの改良
.
まず、ボタンのトグル機能を中止したので、操作画面とボタン形状を変更した。 そして処理プログラムの修正しました。
int [] com1={0,0,0,0}; int [] com2={0,0,0,0}; void draw(){ ******************* 省略 ********* if (moy>720){
//本線転轍機チェック if (25<mox && mox<53){com1[0]=0;}
if (65<mox && mox<93){com1[0]=1;} //支線転轍機チェック if (110<mox && mox<138){com1[1]=0;}
if (150<mox && mox<178){com1[1]=1;} //本線出発信号機チェック if (390<mox && mox<418){com1[2]=0;}
if (430<mox && mox<458){com1[2]=1;} //本線1出発信号機チェック if (490<mox && mox<518){com1[3]=0;}
if (530<mox && mox<558){com1[3]=1;} } ////アクション if (com1[0]!=con2[0]){ //本線転轍機作動 if (com1[0]==0){ image(tenB, 20, 520); myPort.write(201); com2[0]=com1[0]; } else { image(tenA, 20, 520); myPort.write(202); com2[0]=com1[0]; } } **************** 以下省略 ***********************
レバーの処理部分を参考にして、記憶している前の操作と異なった場合に、の画像を入れ替えると共に、シリアル通信を発信することを目論んだのある。
他のポイントと二つの信号機も同様に記述して、スケッチを走らせてみて、驚いてしまった。
転轍機は表示されず、信号灯も点灯しないのである。
*********************************************************
でも、ボタンをクリックすると一瞬、画像は表示されるもすぐに消えてしまうのである。 残像効果が無いのである。
*********************************************************
最初は何が起こっているのか分からなかったが、やっとその理由を理解した。
この void draw() 命令の最初に、image(panel,0,0) ; として全画面を背景として描画しているので、ひとつ前に描いた画像は背景画によって全て上書されてしまうのである。 このため、転轍機などの画像は、ループの度に画像を新たに描く必要があると言うことを理解した。 従って、左のような記述では、ボタンをクリックしなかった場合、IFコマンドを飛ばしてしまうので、転轍機の画像の tenA と tenB のどちらの画像も表示されないのである。 クリックした瞬間はこのコマンドに引っかかって、どちらかの画像が表示されるものの、次の瞬間は表示が消えてしまう ( 否、背景画にて上書される ) と理解したのである。
if (com1[0]==0){ //本線転轍機作動 image(tenA, 20, 520); if (com1[0]!=com2[0]){ myPort.write(202); com2[0]=com1[0]; } } else if (com1[0]==1){ image(tenB, 20, 520); if (com1[0]!=com2[0]){ myPort.write(201); com2[0]=com1[0]; } }
このため、記述方法を右のように変更した。 画像は、tenA か tenB のどちらかは必ず描かれるようにしたのである。 そして、現在の状態を示す情報に従って画像を表示する一方、以前の状態と異なる場合には、変更すべき信号をシリアル通信にて発信し、古い情報の書き換えも実行するのである。 勿論、ボタンを操作した場合は、そのの状態を示す情報を最初の部分で com1[0] に書き込んでいるのである。
.
この細工は大正解であった。
卓上レイアウトでの走行テストでも正常に機能し、かつ、走行中の動力車はピクリと変動せず、悠々と走行を続けていた。
*******************************************************
完成したスケッチを紹介する。 今回は圧縮ソフトを導入したので、関係ファイル一式をセットにしている。
ファイル一式 ⇒ test_57.zip
■ テスト走行の状態
今回も卓上レイアウトでの操作状態を紹介しよう。
スケッチの修正によって動きはスムースになりましたが、進行方向変更時のピクリ動作がありますね。 ここも、修正する必要がありますが、原因究明が必要です。 また、いろいろな車両でもテスト走行も必要です。
******************************************************************
次回は、サウンド関係と時計表示も手がけたいと考えています。
2021/9/26 作成