// Sin-Tozan-Unit-05A
// 2021.11/19
// Arduino MEGA 2560 を使用する。
// PWM周波数を31kHzにする。
#define VOL1 A0
#define VOL2 A1
#define VOL3 A2
#define AUT 62
#define PTS1 63
#define PTS2 64
#define PTS3 65
#define DSWR 66
#define DSWL 67
#define EDS1 22
#define EDS2 24
#define EDS3 28
#define EDS4 32
#define EDS5 34
#define TS1 26
#define TS2 30
#define TS3 36
#define J1G 48
#define S1G 46
#define J2G 44
#define S2G 42
#define J3G 43
#define S3G 45
#define J4G 49
#define S4G 47
#define J5G 53
#define S5G 51
#define J1R 23
#define S1R 25
#define J2R 27
#define S2R 29
#define J3R 31
#define S3R 33
#define J4R 37
#define S4R 35
#define J5R 41
#define S5R 39
#define POUT1 11
#define POUT2 12
#define POUT3 13
#define MPWM 7
#define DIRR 5
#define DIRL 6
int pts1;
int pts2;
int pts3;
int dswr;
int dswl;
int vol1;
int vol2;
int vol3;
int aut;
int aut1;
int eds1;
int eds2;
int eds3;
int eds4;
int eds5;
int ts1;
int ts2;
int ts3;
int duty;
int i;
void setup() {
pinMode(VOL1,INPUT);
pinMode(VOL2,INPUT);
pinMode(VOL3,INPUT);
pinMode(AUT,INPUT);
pinMode(PTS1,INPUT);
pinMode(PTS2,INPUT);
pinMode(PTS3,INPUT);
pinMode(DSWR,INPUT);
pinMode(DSWL,INPUT);
pinMode(EDS1,INPUT);
pinMode(EDS2,INPUT);
pinMode(EDS3,INPUT);
pinMode(EDS4,INPUT);
pinMode(EDS5,INPUT);
pinMode(TS1,INPUT);
pinMode(TS2,INPUT);
pinMode(TS3,INPUT);
pinMode(J1G,OUTPUT);
pinMode(J2G,OUTPUT);
pinMode(J3G,OUTPUT);
pinMode(J4G,OUTPUT);
pinMode(J5G,OUTPUT);
pinMode(S1G,OUTPUT);
pinMode(S2G,OUTPUT);
pinMode(S3G,OUTPUT);
pinMode(S4G,OUTPUT);
pinMode(S5G,OUTPUT);
pinMode(J1R,OUTPUT);
pinMode(J2R,OUTPUT);
pinMode(J3R,OUTPUT);
pinMode(J4R,OUTPUT);
pinMode(J5R,OUTPUT);
pinMode(S1R,OUTPUT);
pinMode(S2R,OUTPUT);
pinMode(S3R,OUTPUT);
pinMode(S4R,OUTPUT);
pinMode(S5R,OUTPUT);
pinMode(POUT1,OUTPUT);
pinMode(POUT2,OUTPUT);
pinMode(POUT3,OUTPUT);
pinMode(MPWM,OUTPUT);
pinMode(DIRR,OUTPUT);
pinMode(DIRL,OUTPUT);
TCCR4B = (TCCR4B & 0b11111000) | 0x01; //Timer4を31KHzにする
digitalWrite(DIRR,LOW);
digitalWrite(DIRL,LOW);
analogWrite(MPWM,0);
digitalWrite(POUT1,LOW);
digitalWrite(POUT2,LOW);
digitalWrite(POUT3,LOW);
digitalWrite(J1G,LOW);
digitalWrite(J2G,LOW);
digitalWrite(J3G,LOW);
digitalWrite(J4G,LOW);
digitalWrite(J5G,LOW);
digitalWrite(S1G,LOW);
digitalWrite(S2G,LOW);
digitalWrite(S3G,LOW);
digitalWrite(S4G,LOW);
digitalWrite(S5G,LOW);
digitalWrite(J1R,HIGH);
digitalWrite(J2R,HIGH);
digitalWrite(J3R,HIGH);
digitalWrite(J4R,HIGH);
digitalWrite(J5R,HIGH);
digitalWrite(S1R,HIGH);
digitalWrite(S2R,HIGH);
digitalWrite(S3R,HIGH);
digitalWrite(S4R,HIGH);
digitalWrite(S5R,HIGH);
duty = 0;
}
void ledhyoji(){
// 全ての信号を赤にする
digitalWrite(J1G,LOW);
digitalWrite(J2G,LOW);
digitalWrite(J3G,LOW);
digitalWrite(J4G,LOW);
digitalWrite(J5G,LOW);
digitalWrite(S1G,LOW);
digitalWrite(S2G,LOW);
digitalWrite(S3G,LOW);
digitalWrite(S4G,LOW);
digitalWrite(S5G,LOW);
digitalWrite(J1R,HIGH);
digitalWrite(J2R,HIGH);
digitalWrite(J3R,HIGH);
digitalWrite(J4R,HIGH);
digitalWrite(J5R,HIGH);
digitalWrite(S1R,HIGH);
digitalWrite(S2R,HIGH);
digitalWrite(S3R,HIGH);
digitalWrite(S4R,HIGH);
digitalWrite(S5R,HIGH);
// 出発ホームと到着ホームへの信号を緑にする
if (dswr == HIGH){
if (pts1 == HIGH){
if (pts2 == HIGH){
digitalWrite(J3G,HIGH);
digitalWrite(S2G,HIGH);
digitalWrite(J3R,LOW);
digitalWrite(S2R,LOW);
} else if (pts3 == HIGH){
digitalWrite(J4G,HIGH);
digitalWrite(S2G,HIGH);
digitalWrite(J4R,LOW);
digitalWrite(S2R,LOW);
} else {
digitalWrite(J5G,HIGH);
digitalWrite(S2G,HIGH);
digitalWrite(J5R,LOW);
digitalWrite(S2R,LOW);
}
} else if (pts2 == HIGH){
digitalWrite(J3G,HIGH);
digitalWrite(S1G,HIGH);
digitalWrite(J3R,LOW);
digitalWrite(S1R,LOW);
} else if (pts3 == HIGH){
digitalWrite(J4G,HIGH);
digitalWrite(S1G,HIGH);
digitalWrite(J4R,LOW);
digitalWrite(S1R,LOW);
} else {
digitalWrite(J5G,HIGH);
digitalWrite(S1G,HIGH);
digitalWrite(J5R,LOW);
digitalWrite(S1R,LOW);
}
} else if (dswl == HIGH){
if (pts1 == HIGH){
if (pts2 == HIGH){
digitalWrite(J2G,HIGH);
digitalWrite(S3G,HIGH);
digitalWrite(J2R,LOW);
digitalWrite(S3R,LOW);
} else if (pts3 == HIGH){
digitalWrite(J2G,HIGH);
digitalWrite(S4G,HIGH);
digitalWrite(J2R,LOW);
digitalWrite(S4R,LOW);
} else {
digitalWrite(J2G,HIGH);
digitalWrite(S5G,HIGH);
digitalWrite(J2R,LOW);
digitalWrite(S5R,LOW);
}
} else if (pts2 == HIGH){
digitalWrite(J1G,HIGH);
digitalWrite(S3G,HIGH);
digitalWrite(J1R,LOW);
digitalWrite(S3R,LOW);
} else if (pts3 == HIGH){
digitalWrite(J1G,HIGH);
digitalWrite(S4G,HIGH);
digitalWrite(J1R,LOW);
digitalWrite(S4R,LOW);
} else {
digitalWrite(J1G,HIGH);
digitalWrite(S5G,HIGH);
digitalWrite(J1R,LOW);
digitalWrite(S5R,LOW);
}
}
delay(20);
return;
}
void mode1(int densha){
if (analogRead(densha) < 400 ) { //電車の設定の有無チェック
return; //無の場合はこの運行をパスする
}
digitalWrite(POUT1, HIGH); //経路を設定する
delay(500);
digitalWrite(POUT2, HIGH);
delay(500);
digitalWrite(DIRL,LOW); //進行方向を設定する
digitalWrite(DIRR,HIGH);
dswr=HIGH;
dswl=LOW;
pts1=HIGH;
pts2=HIGH;
pts3=LOW;
ledhyoji();
analogWrite(MPWM, 0); //フィーダー出力0
for (i=0;i<17;i++ ) { //走行加速開始
duty = analogRead(densha); //VRの値を読込む
duty = (duty - 500) *(0.1 + 0.025*i );
analogWrite(MPWM, duty); //フィーダー出力
delay(200);
}
ts2 = digitalRead(TS2); //場内点通過チェック
while (ts2 == HIGH ) { //場内点通過待ち
duty = analogRead(densha); //VRの値を読込む
duty = (duty - 500) * 0.5; //通常速度
analogWrite(MPWM, duty); //フィーダー出力
ts2 = digitalRead(TS2); //場内点通過チェック
delay(50);
}
eds3 = digitalRead(EDS3); //到着チェック
while (eds3 == HIGH ) { //到着待ち
duty = analogRead(densha); //VRの値を読込む
duty = (duty - 500) * 0.4; //低速走行
analogWrite(MPWM, duty); //フィーダー出力
eds3 = digitalRead(EDS3); //到着チェック
delay(50);
}
delay(500);
analogWrite(MPWM, 0);
delay(1000);
return;
}
void mode2(int densha){
if (analogRead(densha) < 400 ) { //電車の設定の有無チェック
return; //無の場合はこの運行をパスする
}
digitalWrite(POUT1, HIGH); //経路を設定する
delay(500);
digitalWrite(POUT2, LOW);
delay(500);
digitalWrite(DIRR,LOW); //進行方向を設定する
digitalWrite(DIRL,HIGH);
dswr=LOW;
dswl=HIGH;
pts1=HIGH;
pts2=LOW;
pts3=LOW;
ledhyoji();
analogWrite(MPWM, 0); //フィーダー出力0
for (i=0;i<17;i++ ) { //走行加速開始
duty = analogRead(densha); //VRの値を読込む
duty = (duty - 500) *(0.1 + 0.025*i );
analogWrite(MPWM, duty); //フィーダー出力
delay(200);
}
eds2 = digitalRead(EDS2); //到着チェック
while (eds2 == HIGH ) { //到着待ち
duty = analogRead(densha); //VRの値を読込む
duty = (duty - 500) * 0.4; //低速走行
analogWrite(MPWM, duty); //フィーダー出力
eds2 = digitalRead(EDS2); //到着チェック
delay(50);
}
delay(500);
analogWrite(MPWM, 0);
delay(1000);
return;
}
void mode3(int densha){
if (analogRead(densha) < 400 ) { //電車の設定の有無チェック
return; //無の場合はこの運行をパスする
}
digitalWrite(POUT1, LOW); //経路を設定する
delay(500);
digitalWrite(POUT2, LOW);
delay(500);
digitalWrite(DIRL,LOW); //進行方向を設定する
digitalWrite(DIRR,HIGH);
dswr=HIGH;
dswl=LOW;
pts1=LOW;
pts2=LOW;
pts3=LOW;
ledhyoji();
analogWrite(MPWM, 0); //フィーダー出力0
for (i=0;i<17;i++ ) { //走行加速開始
duty = analogRead(densha); //VRの値を読込む
duty = (duty - 500) *(0.1 + 0.025*i );
analogWrite(MPWM, duty); //フィーダー出力
delay(200);
}
eds5 = digitalRead(EDS5); //到着チェック
while (eds5 == HIGH ) { //到着待ち
duty = analogRead(densha); //VRの値を読込む
duty = (duty - 500) * 0.4; //低速走行
analogWrite(MPWM, duty); //フィーダー出力
eds5 = digitalRead(EDS5); //到着チェック
delay(50);
}
delay(500);
analogWrite(MPWM, 0);
delay(1000);
return;
}
void mode4(int densha){
if (analogRead(densha) < 400 ) { //電車の設定の有無チェック
return; //無の場合はこの運行をパスする
}
digitalWrite(POUT1, LOW); //経路を設定する
delay(500);
digitalWrite(POUT2, HIGH);
delay(500);
digitalWrite(DIRR,LOW); //進行方向を設定する
digitalWrite(DIRL,HIGH);
dswr=LOW;
dswl=HIGH;
pts1=LOW;
pts2=HIGH;
pts3=LOW;
ledhyoji();
analogWrite(MPWM, 0); //フィーダー出力0
for (i=0;i<17;i++ ) { //走行加速開始
duty = analogRead(densha); //VRの値を読込む
duty = (duty - 500) *(0.1 + 0.025*i );
analogWrite(MPWM, duty); //フィーダー出力
delay(200);
}
ts1 = digitalRead(TS1); //場内点通過チェック
while (ts1 == HIGH ) { //場内点通過待ち
duty = analogRead(densha); //VRの値を読込む
duty = (duty - 500) * 0.5; //通常速度
analogWrite(MPWM, duty); //フィーダー出力
ts1 = digitalRead(TS1); //場内点通過チェック
delay(50);
}
eds1 = digitalRead(EDS1); //到着チェック
while (eds1 == HIGH ) { //到着待ち
duty = analogRead(densha); //VRの値を読込む
duty = (duty - 500) * 0.4; //低速走行
analogWrite(MPWM, duty); //フィーダー出力
eds1 = digitalRead(EDS1); //到着チェック
delay(50);
}
delay(500);
analogWrite(MPWM, 0);
delay(1000);
return;
}
void loop(){
aut = digitalRead(AUT); //自動運転スイッチをチェック
if (aut==LOW){ //手動運転モード
pts1 = digitalRead(PTS1); //スイッチ類のチェック
pts2 = digitalRead(PTS2);
dswr = digitalRead(DSWR);
dswl = digitalRead(DSWL);
vol1 = analogRead(VOL1);
ledhyoji(); //パネル表示
if (pts1==HIGH){ //ポイント操作
digitalWrite(POUT1,HIGH);
delay(100);
} else {
digitalWrite(POUT1,LOW);
delay(100);
}
if (pts2==HIGH){
digitalWrite(POUT2,HIGH);
delay(100);
} else {
digitalWrite(POUT2,LOW);
delay(100);
}
if (dswr==HIGH){ //進行方向設定
digitalWrite(DIRR,HIGH);
} else {
digitalWrite(DIRR,LOW);
}
if (dswl==HIGH){
digitalWrite(DIRL,HIGH);
} else {
digitalWrite(DIRL,LOW);
}
duty=(vol1-500)/2;
analogWrite(MPWM,duty);
} else if (aut==HIGH){ //自動運転モード
analogWrite(MPWM, 0); //暴走防止
mode3(0); //densHa0の運行
mode2(0);
mode1(0);
mode4(0);
}
delay(10);
}