HOME >> 鉄道模型実験室 > XBeeを搭載したドクターカー その1
■ はじめに
レイアウトの保守状態が悪化すると動力車の走行はギクシャクしてくるし、室内灯もチラチラしてくる。 この様な場合にはクリーニングカーを走らせてメンテナンスを実施することになるが、自動列車停止システム ATS を組み込んだ我がレイアウトでは、閉塞区間ごとに給電している状態にばらつきがあるように感じられた。 そこで、この給電状態や線路の汚れ状態をチェック出来る線路の保守状態検査方法を考えることにした。
先回は、超小型2線式LEDデジタル電圧計を組み込んだドクターカーを仕立てて実験を行った。 「ドクターカーを作ろう」参照。 そしてなんとか、保守状態の検査法とし有効な手段にすることが出来たと思っているが、走行中のパネルを直接観察するのは難しいのでデジカメで動画として撮影し、その画像をゆっくりと再生しながらチェックすることが出来た。 画面には場所も映っているので、問題個所の特定も可能なのである。
しかし、トンネルの中は撮影できないし、データとして、あるいは電圧降下量のグラウとして表示出来ないので、観察処理が面倒なのだ・・・・・・・・・。 無線通信モジュール XBee を使用してモータ端子電圧のデータをパソコンに飛ばし、パソコンにて処理する方法が考えられる。 このXBee の使用に関しては既に経験済みであるが、線路の位置データをどうやって取得するのかも問題であったが、今回はこのテーマに挑戦することにた。
なお、駅構内の給電についてはポイント部での電圧降下の影響と判断しており、両サイドから給電する方法を実施してこの問題は既に改善済みである。
■ XBeeを搭載した測定車の改良
「動力車のモータ端子電圧と回転数の測定方法を模索」にて、走行中の動力車のモータ端子電圧を測定するため、 XBee を搭載した測定車の検討と制作を報告してきた。 そして、その測定車の改良(第2号機)や有線方式の開発によって、最初の測定車はお蔵入りであった。 今回は、このお蔵入りしていた第1号車を持ち出し、ドクターカーに改良することにした。
ここでは、電圧データだけを無線通信で飛ばせばよいので、 XBee のアナログ入力用回路だけの非常に簡単な回路だけで良いのである。 しかし、充分なスペースがあるので、超小型2線式LEDデジタル電圧計も装着させることにした。 下左の写真は、第1号車に搭載してあった処理回路と、今回新しく作成した処理回路を並べて示す。 下右の写真は、今回作成した基板である。
基板には電池からの電源入力端子と、電圧測定のための入力端子と、XBee基板への出力端子を設けている。
この測定車は、車両としてのフレーム、充電式乾電池2本、XBee子機とその取付け基板、新しく制作した基板、そしてモータ端子電圧を測定するための検出端子から構成されており、これらを測定車に装着した状態を下に示す。 ワイヤアンテナ型のモジュール は DIGI-XB24-Z7WIT-004 XBee ZB を使用している。
完成した測定車の動作チェックのために、試しにレイアウトを走行させてみた。
異常なかったので、次のステップに進めた。
■ 基地局のシールドの作成と無線通信の確認
まず無線通信のための基地局ユニットの工作を実施した。 使用した無線通信モジュールは、以前に使用していたものをそのまま使用する。 「無線通信モジュール XBee を使う」を参照してください。 即ち、ワイヤアンテナ型のモジュール (DIGI-XB24-Z7WIT-004 XBee ZB ) を使用し、ワイヤレスプロトシールド (ARDUINO-A000064 Arduino) をArduino に乗せて、さらに孫亀のように XBee を重ねた。 このシールドの上に、測定開始や停止のボタンを配した手作りのシールドを重ねた。 このシールドはまだ製作途中であるので、完成後に回路などを紹介しよう。
今回は、無線通信の作動チェックのために、次のようなシステムを組んで動作確認を実施した。
● テストシステムの設定
機能テスト用として、簡単なエンドレスレイアウトを床の上に設置して、ドクターカーを走らせる。 そして、無線の基地局をパソコンに接続してデータ通信の状態を検討した。 下左の写真はその全体風景で、右の写真は基地局の状態である。
ドクターカーは、動力車で牽引し、その動力車のモータ端子電圧を測定して無線でデータを送信させるのである。
測定車の電力は乾電池から供給されるが、そのON/OFFはスイッチで実施し、ON時にLEDを点灯させ、その明るさで乾電池の消耗状態をチェックしている。 下右の写真の様に明るく輝いている場合は、電源はOKとのサインとなる。
void setup() { Serial.begin(9600); } void loop() { unsigned long t1; int i; int analogHigh; int analogLow; int analogValue ; if (Serial.available() > 21) { if (Serial.read() == 0x7E) { for (int i = 0; i < 18; i++) { byte discard = Serial.read(); } analogHigh = Serial.read(); analogLow = Serial.read(); analogValue = analogLow + (analogHigh * 256); t1 = millis(); String buf = String(t1)+","+String(analogValue)+",E"; Serial.println(buf); } } }
● テスト1: 無線通信の確認
.
まず最初に、無線通信が機能しているかどうかを確認することにした。 親機と子機の二つの XBee モジュールの設定は従来のままである。
もう一度設定し直しするとなると、操作方法を忘れているので説明書を一から読み直さなければならないのだ。 出来るならこのまま使えないかと期待しながら実験をしていた。
即ち、子機の送信は 50msec 毎に送信してくる設定のままである。
Arduino 側の処理は右に示すような簡単なスケッチを書き込んで実験を実施した。 そして、シリアルモニタで観察されたデータをメモ帳にペーストした状態を左に示す。 最初に時刻を、次に電圧データを送信して来た。 このデータをEXCELに取り込み、時刻データをスタートからの時間に計算し直してグラフ化したものを下に示す。
.
また、送信間隔の時間も計算してデータとして表示させている。
これにより、
無線通信は有効に機能していることが確認できた。
また、送信間隔は、4013 msec ÷60 個 = 66.9 msec であることが分かる。 しかし、子機からの送信は 50msec 毎に送信してくるはずなので、それとの関係がよく理解できないが、兎に角OKとしておこう。
#define START_PIN 15 #define STOP_PIN 16 void setup() { pinMode(START_PIN,INPUT); pinMode(STOP_PIN,INPUT); Serial.begin(9600); } void loop() { unsigned long t1; int i; int analogHigh; int analogLow; int analogValue ; int start; int fin; start=digitalRead(START_PIN); fin = digitalRead(STOP_PIN) ; while (start == HIGH) { // スタートボタンを待つ start = digitalRead(START_PIN) ; } while (fin == HIGH) { // ストップボタンを待つ if (Serial.available() > 21) { if (Serial.read() == 0x7E) { for (int i = 0; i < 18; i++) { byte discard = Serial.read(); } analogHigh = Serial.read(); analogLow = Serial.read(); analogValue = analogLow + (analogHigh * 256); t1 = millis(); String buf = String(t1)+","+String(analogValue)+",E"; Serial.println(buf); fin = digitalRead(STOP_PIN) ; } } } }
● テスト2: スタートボタンとストップボタンに追加
測定の開始と終了のために、専用のボタンを設置して置く。 このボタンはプルアップ回路として、A1とA2のアナログ入力端子をデジタル入力端子として使用し、Arduino からパソコンへの送信の開始と終了を行う。 そのスケッチを右に示す。
また、この時のデータ送信結果をテスト1と同様に、シリアルモニタの値をメモ帳にコピーしてEXCELに取り込み、上記と同じ計算を実施してグラフ化した。
このテストにより、スタートボタンとストップボタンは機能しており、データの送信機能には影響していない事が確認できた。
● テスト3: EXCELにテータを取り込む
シリアルポートに送信されたArduino からのデータを EXCEL に取り込む処理を検討する。 動力特性の場合に利用してきた方法では処理速度が間に合わない恐れがあると考えているのである。 それは、「動力車の発進時や停止時の動き」での経験によるのであるが、送信されたデータ毎にEXCELで計算して表示させる方式では、今回のように素早い送信間隔ではEXCELの処理が追いつかないものと判断している。 先回はその対策として、「EXCEL の通信処理ソフトを変える」で報告した別の処理ソフトを使って成功しているので、今回も同じ方法を使用することにする。
それは、通信処理ソフトとして EasyComn を使用するものである。 以前のシートをコピーしてそのまま使用することにした。
.
シリアル受信ポートにあるデータを取り込み、コンマ文字を頼りに文字を切り出してセルにそれを書き込んで行くのである。
テスト結果を右に示す。 グラフはテスト後に整形しているが、実際はリアルタイムに表示されていた。 スタートボタンに従って Arduino からのデータ送信が始まり、ストップボタンに従って停止したが、その後が大変であった。 EXCEL のマクロ処理が停止しないのである。 途中からデータが来ないと勝手にフリーズしてしまうのである。 ウロウロしていると、EXCELが勝手に再起動して、せっかくのデータが消えてしまうのである。
右のグラウは何とかセーブ出来たものであるが、設定している繰り返し回数が完了する前に強制停止させるエラー処理などの工夫が必要である。 でも、その方法は経験がないので分からないのだ。 ストップ信号を作り、その信号でマクロを止める方法は・・・・・・・・・・・・・・・・? 今後の課題としよう。 当面は規定回数まで走らせて止めることにする。
.
● テスト4: 200個のデータを取り込む
設定している繰返し回数は200回であったので、連続させたデータを右に示す。
しかし、ここで不思議な事に気が付いた。 200回のデータ収集の経過時間が 12,941msec となっていた。 一回当たりの間隔は、グラフに表示しているように 12,941÷200 = 64.7msec となる。 しかし、実感として測定終了までにもっと時間が掛かっているように気がした。
● テスト5:: 500個のデータを取り込む
そこで、設定回数を 500 回に変更して終了までの時間をストップウォッチで計ってみた。
その時に記録されたデータを下に示す。 測定開始から終了までは、1分13秒、即ち83秒経過していた。 データによる経過時間は、32,665 msec 、いや、32,665 刻み である!msec では無いのである。 即ち、刻みの長さは 83sec ÷32,665 = 2.54 msec となる。 これってどういうことなのか? Arduino の内部タイマーは横着で、のろのろ動いている? あるいはタイマーのカウンターが正確に反応していないのか?
何故こうなるのかさっぱり分からないので、t1 = millis(); で読み込まれたデータは、msec とする表示をやめて、単なる 時間 としてグラフには表記することにした。 今回の場合、正確な時間である必要はないのであり、経過時間を表す一つの尺度であれば良いので、このまま使用することにした。
でも、その原因が分からにと、いままでのデータや今後のデータの信頼性が確保できないので不安である。 自分の想定では、シリアル通信との併用がダメなのではないかと考えているのであるが、確証は無い。 Arduino の内部タイマーは使い方に注意が必要との記事をどこかで見たような気がするが、定かではない。
#define START_PIN 15 #define STOP_PIN 16 #define S1_PIN 17 #define S2_PIN 2 #define S3_PIN 3 #define S4_PIN 4 #define S5_PIN 5 #define S6_PIN 6 #define S7_PIN 7 #define e0_PIN 0 void setup() { pinMode(START_PIN,INPUT); pinMode(STOP_PIN,INPUT); pinMode(S1_PIN,INPUT); pinMode(S2_PIN,INPUT); pinMode(S3_PIN,INPUT); pinMode(S4_PIN,INPUT); pinMode(S5_PIN,INPUT); pinMode(S6_PIN,INPUT); pinMode(S7_PIN,INPUT); Serial.begin(9600); } void loop() { unsigned long t1; int i; int analogHigh; int analogLow; int analogValue ; int start; int fin; unsigned long e0; int s1; int s2; int s3; int s4; int s5; int s6; int s7; start=digitalRead(START_PIN); fin = digitalRead(STOP_PIN) ; while (start == HIGH) { // スタートボタンを待つ start = digitalRead(START_PIN) ; } while (fin == HIGH) { // ストップボタンを待つ if (Serial.available() > 21) { if (Serial.read() == 0x7E) { for (int i = 0; i < 18; i++) { byte discard = Serial.read(); } analogHigh = Serial.read(); analogLow = Serial.read(); analogValue = analogLow + (analogHigh * 256); t1 = millis(); s1 = digitalRead(S1_PIN) ; s2 = digitalRead(S2_PIN) ; s3 = digitalRead(S3_PIN) ; s4 = digitalRead(S4_PIN) ; s5 = digitalRead(S5_PIN) ; s6 = digitalRead(S6_PIN) ; s7 = digitalRead(S7_PIN) ; e0 = analogRead(e0_PIN); String buf = String(t1)+","+String(analogValue)+"," +String(s1)+"," +String(s2)+","+String(s3)+"," +String(s4)+","+String(s5)+","+String(s6)+"," +String(s7)+","+String(e0)+",E"; Serial.println(buf); fin = digitalRead(STOP_PIN) ; } } } }
● テスト6: チェックするデータを増やす
タイマーの問題はさておいて、次のステップに進むことにした。
走行位置のマーキングのためにATS のセンサーを使用しようとしているので、そのデータを取り込んだ場合の処理時間の確認をすることにした。 センサーは7ヶ所あるので、それぞれをデジタル入力ポートとして確保し、その状態を送信することにした。 S1 〜 S7 までのポートを当てている。
さらに欲張ってパワーユニットからの供給電圧を測定することも想定して、一つのアナログポートを確保し、そのデータも処理しようと考えている。
この場合のスケッチを右に示す。 そして、送信されたデータをシリアルモニタで確認したものを何時もの方法で下に示す。
追加したポートは、何も接続していないので 1 or 0 をランダムに表示しているが、 問題無く処理されていると判断できる。 そこで、この状態でEXCELに取り込むことにした。
● テスト7: EXCELに取り込む
EXCELのシートは、データ欄を増やして対応した。
それぞれのデータはきれいに処理されておりスケッチも問題ないと判断する。 そして一番注目しているのは測定間隔については、今までと同じレベルであり一安心である。 500個のデータを 32,789 刻みで実施している。
テスト5では 32665/500 = 65.33 刻みで処理し、今回は32789/500 = 65.578 刻みで処理しているので、少し時間が掛かているようであるが問題ないであろう。
この時の測定データのグラフを下に示す。
新しく追加した7個のセンサ信号と電源電圧信号は、時間経過のグラフの上に重ねて表示させて、位置のチェックポイントとして観察できるようにするつもりである。 また、ATS の無いレイアウト、例えばモジュールレイアウトでも活用できるようにするため、手動で操作できるボタンを設け、チェックポイント通過の信号も入力出来るようにしよう。
■ 今後の予定
まず、センサ信号線の追加など作成中のシールドを完成させ、電圧測定量の校正を実施する。 そして、いよいよレイアウトでの試験走行を実施することにしよう。 さらにタイマーの問題も気になるので、思いつく色々な実験もしてみたいし、EXCELの処理ソフトも再検討してみたい。 また、グラフの横軸としてこのような 刻み のデータが本当に要るのかどうかも考えてみたいと思っている。 いろいろテーマが沸きだしてくるのだ。
2016/12/18 作成