Need help with model railway sensors to stop trains crashing

Hello,

I am writing a program for two HO scale locomotives that follow eachother on a single loop of track. I’ve placed photo cells on the track to keep the engines apart. If one engine gets too close to the other engine, I plan on stopping it at a photo cell. Each locomotive is pulling a flatcar with an Arduino and a motor shield. The Arduino Uno communicates with an Arduino Mini via xbees. I am still relatively new to programming. I will be downloading this program to an Arduino Mini.

If there is anyway I can simplify this please let me know.

Explanation of Coding:

The idea of the coding is to read a value from a photo cell using the readmux(command). Because I have a total of 11 photo cells, I decided to use a multiplexer chip to reduce 11 analog inputs into one. I have four digital output pins that control which channel to select and read from. I am using an array to call upon the separate channels of the mux.

If the value of say photo cell A1 is less than the value assigned to A1max (train present), than I go through a while loop and jump down to compare(). I tell the program to take a reading from the next photo cell up the line(track). In this example, it would be A2. If A2 has a train present (value <A2max) the program sends an ASII character using the serial.print command to the Arduino Uno to shut the motor off… Other wise, it tells the train to keep moving.

After it is finished going through the while loop, it goes back to the top and waits until one of the other while statements are satisfied.

Please note:

A min value indicates when a train is present over a photo cell.

A max value indicates when a train is not present.

Whenever I try to build the program, I get the error “a function-definition is not allowed here before ‘{’ token.” This is located at the beginnign of my void compare statement.

I know there is probably quite a few errors in this program. I am still a newbie at this.

int s0=6;
int s1=7;
int s2=8;
int s3=9;
int analogA0=A0;

int A1min=594;
int A1max=949;
int A2min=690;
int A2max=940;
int A3min=412;
int A3max=899;
int A4min=648;
int A4max=927;
int A5min=700;
int A5max=840;

int A6min=278;
int A6max=676;
int A7min=686;
int A7max=942;
int A8min=743;
int A8max=957;
int A9min=734;
int A9max=964;
int A10min=523;
int A10max=911;
int A11min=521;
int A11max=988;



void setup() {
  Serial.begin(9600);//baud rate required by serial motor driver
  pinMode(s0, OUTPUT);
  pinMode(s1, OUTPUT);
  
  pinMode(s2, OUTPUT);
  
  pinMode(s3, OUTPUT);
  
  pinMode(analogA0=0, INPUT);
  
  digitalWrite(s0, LOW);
  digitalWrite(s1, LOW);
  digitalWrite(s2, LOW);
  digitalWrite(s3, LOW);
  
 
 
  
  
}
 
 void loop(){
   int val0 = readMux(0);//read value of sensor 0
  
   while (val0 < A1max){ //when train is passing over sensor A0, branch to compare to next sensor
     compare();
   }
   int val1= readMux(1);
   
    while (val1 < A2max){ //when train is passing over sensor A1, branch to compare to next sensor
     compare2();
   }
   int val2=readMux(2);
   
   while (val2 < A3max){ //when train is passing over sensor A2, branch to compare to next sensor
     compare3();
   }
   
   int val3=readMux(3);
   
     while (val3 < A4max){ //when train is passing over sensor A3, branch to compare to next sensor
     compare4();
   }
   
   int val4=readMux(4);
   
     while (val4 < A5max){ //when train is passing over sensor A4, branch to compare to next sensor
     compare5();
   }
   int val5=readMux(5);
   
     while (val5 < A6max){ //when train is passing over sensor A5, branch to compare to next sensor
     compare6();
   }
   
   int val6=readMux(6);
   
    while (val6 < A7max){ //when train is passing over sensor A6, branch to compare to next sensor
     compare7();
   }
   
   int val7=readMux(7);
   
    while (val7 < A8max){ //when train is passing over sensor A7, branch to compare to next sensor
     compare8();
   }
   
    int val8=readMux(8);
   
    while (val8 < A9max){ //when train is passing over sensor A8, branch to compare to next sensor
     compare9();
    }
    int val9=readMux(9);
   
    while (val9 < A10max){ //when train is passing over sensor A8, branch to compare to next sensor
     compare10();
    }
    int val10=readMux(10);
   
    while (val10 < A11max){ //when train is passing over sensor A8, branch to compare to next sensor
     compare11();
    }
       
   
   
     
     
   
   
     
 void compare() {
  int val1=readMux(1);//read sensor 1
  if (val1 < A2max && val0 < A1max){//if sensor 1 and 0 are high, stop train
    Serial.write('a');
    
  }
  if else(val1=A2max && val0 <A1max){//if sensor 1 is low and sensor 0 is high, run train
    Serial.write('b');
  }
}

void compare2 (){
  int val2=readMux(2);//read sensor 2
  if (val2 < A3max && val1 < A2max){//if sensor 2 and 1 are high, stop train
    Serial.write('a');
  }
  if else(val2=A3max && val1 <A1max){//if sensor 2 is low and sensor 1 is high, run train
    Serial.write('b');
  }
}

void compare3 (){
  int val3=readMux(3);//read sensor 3
  if (val3 < A4max && val2 < A3max){//if sensor 3 and 2 are high, stop train
   Serial.write('a');
  }
  if else(val3=A4max && val2 <A3max){//if sensor 3 is low and sensor 2 is high, run train
    Serial.write('b');
  }
}
    
void compare4 (){
  int val4=readMux(4);//read sensor 4
  if (val4 < A5max && val3 < A4max){//if sensor 4 and 3 are high, stop train
    Serial.write('a');
  }
  if else(val4=A5max && val3 <A4max){//if sensor 4 is low and sensor 3 is high, run train
    
    Serial.write('b'):
    )
    
  }
}    

void compare5 (){
  int val5=readMux(5);//read sensor 5
  if (val5 < A6max && val4 <A5max){//if sensor 5 and 4 are high, stop train
    Serial.write('a');
  }
  if else(val5=A6max && val4 <A5max){//if sensor 5 is low and sensor 4 is high, run train
    Serial.write('b');
  }
}    

void compare6 (){
  int val6=readMux(6);//read sensor 6
  if (val6 < A7max && val5 < A6max){//if sensor 6 and 05are high, stop train
    Serial.write('a');
  }
  if else(val6=A7max && val5 <A6max){//if sensor 6 is low and sensor 5 is high, run train
   Serial.write('b');
   }
}    

void compare7 (){
  int val7=readMux(7);//read sensor 7
  if (val7 < A8max && val6 < A7max){//if sensor 7 and 6 are high, stop train
    Serial.write('a');
  }
  if else(val7=A8max && val6 <A7max){//if sensor 7 is low and sensor 6 is high, run train
    Serial.write('b');
  }
}    
  
void compare8 (){
  int val8=readMux(8);//read sensor 8
  if (val8 < A9max && val7 < A8max){//if sensor 8 and 7 are high, stop train
  Serial.write('a');

  }
  if else(val8=A9max && val7 <A8max){//if sensor 8 is low and sensor 7 is high, run train
  Serial.write('b');
  }
}    

void compare9 (){
  int val9=readMux(9);//read sensor 9
  if (va9 < A10max && val8 < A9max){//if sensor  and 0 are high, stop train
  Serial.write('a');
  }
  if else(va9=A10max && val8 <A9max{//if sensor 1 is low and sensor 0 is high, run train
    Serial.write('b');
  }
} 

void compare10 (){
  int val0=readMux(10);//read sensor 9
  if (val0 < A11max && val9 < A10max){//if sensor  and 0 are high, stop train
  Serial.write('a');
  }
  if else(val0=A11max && val9 <A10max){//if sensor 1 is low and sensor 0 is high, run train
    Serial.write('b');
  }
} 
  
void compare11 (){
  int va0=readMux(0);//read sensor 9
  if (va0 < A1max && val10 < A11max){//if sensor  and 0 are high, stop train
  Serial.write('a');
  }
  if else(val0=A1max && val10 <A11max){//if sensor 1 is low and sensor 0 is high, run train
    Serial.write('b');
  }
} 
  
int readMux(int channel){
 
 
 
int controlpin []={s0,s1,s2,s3}

int muxChannel[16][controlpin]={//mux breakout board array
    {0,0,0,0}, //sensor 0
    {1,0,0,0}, //sensor 1
    {0,1,0,0}, //sensor 2
    {1,1,0,0}, //sensor 3
    {0,0,1,0}, //sensor 4
    {1,0,1,0}, //sensor 5
    {0,1,1,0}, //sensor 6
    {1,1,1,0}, //sensor 7
    {0,0,0,1}, //sensor 8
    {1,0,0,1}, //sensor 9
    {0,1,0,1}, //sensor 10
    {1,1,0,1}, //sensor 11
    {0,0,1,1}, //sensor 12
    {1,0,1,1}, //sensor 13
    {0,1,1,1}, //sensor 14
    {1,1,1,1}  //sensof 15
  };
 for(int i = 0; i  < 4; i ++){//cycle through each of the four pins a0,a1,a2,a3
    digitalWrite(controlPin[i], muxChannel[channel][i]);
    int val=analogRead(analogA0);
  }
}

Leave your functions outside of loop(). You forgot the closing brace. The error says you cannot have a function defined within loop()

    int val1= readMux(1);

while (val1 < A2max){ //when train is passing over sensor A1, branch to compare to next sensor
    compare2();
  }

void compare2 (){
 int val2=readMux(2);//read sensor 2
 if (val2 < A3max && val1 < A2max){//if sensor 2 and 1 are high, stop train
   Serial.write(‘a’);
 }
 if else(val2=A3max && val1 <A1max){//if sensor 2 is low and sensor 1 is high, run train
   Serial.write(‘b’);
 }
}

You have at least two problems here. First is that this:

while (val1 < A2max){ //when train is passing over sensor A1, branch to compare to next sensor
     compare2();
   }

… will never exit, because compare2 does not change val1.

The second is that even if it did, the way you are writing it val1 is local to loop. In other words, the “val2” inside compare2, is a different “val2” to the one inside loop.

You need to move val1, val2 etc. from outside both functions to be global variables.

You might want to amend your original post and change the subject line. This is the programming section of the forum, so of course it is a programming question, and of course you need help. Maybe something like "Need help with model railway sensors to stop trains crashing".

Leave your functions outside of loop(). You forgot the closing brace. The error says you cannot have a function defined within loop()

Okay, I brought all of my functions outside of my loop.

You need to move val1, val2 etc. from outside both functions to be global variables.

I defined all my values at the beginning of the coding, will this work?

… will never exit, because compare2 does not change val1.

How can I tweak the code so I can exit one while loop and proceed to the next

I do have one new error.

"size of array ‘mux channel’ has non-intergral type int[4]’

int s0=6;
int s1=7;
int s2=8;
int s3=9;
int analogA0=A0;

int A1min=594;
int A1max=949;
int A2min=690;
int A2max=940;
int A3min=412;
int A3max=899;
int A4min=648;
int A4max=927;
int A5min=700;
int A5max=840;

int A6min=278;
int A6max=676;
int A7min=686;
int A7max=942;
int A8min=743;
int A8max=957;
int A9min=734;
int A9max=964;
int A10min=523;
int A10max=911;
int A11min=521;
int A11max=988;


int val0= readMux(0);
int val1= readMux(1);
int val2=readMux(2);
int val3=readMux(3);
int val4=readMux(4);
int val5=readMux(5);
int val6=readMux(6);
int val7=readMux(7);
int val8=readMux(8);
int val9=readMux(9);
int val10=readMux(10);

void setup() {
  Serial.begin(9600);//baud rate required by serial motor driver
  pinMode(s0, OUTPUT);
  pinMode(s1, OUTPUT);
  
  pinMode(s2, OUTPUT);
  
  pinMode(s3, OUTPUT);
  
  pinMode(analogA0=0, INPUT);
  
  digitalWrite(s0, LOW);
  digitalWrite(s1, LOW);
  digitalWrite(s2, LOW);
  digitalWrite(s3, LOW);
  
 
 
  
  
}
 
 void loop(){
   //read value of sensor 0
  
   while (val0 < A1max){ //when train is passing over sensor A0, branch to compare to next sensor
     compare();
   }
   
   
    while (val1 < A2max){ //when train is passing over sensor A1, branch to compare to next sensor
     compare2();
   }
   
   
   while (val2 < A3max){ //when train is passing over sensor A2, branch to compare to next sensor
     compare3();
   }
   

   
     while (val3 < A4max){ //when train is passing over sensor A3, branch to compare to next sensor
     compare4();
   }
   
  
   
     while (val4 < A5max){ //when train is passing over sensor A4, branch to compare to next sensor
     compare5();
   }
  
   
     while (val5 < A6max){ //when train is passing over sensor A5, branch to compare to next sensor
     compare6();
   }
   
  
   
    while (val6 < A7max){ //when train is passing over sensor A6, branch to compare to next sensor
     compare7();
   }
   
  
   
    while (val7 < A8max){ //when train is passing over sensor A7, branch to compare to next sensor
     compare8();
   }
   
    
   
    while (val8 < A9max){ //when train is passing over sensor A8, branch to compare to next sensor
     compare9();
    }
    
   
    while (val9 < A10max){ //when train is passing over sensor A8, branch to compare to next sensor
     compare10();
    }
    
   
    while (val10 < A11max){ //when train is passing over sensor A8, branch to compare to next sensor
     compare11();
    }
 }
       
   
   
     
     
   
   
     
 
  
int readMux(int channel){
 
 
 
int controlpin []={s0,s1,s2,s3};

int muxChannel[16][controlpin]={//mux breakout board array
    {0,0,0,0}, //sensor 0
    {1,0,0,0}, //sensor 1
    {0,1,0,0}, //sensor 2
    {1,1,0,0}, //sensor 3
    {0,0,1,0}, //sensor 4
    {1,0,1,0}, //sensor 5
    {0,1,1,0}, //sensor 6
    {1,1,1,0}, //sensor 7
    {0,0,0,1}, //sensor 8
    {1,0,0,1}, //sensor 9
    {0,1,0,1}, //sensor 10
    {1,1,0,1}, //sensor 11
    {0,0,1,1}, //sensor 12
    {1,0,1,1}, //sensor 13
    {0,1,1,1}, //sensor 14
    {1,1,1,1}  //sensof 15
  };
 for(int i = 0; i  < 4; i ++){//cycle through each of the four pins a0,a1,a2,a3
    digitalWrite(controlPin[i], muxChannel[channel][i]);
    int val=analogRead(analogA0);
  }
}
  
  
void compare() {
 
  if (val1 < A2max && val0 < A1max){//if sensor 1 and 0 are high, stop train
    Serial.write('a');
    
  }
  if else(val1=A2max && val0 <A1max){//if sensor 1 is low and sensor 0 is high, run train
    Serial.write('b');
  }
}

void compare2 (){
  
  if (val2 < A3max && val1 < A2max){//if sensor 2 and 1 are high, stop train
    Serial.write('a');
  }
  if else(val2=A3max && val1 <A1max){//if sensor 2 is low and sensor 1 is high, run train
    Serial.write('b');
  }
}

void compare3 (){
 
  if (val3 < A4max && val2 < A3max){//if sensor 3 and 2 are high, stop train
   Serial.write('a');
  }
  if else(val3=A4max && val2 <A3max){//if sensor 3 is low and sensor 2 is high, run train
    Serial.write('b');
  }
}
    
void compare4 (){
  
  if (val4 < A5max && val3 < A4max){//if sensor 4 and 3 are high, stop train
    Serial.write('a');
  }
  if else(val4=A5max && val3 <A4max){//if sensor 4 is low and sensor 3 is high, run train
    
    Serial.write('b'):
    )
    
  }
}    

void compare5 (){
  
  if (val5 < A6max && val4 <A5max){//if sensor 5 and 4 are high, stop train
    Serial.write('a');
  }
  if else(val5=A6max && val4 <A5max){//if sensor 5 is low and sensor 4 is high, run train
    Serial.write('b');
  }
}    

void compare6 (){

  if (val6 < A7max && val5 < A6max){//if sensor 6 and 05are high, stop train
    Serial.write('a');
  }
  if else(val6=A7max && val5 <A6max){//if sensor 6 is low and sensor 5 is high, run train
   Serial.write('b');
   }
}    

void compare7 (){

  if (val7 < A8max && val6 < A7max){//if sensor 7 and 6 are high, stop train
    Serial.write('a');
  }
  if else(val7=A8max && val6 <A7max){//if sensor 7 is low and sensor 6 is high, run train
    Serial.write('b');
  }
}    
  
void compare8 (){
  
  if (val8 < A9max && val7 < A8max){//if sensor 8 and 7 are high, stop train
  Serial.write('a');

  }
  if else(val8=A9max && val7 <A8max){//if sensor 8 is low and sensor 7 is high, run train
  Serial.write('b');
  }
}    

void compare9 (){

  if (va9 < A10max && val8 < A9max){//if sensor  and 0 are high, stop train
  Serial.write('a');
  }
  if else(va9=A10max && val8 <A9max{//if sensor 1 is low and sensor 0 is high, run train
    Serial.write('b');
  }
} 

void compare10 (){
  
  if (val0 < A11max && val9 < A10max){//if sensor  and 0 are high, stop train
  Serial.write('a');
  }
  if else(val0=A11max && val9 <A10max){//if sensor 1 is low and sensor 0 is high, run train
    Serial.write('b');
  }
} 
  
void compare11 (){

  if (va0 < A1max && val10 < A11max){//if sensor  and 0 are high, stop train
  Serial.write('a');
  }
  if else(val0=A1max && val10 <A11max){//if sensor 1 is low and sensor 0 is high, run train
    Serial.write('b');
  }
}

How can I tweak the code so I can exit one while loop and proceed to the next

Change the condition so it might be met.

The error “size of array ‘mux channel’ has non-intergral type int[4]’” is caused by this…

int controlpin []={s0,s1,s2,s3};

int muxChannel[16][controlpin]={//mux breakout board array

You can’t define an array dimension with another array.

Just out of interest, would it not be better to place sensors on the engines, possibly ultrasonic, and have the train's local arduino slow it down as necessary?

You still have the fundamental issue Nick referred to in reply #2. This is a problem:

   while (val0 < A1max){ //when train is passing over sensor A0, branch to compare to next sensor
     compare();
   }

When the program starts, you read all your sensors once, but you never read them again. From the comment, you’re expecting that val0 will change when the train moves away from sensor A0. It won’t; you have to explicitly read it again with another val0= readMux(0).

Another thing to think about is that whenever you find yourself copy pasting routines to make similar ones (your family of compare routines), it’s a sign that things are not as they should be. You should be able to create a single version that takes several parameters, in the same way that you’ve coded readMux to take one. It also means that when you find the issues in compare, you only have to fix them once.

pinMode(analogA0=0, INPUT);

Unusual construct, and an excellent illustration of why constants should be qualified as "const".

I know there is probably quite a few errors in this program. I am still a newbie at this.

Given this, consider trying to build up to the full version in smaller parts. Perhaps start with detecting when a train passes over one particular sensor, then work up to detecting all of them, preferably using arrays to hold your min & max constants. Big Bang debugging is painful, incremental development can make things easier.