当サイトではアフィリエイト広告を利用しています。
列車の走行位置に合わせて信号機を青→赤→黄→青と変化させる
タイマではなく列車走行位置に合わせてLED 信号機の現示を更新します。
Arduino とトミックスのセンサーを活用します。
LED を組み込んで作成した信号機。少しでも実感的になるよう、列車の走行位置に合わせた灯火色にしたいので、Arduino を使って実際にお試ししてみました。


実際の鉄道での ATS をイメージし、信号機を通過した後、さらに先へ列車が進み遠ざかることで 赤 から 黄、青と変わるようにします。
列車が遠ざかったことを検出するために、以下のようにセンサーを利用します。
センサーはトミックスの TCS センサーを活用します。

なお、TCS センサーの活用については以下のサイトを参考にしました。
それぞれのセンサーは以下のように信号機と連動させます。
センサー | 用途 |
---|---|
A | 信号機横を通過したことを検出する。 灯火は赤に変更。 |
B | 信号機から2編成分くらい遠くまで列車が移動したことを検出する。灯火は黄に変更。 信号機のある閉塞区間の次の閉塞区間に列車が抜けた位置のイメージ。 |
C | センサーB の位置からさらに1編成分以上遠くまで列車が移動したことを検出する。灯火は青に変更。 B の閉塞区間のさらに次の閉塞区間に列車が抜けた位置のイメージ。 |
図で表すと以下のようなイメージです。

イメージと記載しているのは、実物の閉塞信号機とは異なる方法で制御しているためです。実際には閉塞区間に列車が存在するかどうかによって閉塞信号機は動作するため、点で列車が通過するのを判定するのは正しくありません。が、鉄道模型で閉塞区間を表現するのはなかなか大変(1本のレールであっても、閉塞区間に合わせて電気的に分割し、列車が走る区間のみに給電する必要があります)なので、簡易的な表現としています。
今回、TCS センサーはワイドレールの S140 に取り付けました。
レールに応じてセンサーがいくつか発売されてますので、レールに応じてセンサーを選択する必要があります。
S140 を選択したのは、設置スペースを考えるとできるだけ短い方が良いことと、センサー取り付けのための開口部が元から簡単に取り外せるようになっているためです。
他のワイドレールや PCレールでは切り込み部分に合わせてカーターナイフなどで実際に切り離す必要があります。

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

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

はい、汚くてわからないですね、、すみません。
どのポートに何を接続しているかは付録のところで記載してますので、参考にしてください。
なお、LED は抵抗 1kΩ を入れているのと、センサーA のみ動作確認用として、列車が通過した時にブレッドボード上の LED が点灯するようにしています。
走行の様子です。
かなり短い距離でテストしてます。実際には走らせる列車長に応じて距離を決めていくと良いです。
写真でも、信号の変化する様子です。




お試し用ではありますが、Arduino のコードも掲載しておきますので、ご参考まで。
ポートは以下のように利用しています。
ポート | IO | 用途 |
---|---|---|
2 | IN | センサーA |
3 | IN | センサーA (逆方向検知) |
6 | OUT | 信号機 Green |
7 | OUT | 信号機 Yellow |
8 | OUT | 信号機 Red |
11 | IN | センサーB |
12 | IN | センサーC |
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);
}
今回はお試しということで、トミックスのセンサーを活用した車両の通過を検知し、信号機の灯火に反映させられることを確認しました。複数の信号機の制御など描いているのはもっと複雑な制御が必要になります。まだまだやりたい形に近づけられるよう進めていきます!
皆様の鉄道模型ライフがより楽しくハッピーになりますように!