HOME >> 鉄道模型実験室 > 登山鉄道レイアウトとモニタ式操作盤 > ArduinoMEGAのスケッチの内容

鉄道模型実験室 No.227  登山鉄道レイアウトとモニタ式操作盤 ArduinoMEGAのスケッチの内容    

 ArduinoMEGAのスケッチの内容を示す。

// Sin-Tozan-Unit-10
// 2022/11/5
// Arduino MEGA 2560 を使用する。
// PWM周波数を31kHzにする。

#include <VarSpeedServo.h>

#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  MPWM  7
#define  DIRR  5
#define  DIRL  6

VarSpeedServo myservo1;
VarSpeedServo myservo2;

  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=0 ;
  int i;
  int mnt;
  int spd;

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(3,INPUT);     //追加
  pinMode(4,INPUT);     //追加
  pinMode(8,INPUT);     //追加
  pinMode(9,INPUT);     //追加
  pinMode(A4,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(MPWM,OUTPUT);
  pinMode(DIRR,OUTPUT);
  pinMode(DIRL,OUTPUT);

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

  digitalWrite(DIRR,LOW);
  digitalWrite(DIRL,LOW);
  analogWrite(MPWM,0);  
  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(J5R,HIGH);
  digitalWrite(S1R,HIGH);
  digitalWrite(S2R,HIGH);
  digitalWrite(S3R,HIGH);
  digitalWrite(S5R,HIGH);

  aut1 = LOW;
  duty = 0;
  mnt = LOW;
}

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(J5R,HIGH);
    digitalWrite(S1R,HIGH);
    digitalWrite(S2R,HIGH);
    digitalWrite(S3R,HIGH);
    digitalWrite(S5R,HIGH);

  // 出発ホームと到着ホームへの信号を緑にする
    if (dswr == HIGH){
      digitalWrite(50,HIGH);
      digitalWrite(52,LOW);
      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){
      digitalWrite(52,HIGH);
      digitalWrite(50,LOW);
      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);
      }
    } else {
      digitalWrite(52,LOW);
      digitalWrite(50,LOW);
    }
    delay(20);
    return;
}

void p1tei_i(){
  if (myservo1.read()<36 ){
    myservo1.attach(11);
    myservo1.write(60,10,true);
    myservo1.detach();
  }
  return;
}

void p1han_i(){
  if (myservo1.read()>34 ){
    myservo1.attach(11);
    myservo1.write(10,10,true);
    myservo1.detach();
  }
  return;
}

void p2tei_i(){
  if (myservo2.read()>34 ){
    myservo2.attach(12);
    myservo2.write(10,10,true);
    myservo2.detach();
  }
  return;
}

void p2han_i(){
  if (myservo2.read()<36 ){
    myservo2.attach(12);
    myservo2.write(60,10,true);
    myservo2.detach();
  }
  return;
}

void mode1(int densha){
  if (analogRead(densha) < 400 ) {   //電車の設定の有無チェック
    return;                          //無の場合はこの運行をパスする
  }
  p1han_i();         //経路を設定する
  delay(500);
  p2han_i();
  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<22;i++ ) {           //走行加速開始
    duty = analogRead(densha);    //VRの値を読込む
    duty = (duty - 500) *0.025*i; 
    analogWrite(MPWM, duty);      //フィーダー出力
    delay(200);
  }
 ts2 = digitalRead(TS2);          //場内点通過チェック
  while (ts2 == HIGH ) {           //場内点通過待ち
    duty = analogRead(densha);    //VRの値を読込む
    duty = (duty - 500) * 0.55;    //通常速度
    analogWrite(MPWM, duty);      //フィーダー出力
    ts2 = digitalRead(TS2);       //場内点通過チェック
    delay(50);
  }
  eds3 = digitalRead(EDS3);       //到着チェック
  while (eds3 == HIGH ) {          //到着待ち
    duty = analogRead(densha);    //VRの値を読込む
    duty = (duty - 500) * 0.45;    //低速走行
    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;                          //無の場合はこの運行をパスする
  }
  p1han_i();         //経路を設定する
  delay(500);
  p2tei_i();
  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<20;i++ ) {           //走行加速開始
    duty = analogRead(densha);    //VRの値を読込む
    duty = (duty - 500) *0.025*i; 
    analogWrite(MPWM, duty);      //フィーダー出力
    delay(200);
  }
  eds2 = digitalRead(EDS2);       //到着チェック
  while (eds2 == HIGH ) {          //到着待ち
    duty = analogRead(densha);    //VRの値を読込む
    duty = (duty - 500) * 0.5;    //低速走行
    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;                          //無の場合はこの運行をパスする
  }
  p1tei_i();         //経路を設定する
  delay(500);
  p2tei_i();
  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<20;i++ ) {           //走行加速開始
    duty = analogRead(densha);    //VRの値を読込む
    duty = (duty - 500) *0.025*i; 
    analogWrite(MPWM, duty);      //フィーダー出力
    delay(200);
  }
  eds5 = digitalRead(EDS5);       //到着チェック
  while (eds5 == HIGH ) {          //到着待ち
    duty = analogRead(densha);    //VRの値を読込む
    duty = (duty - 500) * 0.5;    //低速走行
    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;                          //無の場合はこの運行をパスする
  }
  p1tei_i();         //経路を設定する
  delay(500);
  p2han_i();
  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<20;i++ ) {           //走行加速開始
    duty = analogRead(densha);    //VRの値を読込む
    duty = (duty - 500) *0.025*i; 
    analogWrite(MPWM, duty);      //フィーダー出力
    delay(200);
  }
  eds1 = digitalRead(EDS1);       //到着チェック
  while (eds1 == HIGH ) {          //到着待ち
    duty = analogRead(densha);    //VRの値を読込む
    duty = (duty - 500) * 0.5;    //低速走行
    analogWrite(MPWM, duty);      //フィーダー出力
    eds1 = digitalRead(EDS1);     //到着チェック
    delay(50);
  }
  delay(500);
  analogWrite(MPWM, 0);
  delay(1000);
  return;
}

void loop(){
  aut = digitalRead(AUT);            //自動運転スイッチをチェック
  mnt = digitalRead(PTS3); 
  
  if (aut==LOW){                     //手動運転モード
      if (mnt == LOW){               //パネル操作
        pts1 = digitalRead(PTS1);    //スイッチ類のチェック
        pts2 = digitalRead(PTS2);
        dswr = digitalRead(DSWR);
        dswl = digitalRead(DSWL);
        vol1 = analogRead(VOL1);
        duty=(vol1-500)/2;
      } else {                       //モニタ操作
        pts1 = digitalRead(4);       //スイッチ類のチェック
        pts2 = digitalRead(3);
        dswr = digitalRead(9);
        dswl = digitalRead(8);
        spd = analogRead(A4);
        duty = spd/2.65;
      }
    
      ledhyoji();                   //パネル表示       
      if (pts1==HIGH){              //ポイント1操作
        p1han_i();
        delay(100);
      } else {
        p1tei_i();
        delay(100);
      }
      if (pts2==HIGH){             //ポイント2操作
        p2han_i();
        delay(100);
      } else {
        p2tei_i();
        delay(100);
      }
      if (dswr==HIGH){             //進行方向右設定
        digitalWrite(DIRR,HIGH);
      }  else {
        digitalWrite(DIRR,LOW);
      }
      if (dswl==HIGH){             //進行方向左設定
        digitalWrite(DIRL,HIGH);
      } else {
        digitalWrite(DIRL,LOW);
      }
      analogWrite(MPWM,duty);      //速度指示
      
  } else if (aut==HIGH){           //自動運転モード
      analogWrite(MPWM, 0);        //暴走防止
      mode1(1);                    //denshaの運行
      mode2(2);
      mode3(0);
      mode4(1);
      mode1(2);
      mode2(0);
      mode3(1);
      mode4(2);
      mode1(0);
      mode2(1);
      mode3(2);
      mode4(0);
      aut1=LOW;                   //自動運転のシーケンス終了
  }
  delay(10);
}

 

ページトップへ戻る  .


 2022/11/10