列車走行に合わせて LED信号機の現示を変更する

当サイトではアフィリエイト広告を利用しています。

列車の走行位置に合わせて信号機を青→赤→黄→青と変化させる

タイマではなく列車走行位置に合わせてLED 信号機の現示を更新します。
Arduino とトミックスのセンサーを活用します。

LED を組み込んで作成した信号機。少しでも実感的になるよう、列車の走行位置に合わせた灯火色にしたいので、Arduino を使って実際にお試ししてみました。

架線柱に LED 点灯する信号機を設置する 2つの信号機を設置した場内信号機をつくる

センサーによる列車検出と灯火への反映

実際の鉄道での ATS をイメージし、信号機を通過した後、さらに先へ列車が進み遠ざかることで 赤 から 黄、青と変わるようにします。

列車が遠ざかったことを検出するために、以下のようにセンサーを利用します。
センサーはトミックスの TCS センサーを活用します。

信号機とセンサーの位置

なお、TCS センサーの活用については以下のサイトを参考にしました。

それぞれのセンサーは以下のように信号機と連動させます。

センサー用途
A信号機横を通過したことを検出する。
灯火は赤に変更。
B信号機から2編成分くらい遠くまで列車が移動したことを検出する。灯火は黄に変更。
信号機のある閉塞区間の次の閉塞区間に列車が抜けた位置のイメージ。
CセンサーB の位置からさらに1編成分以上遠くまで列車が移動したことを検出する。灯火は青に変更。
B の閉塞区間のさらに次の閉塞区間に列車が抜けた位置のイメージ。
センサーと信号機との連動

図で表すと以下のようなイメージです。

列車位置による信号機の灯火の変化

イメージと記載しているのは、実物の閉塞信号機とは異なる方法で制御しているためです。実際には閉塞区間に列車が存在するかどうかによって閉塞信号機は動作するため、点で列車が通過するのを判定するのは正しくありません。が、鉄道模型で閉塞区間を表現するのはなかなか大変(1本のレールであっても、閉塞区間に合わせて電気的に分割し、列車が走る区間のみに給電する必要があります)なので、簡易的な表現としています。

センサーレールの準備

今回、TCS センサーはワイドレールの S140 に取り付けました。
レールに応じてセンサーがいくつか発売されてますので、レールに応じてセンサーを選択する必要があります。
S140 を選択したのは、設置スペースを考えるとできるだけ短い方が良いことと、センサー取り付けのための開口部が元から簡単に取り外せるようになっているためです。

他のワイドレールや PCレールでは切り込み部分に合わせてカーターナイフなどで実際に切り離す必要があります。

S140 への TCS センサーの取り付け

下の写真がセンサーを取り付けた状態です。

センサーを取り付けたレール

センサーはレールに応じて選択する必要があります。参考に、従来のワイドレールでないレール用の製品です。

Arduino の接続

Arduino との接続は以下の通り。

ちょっと汚いですね。若干強引に接続している箇所もあります。

はい、汚くてわからないですね、、すみません。

どのポートに何を接続しているかは付録のところで記載してますので、参考にしてください。
なお、LED は抵抗 1kΩ を入れているのと、センサーA のみ動作確認用として、列車が通過した時にブレッドボード上の LED が点灯するようにしています。

走行の様子

走行の様子です。
かなり短い距離でテストしてます。実際には走らせる列車長に応じて距離を決めていくと良いです。

写真でも、信号の変化する様子です。

列車がセンサーA に差し掛かる前。
列車が信号機横を通過すると赤信号に。
列車が遠ざかると赤から黄色に。
列車がさらに遠ざかり青信号に。

付録 ー Arduino コード

お試し用ではありますが、Arduino のコードも掲載しておきますので、ご参考まで。

ポートは以下のように利用しています。

ポートIO用途
2INセンサーA
3INセンサーA (逆方向検知)
6OUT信号機 Green
7OUT信号機 Yellow
8OUT信号機 Red
11INセンサーB
12INセンサーC
入出力ポートと用途
Arduino コードサンプル
const int SIG_A_LED_G = 6;
const int SIG_A_LED_Y = 7;
const int SIG_A_LED_R = 8;

const int SENSOR_A_1 = 2;
const int SENSOR_A_2 = 3;
const int SENSOR_B_1 = 11;
const int SENSOR_C_1 = 12;

const int SIGNAL_STOP = 0;
const int SIGNAL_WARN = 1;
const int SIGNAL_CAUTION = 2;
const int SIGNAL_REDUCE = 3;
const int SIGNAL_CLEARD = 4;

int signalA = SIGNAL_CLEARD;
int signalB = SIGNAL_CLEARD;
int signalC = SIGNAL_CLEARD;


void setup() {
  // put your setup code here, to run once:
  pinMode(SENSOR_A_1, INPUT_PULLUP);
  pinMode(SENSOR_A_2, INPUT_PULLUP);
  pinMode(SENSOR_B_1, INPUT_PULLUP);
  pinMode(SENSOR_C_1, INPUT_PULLUP);
  pinMode(SIG_A_LED_G, OUTPUT);
  pinMode(SIG_A_LED_Y, OUTPUT);
  pinMode(SIG_A_LED_R, OUTPUT);

  digitalWrite(SIG_A_LED_G, LOW);
  digitalWrite(SIG_A_LED_Y, LOW);
  digitalWrite(SIG_A_LED_R, LOW);

  Serial.begin(9600);
  while (!Serial) {
    ;
  }
}

void loop() {
  // put your main code here, to run repeatedly:
  int sensor1, sensor2, sensorB, sensorC;
  sensor1 = digitalRead(SENSOR_A_1);
  sensor2 = digitalRead(SENSOR_A_2);
  sensorB = digitalRead(SENSOR_B_1);
  sensorC = digitalRead(SENSOR_C_1);
  Serial.print("sensor1: ");
  Serial.print(sensor1);
  Serial.print(", sensor2: ");
  Serial.print(sensor2);
  Serial.print(", sensorB: ");
  Serial.print(sensorB);
  Serial.print(", sensorC: ");
  Serial.println(sensorC);

  if (sensor1 == LOW) {
    signalA = SIGNAL_STOP;
  } else if (sensorB == LOW) {
    signalA = SIGNAL_CAUTION;
  } else if (sensorC == LOW) {
    signalA = SIGNAL_CLEARD;
  } else if (sensor2 == LOW) { //逆行
    signalA = SIGNAL_STOP;
  }

  updateSignal(signalA);
  delay(50);
}


void updateSignal(int signal) {
  int green = LOW, yellow = LOW, red = LOW;
  switch (signal) {
  case SIGNAL_STOP:
    red = HIGH;
    break;
  case SIGNAL_CAUTION:
    yellow = HIGH;
    break;
  case SIGNAL_CLEARD:
    green = HIGH;
    break;
  default:
    red = HIGH;
    yellow = HIGH;
    break;
  }
  digitalWrite(SIG_A_LED_G, green); 
  digitalWrite(SIG_A_LED_Y, yellow);
  digitalWrite(SIG_A_LED_R, red);
}

今回はお試しということで、トミックスのセンサーを活用した車両の通過を検知し、信号機の灯火に反映させられることを確認しました。複数の信号機の制御など描いているのはもっと複雑な制御が必要になります。まだまだやりたい形に近づけられるよう進めていきます!

皆様の鉄道模型ライフがより楽しくハッピーになりますように!