// MEGA-2-7
// 2021.2.3
// Arduino MEGA 2560 を使用する。
// PWM周波数を31kHzにする。

#define  UNTEN 55
#define  STRT  54
#define  VOL   A2
#define  GEN   A3
#define  CH1   58
#define  CH2   59
#define  CH3   60
#define  CH4   61
#define  SEN1  63
#define  SEN2  64
#define  SEN3  68
#define  SEN4  69
#define  SEN5  40
#define  SEN6  46
#define  F11   13
#define  F12   12
#define  F21   11
#define  F22   10
#define  F31   5
#define  F32   4
#define  F41   3
#define  F42   2
#define  F12PWM 8
#define  F3PWM  7
#define  F4PWM  6
#define  P12   23
#define  P34   25
#define  P5    29
#define  P6    31
#define  S5SIN 38
#define  S6SIN 44

  int i;
  int vol;
  int gen;

void setup() {
  pinMode(UNTEN,INPUT);
  pinMode(STRT,INPUT);  
  pinMode(VOL,INPUT);
  pinMode(GEN,INPUT);
  pinMode(CH1,INPUT);
  pinMode(CH2,INPUT);
  pinMode(CH3,INPUT);
  pinMode(CH4,INPUT);
  pinMode(SEN1,INPUT);
  pinMode(SEN2,INPUT);
  pinMode(SEN3,INPUT);
  pinMode(SEN4,INPUT);
  pinMode(SEN5,INPUT);
  pinMode(SEN6,INPUT);
  
  pinMode(F11,OUTPUT);
  pinMode(F12,OUTPUT);
  pinMode(F21,OUTPUT);
  pinMode(F22,OUTPUT);
  pinMode(F31,OUTPUT);
  pinMode(F32,OUTPUT);
  pinMode(F41,OUTPUT);
  pinMode(F42,OUTPUT);
  pinMode(F12PWM,OUTPUT);
  pinMode(F3PWM,OUTPUT);
  pinMode(F4PWM,OUTPUT);
  pinMode(P12,OUTPUT);
  pinMode(P34,OUTPUT);
  pinMode(P5,OUTPUT);
  pinMode(P6,OUTPUT);
  pinMode(S5SIN,OUTPUT);
  pinMode(S6SIN,OUTPUT);

  TCCR4B = (TCCR4B & 0b11111000) | 0x01;   //Timer4を31KHzにする

  analogWrite(F12PWM,0); 
  analogWrite(F3PWM,0);
  analogWrite(F4PWM,0);
  digitalWrite(F11,LOW);
  digitalWrite(F12,LOW);
  digitalWrite(F21,LOW);
  digitalWrite(F22,LOW);
  digitalWrite(F31,LOW);
  digitalWrite(F32,LOW);
  digitalWrite(F41,LOW);
  digitalWrite(F42,LOW);
  digitalWrite(S5SIN,HIGH);
  digitalWrite(S6SIN,HIGH);
  
  delay(500);
  digitalWrite(P12,HIGH);
  delay(500);
  digitalWrite(P34,HIGH);
  delay(500);
  digitalWrite(P5,HIGH);
  delay(500);
  digitalWrite(P6,HIGH);
  delay(500);
  digitalWrite(P12,LOW);
  delay(500);
  digitalWrite(P34,LOW);
  delay(500);
  digitalWrite(P5,LOW);
  delay(500);
  digitalWrite(P6,LOW);
  delay(500);
}

void mode1(){        //1番ホーム外周右回り
  if (digitalRead(SEN1)==LOW){    //ホームに列車はいるか?負論理
    digitalWrite(P12,LOW);
    delay(500);
    digitalWrite(P34,LOW);
    delay(500);
    digitalWrite(P5,LOW);
    delay(500);
    digitalWrite(P6,LOW);
    delay(500);
   
    vol=analogRead(VOL)/4;
    delay(10);
    analogWrite(F3PWM,vol*50/255);
    digitalWrite(F31,HIGH);     //室内灯点灯
    digitalWrite(S5SIN,LOW);
    delay(500); 
  
    for(i=50;i<255;i++){      //加速する
      vol=analogRead(VOL)/4;
      delay(10);
      analogWrite(F3PWM,vol*i/255);
    }
    analogWrite(F12PWM,vol);
    digitalWrite(F11,HIGH);

    while (digitalRead(SEN3) == HIGH) {     //S3を待つ
      vol=analogRead(VOL)/4;
      delay(10);
      analogWrite(F12PWM,vol);
      analogWrite(F3PWM,vol);
    }

    digitalWrite(F21,HIGH);
    while (digitalRead(SEN4) == HIGH) {     //S4を待つ
      vol=analogRead(VOL)/4;
      delay(10);
      analogWrite(F12PWM,vol);
    }

    digitalWrite(S5SIN,HIGH);
    while (digitalRead(SEN1) == HIGH) {     //S1を待つ
      vol=analogRead(VOL)/4;
      delay(10);
      analogWrite(F12PWM,vol);
      analogWrite(F3PWM,vol);
    }

    for(i=255;i>50;i--){     //減速
      gen=analogRead(GEN)/12;
      vol=analogRead(VOL)/4;
      delay(5);
      analogWrite(F3PWM,vol*i/255);
      delay(gen);
    }
    delay(1000);
    digitalWrite(F11,LOW);    //停車
    digitalWrite(F21,LOW);
    digitalWrite(F31,LOW);
  }
  delay(500);
  return;
}

void mode2() {        //2番ホーム外周左回り
  if (digitalRead(SEN2)==LOW){    //ホームに列車はいるか?負論理
    digitalWrite(P12,HIGH);
    delay(500);
    digitalWrite(P34,LOW);
    delay(500);
    digitalWrite(P5,LOW);
    delay(500);
    digitalWrite(P6,LOW);
    delay(500);
   
    vol=analogRead(VOL)/4;
    delay(10);
    analogWrite(F4PWM,vol*50/255);
    digitalWrite(F42,HIGH);     //室内灯点灯
    digitalWrite(S6SIN,LOW);
    delay(500);
    
    for(i=50;i<255;i++){      //加速する
      vol=analogRead(VOL)/4;
      delay(10);
      analogWrite(F4PWM,vol*i/255);
    }
    analogWrite(F12PWM,vol);
    digitalWrite(F22,HIGH);
    
    while (digitalRead(SEN4) == HIGH) {     //S4を待つ
      vol=analogRead(VOL)/4;
      delay(10);
      analogWrite(F4PWM,vol);
      analogWrite(F12PWM,vol);
    }
    
    digitalWrite(F12,HIGH);
    while (digitalRead(SEN3) == HIGH) {     //S3を待つ
      vol=analogRead(VOL)/4;
      delay(10);
      analogWrite(F12PWM,vol);   
    }

    digitalWrite(S6SIN,HIGH);
    while (digitalRead(SEN2) == HIGH) {     //S2を待つ
      vol=analogRead(VOL)/4;
      delay(10);
      analogWrite(F12PWM,vol);
      analogWrite(F4PWM,vol);
    }

    for(i=255;i>50;i--){     //減速
      gen=analogRead(GEN)/12;
      vol=analogRead(VOL)/4;
      delay(5);
      analogWrite(F4PWM,vol*i/255);
      delay(gen);
    }
    delay(1000);
    digitalWrite(F12,LOW);    //停車
    digitalWrite(F22,LOW);
    digitalWrite(F42,LOW);
  }
  delay(500);
  return;
}

void mode3(){        //1番ホームから外周右回りし、リバースして2番ホームへ
  if (digitalRead(SEN1)==LOW){    //ホームに列車はいるか?負論理
    digitalWrite(P12,LOW);
    delay(500);
    digitalWrite(P34,LOW);
    delay(500);
    digitalWrite(P5,LOW);
    delay(500);
    digitalWrite(P6,LOW);
    delay(500);
   
    vol=analogRead(VOL)/4;
    delay(10);
    analogWrite(F3PWM,vol*50/255);  //室内灯点灯
    digitalWrite(F31,HIGH);
    digitalWrite(S5SIN,LOW);
    delay(500); 
  
    for(i=50;i<255;i++){      //加速する
      vol=analogRead(VOL)/4;
      delay(10);
      analogWrite(F3PWM,vol*i/255);
    }
    analogWrite(F12PWM,vol);
    digitalWrite(F11,HIGH);
    while (digitalRead(SEN3) == HIGH) {     //S3を待つ
      vol=analogRead(VOL)/4;
      delay(10);
      analogWrite(F12PWM,vol);
      analogWrite(F3PWM,vol);
    }
    digitalWrite(P6,HIGH);        //リバース設定
    delay(500);
    digitalWrite(P34,HIGH);
    delay(500);
    digitalWrite(P12,HIGH);
    delay(500);
    digitalWrite(F21,LOW);
    digitalWrite(F22,HIGH);
    digitalWrite(F31,LOW);

    while (digitalRead(SEN4) == HIGH) {     //S4を待つ
      vol=analogRead(VOL)/4;
      delay(10);
      analogWrite(F12PWM,vol);
    }
    digitalWrite(P6,LOW);        //リバース設定を戻す
    delay(500);
    digitalWrite(F11,LOW);
    digitalWrite(F12,HIGH);

    while (digitalRead(SEN3) == HIGH) {     //S3を待つ
      vol=analogRead(VOL)/4;
      delay(10);
      analogWrite(F12PWM,vol);
    }
    digitalWrite(P34,LOW);    //2番ホームへ
    digitalWrite(F22,LOW);
    analogWrite(F4PWM,vol);
    digitalWrite(F42,HIGH);
    digitalWrite(S6SIN,HIGH);
    delay(500);
 
    while (digitalRead(SEN2) == HIGH) {     //S2を待つ
      vol=analogRead(VOL)/4;
      delay(10);
      analogWrite(F12PWM,vol);
      analogWrite(F4PWM,vol);
    }
    digitalWrite(F12,LOW);
    
    for(i=255;i>50;i--){     //減速
      gen=analogRead(GEN)/12;
      vol=analogRead(VOL)/4;
      delay(5);
      analogWrite(F4PWM,vol*i/255);
      delay(gen);
    }
    delay(1000);
    digitalWrite(F42,LOW);    //停車
    digitalWrite(S5SIN,HIGH);
  }
  delay(500);
  return;
}

void mode4(){        //2番ホームから外周左回りし、リバースして1番ホームへ
  if (digitalRead(SEN2)==LOW){    //ホームに列車はいるか?負論理
    digitalWrite(P12,HIGH);
    delay(500);
    digitalWrite(P34,LOW);
    delay(500);
    digitalWrite(P5,LOW);
    delay(500);
    digitalWrite(P6,LOW);
    delay(500);
   
    vol=analogRead(VOL)/4;
    delay(10);
    analogWrite(F4PWM,vol*50/255);  //室内灯点灯
    digitalWrite(F42,HIGH);
    digitalWrite(S6SIN,LOW);
    delay(500); 
  
    for(i=50;i<255;i++){      //加速する
      vol=analogRead(VOL)/4;
      delay(10);
      analogWrite(F4PWM,vol*i/255);
    }
    analogWrite(F12PWM,vol);
    digitalWrite(F22,HIGH);
    
    while (digitalRead(SEN4) == HIGH) {     //S4を待つ
      vol=analogRead(VOL)/4;
      delay(10);
      analogWrite(F4PWM,vol);
      analogWrite(F12PWM,vol);
    }
    digitalWrite(P5,HIGH);        //リバース設定
    delay(500);
    digitalWrite(P34,HIGH);
    delay(500);
    digitalWrite(P12,HIGH);
    delay(500);
    digitalWrite(F42,LOW);
    digitalWrite(F11,HIGH);

    while (digitalRead(SEN3) == HIGH) {     //S3を待つ
      vol=analogRead(VOL)/4;
      delay(10);
      analogWrite(F12PWM,vol);
    }
    digitalWrite(P5,LOW);        //リバース設定を戻す
    delay(500);
    digitalWrite(F22,LOW);
    digitalWrite(F21,HIGH);

    while (digitalRead(SEN4) == HIGH) {     //S4を待つ
      vol=analogRead(VOL)/4;
      delay(10);
      analogWrite(F12PWM,vol);
    }
    digitalWrite(P12,LOW);     //1番ホームへ
    analogWrite(F3PWM,vol);
    digitalWrite(F31,HIGH); 
    digitalWrite(F11,LOW);
    digitalWrite(S5SIN,HIGH);
    delay(500);
 
    while (digitalRead(SEN1) == HIGH) {     //S1を待つ
      vol=analogRead(VOL)/4;
      delay(10);
      analogWrite(F12PWM,vol);
      analogWrite(F3PWM,vol);
    }

    for(i=255;i>50;i--){     //減速
      gen=analogRead(GEN)/12;
      vol=analogRead(VOL)/4;
      delay(5);
      analogWrite(F3PWM,vol*i/255);
      delay(gen);
    }
    delay(1000);
    digitalWrite(F31,LOW);    //停車
    digitalWrite(F21,LOW);
    digitalWrite(S6SIN,HIGH);
  }
  delay(500);
  return;
}

void mode5(){        //1番ホームから外周右回りし2番ホームの列車と交代
    if (digitalRead(SEN1)==HIGH){    //ホームに列車が居ない場合は中止。負論理
          return;
    }
    if (digitalRead(SEN2)==HIGH){    //ホームに列車が居ない場合は中止。負論理
          return;
    }
    digitalWrite(P12,LOW);
    delay(500);
    digitalWrite(P34,LOW);
    delay(500);
    digitalWrite(P5,LOW);
    delay(500);
    digitalWrite(P6,LOW);
    delay(500);
   
    vol=analogRead(VOL)/4;
    delay(10);
    analogWrite(F3PWM,vol*50/255);  //室内灯点灯
    digitalWrite(F31,HIGH); 
    digitalWrite(S5SIN,LOW);
    delay(500); 
  
    for(i=50;i<255;i++){      //加速する
      vol=analogRead(VOL)/4;
      delay(10);
      analogWrite(F3PWM,vol*i/255);
    }
    analogWrite(F12PWM,vol);
    digitalWrite(F11,HIGH);
    
    while (digitalRead(SEN3) == HIGH) {     //S3を待つ
      vol=analogRead(VOL)/4;
      delay(10);
      analogWrite(F12PWM,vol);
      analogWrite(F3PWM,vol);
    }
    digitalWrite(P6,HIGH);        //リバース設定
    delay(500);
    digitalWrite(P34,HIGH);
    delay(500);
    digitalWrite(P12,HIGH);
    delay(500);
    digitalWrite(F21,LOW);
    digitalWrite(F22,HIGH);
    digitalWrite(F31,LOW);

    while (digitalRead(SEN4) == HIGH) {     //S4を待つ
      vol=analogRead(VOL)/4;
      delay(10);
      analogWrite(F12PWM,vol);
    }
    digitalWrite(P6,LOW);        //リバース設定を戻す
    delay(500);
    digitalWrite(F11,LOW);
    digitalWrite(F12,HIGH);

    while (digitalRead(SEN3) == HIGH) {     //S3を待つ
      vol=analogRead(VOL)/4;
      delay(10);
      analogWrite(F12PWM,vol);
    }
    digitalWrite(P34,LOW);    //2番ホームへ
    digitalWrite(S6SIN,LOW);
    delay(500);

    analogWrite(F4PWM,vol*50/255);
    digitalWrite(F42,HIGH);
    for(i=50;i<255;i++){      //2番線の列車を発車を発車させる
      vol=analogRead(VOL)/4;
      delay(10);
      analogWrite(F4PWM,vol*i/255);
    }

    while (digitalRead(SEN6) == LOW) {   //ホームの列車が出ていくまで待つ。
      vol=analogRead(VOL)/4;
      delay(10);
      analogWrite(F12PWM,vol);
      analogWrite(F4PWM,vol);
    }
    digitalWrite(S6SIN,HIGH);
    delay(500);             //しばらく待つ。
        
    while (digitalRead(SEN2) == HIGH) {     //S2を待つ
      vol=analogRead(VOL)/4;
      delay(10);
      analogWrite(F12PWM,vol);
      analogWrite(F4PWM,vol);
    }
    
    for(i=255;i>20;i--){     //減速
      gen=analogRead(GEN)/12;
      vol=analogRead(VOL)/4;
      delay(5);
      analogWrite(F4PWM,vol*i/255);
      delay(gen);
    }

    digitalWrite(P34,HIGH);   //ホーム2を遮断する。
    digitalWrite(F42,LOW);
    delay(500);

    while (digitalRead(SEN3) == HIGH) {     //S3を待つ
      vol=analogRead(VOL)/4;
      delay(10);
      analogWrite(F12PWM,vol);
    }
    digitalWrite(P5,HIGH);     //リバース設定
    delay(500);
    digitalWrite(F22,LOW);
    digitalWrite(F21,HIGH);
    delay(500);

    while (digitalRead(SEN4) == HIGH) {     //S4を待つ
      vol=analogRead(VOL)/4;
      delay(10);
      analogWrite(F12PWM,vol);
    }
    digitalWrite(F12,LOW);
    analogWrite(F3PWM,vol);
    digitalWrite(F31,HIGH);
    digitalWrite(S5SIN,HIGH);
    
    digitalWrite(P12,LOW);     //ホーム1に入線させる
    delay(500);
    
    while (digitalRead(SEN1) == HIGH) {     //S1を待つ
      vol=analogRead(VOL)/4;
      delay(10);
      analogWrite(F12PWM,vol);
      analogWrite(F3PWM,vol);
    }

    analogWrite(F12PWM,0);
    for(i=255;i>20;i--){     //減速
      gen=analogRead(GEN)/12;
      vol=analogRead(VOL)/4;
      delay(5);
      analogWrite(F3PWM,vol*i/255);
      delay(gen);
    }
    delay(1000);
    digitalWrite(F31,LOW);    //停車
    digitalWrite(F21,LOW);
    delay(500);
    return;
}

void loop(){
  if (digitalRead(UNTEN)==HIGH || digitalRead(STRT)==HIGH){
    if (digitalRead(CH1)==HIGH && digitalRead(CH2)==HIGH && digitalRead(CH3)==HIGH && digitalRead(CH4)==HIGH){
      mode1();
    } else if (digitalRead(CH1)==LOW && digitalRead(CH2)==HIGH && digitalRead(CH3)==HIGH && digitalRead(CH4)==HIGH){
      mode2();
    } else if (digitalRead(CH1)==HIGH && digitalRead(CH2)==LOW && digitalRead(CH3)==HIGH && digitalRead(CH4)==HIGH){
      mode1();
      mode1();
    } else if (digitalRead(CH1)==LOW && digitalRead(CH2)==LOW && digitalRead(CH3)==HIGH && digitalRead(CH4)==HIGH){
      mode2();
      mode2();
    } else if (digitalRead(CH1)==HIGH && digitalRead(CH2)==HIGH && digitalRead(CH3)==LOW && digitalRead(CH4)==HIGH){
      mode1();
      mode2();
    } else if (digitalRead(CH1)==LOW && digitalRead(CH2)==HIGH && digitalRead(CH3)==LOW && digitalRead(CH4)==HIGH){
      mode3();
    } else if (digitalRead(CH1)==HIGH && digitalRead(CH2)==LOW && digitalRead(CH3)==LOW && digitalRead(CH4)==HIGH){
      mode4();
    } else if (digitalRead(CH1)==LOW && digitalRead(CH2)==LOW && digitalRead(CH3)==LOW && digitalRead(CH4)==HIGH){
         mode5();
    }
    delay (500);
  }  
}