Maker Faire Kyoto 2023で展示したシステムのプログラム

14May - by Joe-90 - 0 - In 未分類

先日、Maker Faire Kyoto 2023に出展する際、8bitマイコンがうまく動作せず、急遽、4台のArduinoを用いて動作を再現することになりました。

再現する主な動作は、以下の7つです。

・ホールICセンサーの読み取り
・方向の制御
・速度の制御
・操作ボタンの読み取り
・行き先指定ボタンの読み取り
・ポイントの制御
・踏切の制御

今までLegacy8080でできていた大量のピンの同時制御はArduinoにはできないため、4つのArduinoをUARTと呼ばれるシリアル通信で接続して動作の再現を試みました。

//20230429-Realy_ohuku-v2

char buff[255];
int pin =2 ;
int counter =0;
int stoptime = 1000;  //変数定義
int cmp;
int stop=0;
int speed=2;

void setup() {
	pinMode(2, OUTPUT);
	pinMode(3, OUTPUT);
	pinMode(4, OUTPUT);
	pinMode(5, OUTPUT);
	pinMode(6, OUTPUT);
	pinMode(7, OUTPUT);
	pinMode(8, OUTPUT);
	pinMode(9, OUTPUT);
	pinMode(10, OUTPUT);
	pinMode(11, OUTPUT);
	pinMode(12, OUTPUT);
	pinMode(13, OUTPUT);
	
	Serial.begin(9600);
	//while (!Serial);

  for(int r = 2; r<=9; r++){
    digitalWrite(r, LOW);
  }
  digitalWrite(speed, HIGH);

}

void loop() {
  while(Serial.available()){
    char inChar = char(Serial.read());
    buff[counter] = inChar;
    counter++;  
    if (inChar == '\0'){
      Serial.println(buff);

      cmp = "10000012";
      if(strcmp(buff, cmp)==0){
        Serial.println("Hole-No 12 was read.");
        Serial.write(cmp);
        digitalWrite(11, HIGH);
        digitalWrite(10, HIGH);
        if(stop>=1){
          digitalWrite(speed, LOW);
          delay(50);
          stop = 2;
        }
      }
      cmp = "10000011";
      if(strcmp(buff, cmp)==0){
        Serial.println("Hole-No 11 was read.");
        Serial.write(cmp);
        digitalWrite(11, LOW);
        digitalWrite(10, LOW);
        if(stop=2){
          stop=0;
        }
      }

      cmp = "10000007";
      if(strcmp(buff, cmp)==0){
        Serial.println("Hole-No 07 was read.");
        Serial.write(cmp);
        digitalWrite(speed, HIGH);
        digitalWrite(11, HIGH);
        digitalWrite(10, HIGH);
        stop=0;
      }
      cmp = "10000006";
      if(strcmp(buff, cmp)==0){
        Serial.println("Hole-No 06 was read.");
        Serial.write(cmp);
        digitalWrite(11, LOW);
        digitalWrite(10, LOW);
        stop = 1;
        cmp = " ";
      }

      cmp = "10000004";
      if(strcmp(buff, cmp)==0){
        Serial.println("Hole-No 04 was read.");
        Serial.write(cmp);
        digitalWrite(speed, LOW);
        if(stop=2){
          stop=0;
        }
      }
      //--------------------------------------------------
      cmp = "11000007";
      if(strcmp(buff, cmp)==0){
        Serial.println("Dial-No 07");
        Serial.write(cmp);
        digitalWrite(speed, HIGH);
        speed = 9;
        digitalWrite(speed, LOW);
      }
      cmp = "11000006";
      if(strcmp(buff, cmp)==0){
        Serial.println("Dial-No 06");
        Serial.write(cmp);
        digitalWrite(speed, HIGH);
        speed = 7;
        digitalWrite(speed, LOW);
      }
      cmp = "11000005";
      if(strcmp(buff, cmp)==0){
        Serial.println("Dial-No 05");
        Serial.write(cmp);
        digitalWrite(speed, HIGH);
        speed = 5;
        digitalWrite(speed, LOW);
      }
      cmp = "11000004";
      if(strcmp(buff, cmp)==0){
        Serial.println("Dial-No 04");
        Serial.write(cmp);
        digitalWrite(speed, HIGH);
        speed = 3;
        digitalWrite(speed, LOW);
      }
      cmp = "11000003";
      if(strcmp(buff, cmp)==0){
        Serial.println("Dial-No 03");
        Serial.write(cmp);
        digitalWrite(speed, HIGH);
        speed = 2;
        digitalWrite(speed, LOW);
      }

      counter = 0;

    }
  }
}

上のプログラムは、HOPE-2020システムの速度・方向制御に相当する部分のプログラムです。ほとんどはホールICの読み取りを行っているArduinoとダイヤルを読み取っているArduinoからの信号を読み取り、動作を行います。

//20230428-Arduino-HoleIC-v3

int pin = 0;
int HoleNo = 0;
int stoptime = 500;  //変数定義
String sendstr = "No Data";

void setup() {
  pinMode(13, OUTPUT);
  pinMode(12, INPUT);
  pinMode(11, INPUT);
  pinMode(10, INPUT);
  pinMode(9, INPUT);
  pinMode(8, INPUT);
  pinMode(7, INPUT);
  pinMode(6, INPUT);
  pinMode(5, INPUT);
  pinMode(4, INPUT);
  pinMode(2, OUTPUT);

  Serial.begin(9600);
}

void loop() {
  delay(5);
  //HoleIC
  //--------------------------------------------------
  pin = 12;
  if(digitalRead(pin)){
    HoleNo = pin;
  }
  pin = 11;
  if(digitalRead(pin)){
    HoleNo = pin;
  }
  pin = 10;
  if(digitalRead(pin)){
    HoleNo = pin;
  }
  pin = 9;
  if(digitalRead(pin)){
    HoleNo = pin;
  }
  pin = 8;
  if(digitalRead(pin)){
    HoleNo = pin;
  }
  //Control-Button
  //--------------------------------------------------
  pin = 7;
  if(!digitalRead(pin)){
    HoleNo = pin;
  }
  pin = 6;
  if(!digitalRead(pin)){
    HoleNo = pin;
  }
  /*pin = 5;
  if(!digitalRead(pin)){
    HoleNo = pin;
  }*/
  pin = 4;
  if(!digitalRead(pin)){
    HoleNo = pin;
  }

  if(HoleNo!=0){
    sendstr = 10000000 + HoleNo;  //10000000はHoleICからの信号として認識する
    digitalWrite(2, HIGH);
    delay(100);
    for (int i = 0; i < sendstr.length(); i++){
      Serial.write(sendstr.charAt(i));           //charAt(i)...文字列のi文字目をとる
    }
    digitalWrite(13, HIGH);
    digitalWrite(2, HIGH);
	  delay(50);
	  digitalWrite(13, LOW);
    digitalWrite(2, LOW);
    Serial.write(0);
    HoleNo = 0;
  }

}

上のプログラムは、ホールICからの入力と、操作パネルからの入力を読み取り、速度変更を行っているArduinoに送信するシステムです。シリアル通信のため、同時に信号を発信すると混乱するので、2番ピンを使って、発進時にもう一つが発信することのないようにしています。

//20230428-Arduino-StationButton_Dial-v1

int pin = 0;
int sendDial =0;
int CtrlSwitch = 0;
int stoptime = 500;  //変数定義
String sendstr = "No Data";
int signalinput = 0;

void setup() {
  pinMode(13, OUTPUT);
  //StationButton
	pinMode(12, INPUT);
  pinMode(11, INPUT);
  pinMode(10, INPUT);
  pinMode(9, INPUT);
  pinMode(8, INPUT);
  //Dial(Dialは常時オンなので後に読み込む)
  pinMode(7, INPUT);
  pinMode(6, INPUT);
  pinMode(5, INPUT);
  pinMode(4, INPUT);
  pinMode(3, INPUT);
  pinMode(2, INPUT);

	Serial.begin(9600);

}

void loop() {
	delay(5);

  if(digitalRead(2)){
    signalinput = 1;
    digitalWrite(13, HIGH);
	  delay(50);
	  digitalWrite(13, LOW);
  }else{
    signalinput = 0;
  }
  //--------------------------------------------------
  //StationButton
  pin = 12;
  if(digitalRead(pin)){
    CtrlSwitch = pin;
  }

  pin = 11;
  if(digitalRead(pin)){
    CtrlSwitch = pin;
  }

  pin = 10;
  if(digitalRead(pin)){
    CtrlSwitch = pin;
  }

  pin = 9;
  if(digitalRead(pin)){
    CtrlSwitch = pin;
  }

  pin = 8;
  if(digitalRead(pin)){
    CtrlSwitch = pin;
  }

  //--------------------------------------------------
  //Dial
  pin = 7;
  if(digitalRead(pin)){
    CtrlSwitch = pin;
    sendDial = pin;
  }

  pin = 6;
  if(digitalRead(pin)){
    CtrlSwitch = pin;
    sendDial = pin;
  }

  pin = 5;
  if(digitalRead(pin)){
    CtrlSwitch = pin;
    sendDial = pin;
  }

  pin = 4;
  if(digitalRead(pin)){
    CtrlSwitch = pin;
    sendDial = pin;
  }

  pin = 3;
  if(digitalRead(pin)){
    CtrlSwitch = pin;
    sendDial = pin;
  }

  //--------------------------------------------------
  if(!digitalRead(2)){
    if(CtrlSwitch!=0){
      sendstr = 11000000 + CtrlSwitch;  //11000000はStationButton,Dialからの信号として認識する
      for (int i = 0; i < sendstr.length(); i++){
        Serial.write(sendstr.charAt(i));           //charAt(i)...文字列のi文字目をとる
      }
      digitalWrite(13, HIGH);
	    delay(250);
	    digitalWrite(13, LOW);
      Serial.write(0);
      CtrlSwitch = 0;
    }
  }
}

行先決定ボタンとダイヤルからの信号を受け取り、全体統括を行うArduinoに送信するプログラムです。出力信号が混信しないように、2番ピンを使って連携させています。

//20230429_Arduino_Main_v2

char buff[255];
int counter = 0;
int LED = 13;
int cmp;

void setup(){
  Serial.begin(9600);
  pinMode(LED, OUTPUT);
  Serial.println("Start reading.");
}

void loop(){
  while(Serial.available()){
    char inChar = char(Serial.read());
    buff[counter] = inChar;
    counter++;  
    if (inChar == '\0'){ 
      Serial.println(buff);
      digitalWrite(LED, HIGH);
      
      //--------------------------------------------------
      //HoleIC
      cmp = "10000012";
      if(strcmp(buff, cmp)==0){
        Serial.println("Hole-No 12 was read.");
      }
      cmp = "10000011";
      if(strcmp(buff, cmp)==0){
        Serial.println("Hole-No 11 was read.");
      }
      cmp = "10000010";
      if(strcmp(buff, cmp)==0){
        Serial.println("Hole-No 10 was read.");
      }
      cmp = "10000009";
      if(strcmp(buff, cmp)==0){
        Serial.println("Hole-No 09 was read.");
      }
      cmp = "10000008";
      if(strcmp(buff, cmp)==0){
        Serial.println("Hole-No 08 was read.");
      }

      //--------------------------------------------------
      //CtrlButton
      cmp = "10000007";
      if(strcmp(buff, cmp)==0){
        Serial.println("Control-Button-No 07 was read.");
      }
      cmp = "10000006";
      if(strcmp(buff, cmp)==0){
        Serial.println("Control-Button-No 06 was read.");
      }
      cmp = "10000005";
      if(strcmp(buff, cmp)==0){
        Serial.println("Control-Button-No 05 was read.");
      }

      //--------------------------------------------------
      //StationButton
      cmp = "11000012";
      if(strcmp(buff, cmp)==0){
        Serial.println("Button-No 12 was read.");
      }
      cmp = "11000011";
      if(strcmp(buff, cmp)==0){
        Serial.println("Button-No 11 was read.");
      }
      cmp = "11000010";
      if(strcmp(buff, cmp)==0){
        Serial.println("Button-No 10 was read.");
      }
      cmp = "11000009";
      if(strcmp(buff, cmp)==0){
        Serial.println("Button-No 09 was read.");
      }
      cmp = "11000008";
      if(strcmp(buff, cmp)==0){
        Serial.println("Button-No 08 was read.");
      }

      //--------------------------------------------------
      //Dial
      cmp = "11000007";
      if(strcmp(buff, cmp)==0){
        Serial.println("Dial-No 07 was read.");
      }
      cmp = "11000006";
      if(strcmp(buff, cmp)==0){
        Serial.println("Dial-No 06 was read.");
      }
      cmp = "11000005";
      if(strcmp(buff, cmp)==0){
        Serial.println("Dial-No 05 was read.");
      }
      cmp = "11000004";
      if(strcmp(buff, cmp)==0){
        Serial.println("Dial-No 04 was read.");
      }
      cmp = "11000003";
      if(strcmp(buff, cmp)==0){
        Serial.println("Dial-No 03 was read.");
      }
      //--------------------------------------------------
      counter = 0;

    }else{
      digitalWrite(LED, LOW);
    }
    
    Serial.write(Serial.read());
  }
}