Maker Faire Kyoto 2023で展示したシステムのプログラム
先日、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());
}
}