HOME >> 鉄道模型工作室 >  レイアウトに速度計を設置する

レイアウトに速度計を設置する

■ はじめに

 Arduino を少し使いこなせるようになったので、次のテーマとしてレイアウト設置に用の速度計に挑戦した。 相変わらずの失敗例を記録して置くことにします。 この装置は、Arduino の他に、レイアウトを走行中の模型車両の速度を測る速度センサーと、結果を表示するディスプレイが必要となります。 速度を検出するセンサーは、今までの経験を生かせば出来そうですが、今回はディスプレイの表示を勉強する必要がありました。

 

■ 工作(1): サインスマートのLCDと速度計を使用

 速度を検出するセンサーとして、精度はあまり必要がないので、ストック倉庫行きとなっていたシャープの距離測定センサーを使ってみることにした。 ディスプレイは、Amazon で偶然見つけておいたサインスマートの TW-1602 を使用することにする。 その写真を下左に示す。 また、回路図を下右に示す。

 回路は簡単だし、ロジックも難しくは無いだろうと気楽に始めたが、最初からつまずいた。 ディスプレイがうまく表示してくれないのである。 まず、I2C とは何ぞやから調べ無ければならなかった。 注文時には、部品に付属してくる説明書を見れば使えるだろうと気楽に考えていたが、届いた製品を見て慌ててしまった。 説明書などは付いていなかったのである。 「バルク品」なる物に手を出してしまったのである。

 案内のサイトで紹介されているホームページに従って専用のライブラリを使用してみるも、コンパイルエラーが解消出来なかった。 同じような初心者の苦労話もあったが自分には解決できなかった。 また、 I2Cの通信手段を使用したよく似た製品の使用例があったので、これを真似してスケッチを描いてみるも、コンパイルエラーは解消できたものの、ディスプレイはダンマリであった。

 この配線が少ない I2C の通信手段を使用した方式を結局は諦めることにした。 高い勉強代となったしまった。

 

■ 工作(2): 秋月の超小型LCDと速度計を使用

 ディスプレイについては、Arduino の紹介本などで説明されているキャラクターLCDコントロールチップHD44780 のを使用しているキャラクターLCDに変更することにした。紹介本の内容に従って記述していけば、問題無く表示されるであろうと言う安心感があるからである。

 使用したディスプレイは、秋月の超小型LCDキャラクタディスプレイモジュール SD1602HULB(-XA-G-G) である。 回路図を下右に、ブレッドボード上で配線した状態を下左に示す。

   .

 

 例題に従ってスケッチを記述していくと、今度は簡単に表示してくれた。

 最初に、

   #include <LiquidCrystal.h>

   LiquidCrystal lcd(8, 9, 10, 11, 12, 13);

 と記述しておき、

   sprintf(out_str, "KUDARI   0  Km/h");
   lcd.setCursor (0, 0) ;
   lcd.print(out_str);

 とすれば、表示してくれるので、簡単!簡単! 初心者にはこうでなくちゃ!  これに気を良くして、距離センサーを含めて、測定部分も記述し、何とかスピードメータらしく表示させる事が出来た。

 ロジックとしては、

のような考えで記述した。 そして、動力特性を測定している測定台を利用して、実際に走行させて速度計を動かして見た。 

 ここで、この距離センサーの問題点がやはり浮かび上がってしまった。 距離の測定値が不安定なのである。 電車が止まっていても 50Km/h などと表示してしまうのである。 距離センサーであれば、レイアウトのカーブ部分に簡単に設置できるし、また、持ち運びも容易であるのだが、測定値が信頼出来ないのであれば諦めるしか無い。 この赤外線式の距離センサーが駄目なら、超音波式はどうかと考えたが、こちらは、線路に反射する雑音が邪魔して測定出来ない事を経験しているので、こちらも無理であると判断した。

 このため、車両の通過センサーを使用して速度を検出する方式にするしかないと判断するも、どの様なセンサーを使用するかを悩むこととなった。

 

■ 工作(2): 秋月の超小型LCDと光ゲートを使用

 やはり実績のあるLEDとフォトICダイオードを使用する方法で速度を測ることにした。 線路の上下方向に設置すると複線でも独立して測定出来るが、線路の上方に細工する必要があるので、邪魔になってしまう。 そこで、横方向に複線を跨いで設置すれば、測定ゲートは2ヶ所で済むので、この簡便な方式で実施する。

 この時の回路図を下に示す。 LED は、最近手に入れた超高輝度3mm電球色LED OSM54K3131A (14,400mcd/20mA) を使用、 フォトICダイオードは浜松フトニクス製の S9648-100 を使った。  Arduino のピン配列は、Arduino用ユニバーサル基板を使用した時の状態を想定して決めている。

 光ゲートは、レイアウト上に直接設置するので、設置場所のプレートを取り外して作業部屋(クーラーが効いている部屋です)に持ち込んで工作した。 下左の写真。 この部分は少し坂になっているが、直線部分であり、奥側が土手になっているので光ゲートを設置するには格好の場所である。

 まず、光を通す部分は、外径がφ4mm、内径がφ2mmのアルミパイプを使用する。 その設置位置は線路上の15mmの位置と決める。 複線線路の上に厚さ12.5mm の板を置いて、その上にアルミパイプを置き、線路と平行を保ちながら、土手の部分のスタイロ・フォームを貫通させた。 下右の写真。 

 そして、パイプを適切な長さに切断して、奥側にφ3mm のLEDをはめ込み、配線を実施後に粘土で周りの空間を埋めた。 固定と光漏れ対策である。 受光側のフォトICダイオードは外径がφ5mm なので、それに合うプラパイプを切断し、内側に黒色の折り紙を巻いてはめこんだ。 余分な光が入り込むのを防ぐ為である。 フォトICは1mm厚さのプラ板に固定し、プレートの枠板に固定した。 工作途中の撮影を忘れてしまったが、完成した光ゲートの状態を下に示す。 ゲート間の距離は200mmに取ってある。

 センサー部分が出来たので、点灯と受光による抵抗変化をテスターで確認して光ゲートの作成を完了する。 次に回路部分をブレッドボード上に構成して、プログラムを作成して、その作動を確認することにした。

 ********  Speed Meter G2 *********

 #include <LiquidCrystal.h>
 #define SLIT1_PIN 10
 #define SLIT2_PIN 11

 LiquidCrystal lcd(7, 6, 5, 4, 3, 2);

 void setup()
 {
   lcd.begin(16, 2);
   char out_str[16];
   sprintf(out_str, "KUDARI");
   lcd.setCursor (0, 0) ;
   lcd.print(out_str);
   sprintf(out_str, "NOBORI");
   lcd.setCursor (0, 1) ;
   lcd.print(out_str);
   pinMode(SLIT1_PIN,INPUT);
   pinMode(SLIT2_PIN,INPUT);
 }

 void loop()
 {
   int slit1;
   int slit2;
   unsigned long t1;
   unsigned long t2;
   unsigned long tt;
   long V;
   char out_str1[16];
   int i;

   slit1 = digitalRead(SLIT1_PIN) ;
   slit2 = digitalRead(SLIT2_PIN) ;

  //下り線のチェック
   if (slit1 == LOW) {
     t1 = millis();
     while (slit2 == HIGH) {
         slit2 = digitalRead(SLIT2_PIN) ;
     }
     t2 = millis();
     tt = t2 - t1 ;
     V =108000 / tt ;
     sprintf(out_str1, "KUDARI %4d Km/h" , V);
     lcd.setCursor (0, 0) ;
     lcd.print(out_str1);

     //通過中の車両をチェック
     for (i=0; i<20; i++) {
       slit2 = digitalRead(SLIT2_PIN) ;
       if  (slit2 == LOW) {
         i = 0 ;
       }
       delay (50);
     }
   }

  //上り線のチェック
  if (slit2 == LOW) {
     t1 = millis();
     while (slit1 == HIGH) {
         slit1 = digitalRead(SLIT1_PIN) ;
     }
     t2 = millis();
     tt = t2 - t1;
     V = 108000 / tt ;
     sprintf(out_str1, "NOBORI %4d Km/h" , V);
     lcd.setCursor (0, 1) ;
     lcd.print(out_str1);

     //通過中の車両をチェック
     for (i=0; i<20; i++) {
      slit1 = digitalRead(SLIT2_PIN) ;
       if  (slit1 == LOW) {
         i = 0 ;
       }
       delay (50);
     }
   }
 }

 完成したスケッチを右に示す。 もっとスマートの記述があると思うが、何とか作動しているのでこれでOKとしている。

 その内容を記録して置く。

 C言語を勉強したことのない初心者の小生が、ここで失敗した例を紹介しておこう。

 時刻計測はミリ秒で計測されているのをうっかり忘れて、V = 108 / tt として計算し、速度ゼロとしか表示されなかったので、四苦八苦したこと。

 やっとミリ秒を秒に換算しなければならない事に気が付いて、今度は、tt = (t2 - t1)/1000 としてしまったのであるが、これも駄目なことは、賢明な諸君はすぐに気が付くと思います。

 tt は、unsigned long tt; として符号なしlong整数型と宣言しているので、整数なのです。 従って、0、1、2、・・・・・・・と言った数値なので、この場合の速度表示は、-1、108、216 としか表示しないのです。 これに気が付くまで、1時間ほどウロウロしていました。 このため、1/1000 の計算は、V を計算するときに実施しているのです。 ここで計算された数値は、もう整数で大丈夫なのです。

 データの型に配慮することの重要性を勉強しました。

 また、表示するデータの書式を参考例を見ながら右のように記述していますが、当初はその意味が良く理解できませんでした。 特に %4d の部分です。
    sprintf(out_str1, "KUDARI %4d Km/h" , V);
変数V の書式を指定しているようですが、そのルールがよく分かりませんでした。 ネットで調べてみると、C言語の説明の中で「標準入出力関数」として詳しく解説されており、プログラム屋には常識的な知識なのだと気がつきました。

**************************************************************

 

 一応は作動するソフトが完成したので、今度はハードを固める事にしました。 今回はレイアウトに設置する事を考えていますので、コンパクトに一体的に構成しました。 少しは回路がありますのでArduino用のユニバーサル基板(サンハヤト製 UB-ARD03-P)を使用したシールドを作り、その上にLCDを装着する構成としました。  下の写真はシールドの表側です。

 裏側には、スズメッキ線で配線していますが、クロス部分にはショート防止のため、カプトンテープを貼っています。

 ハード部分の構成は下左の写真の様に、Arduino本体、シールド、LCDの3点で、それを右の写真のように、積み重ねてセットにしました。 このセットを納めるケースが欲しくなりますね。 そのうち工作することにします。

 

 

 レールを設置したプレートと接続した状態を下に示す。 この状態で機能テストを実施して、ハードとソフトの機能が正常である事を確認しました。 そして、クリップで配線していた部分もハンダ付けして完成です。

 

■ レイアウトに設置する

 完成したユニットをレイアウトに設置した状態を下に示す。 埃対策シートを巻きあげて、プレートを設置し、測定ユニットを置いてみました。

 早速、電車や列車を走らせて楽しみたいところですが、クラーの無い物置部屋では、その余裕がありません。 写真撮影もそこそこにクラーの部屋に逃げ込みました。 それにしても暑いですね。 実際の走行テストは、盛夏を過ぎてからの楽しみに取っておくことにします。