*
/*
* Track layout:
*
* S1___Sen1_ _Sen4___S4
* \ /
* S2___Sen2__\____________Track____________/__Sen3___S3
* P_L Sen_L Sen_R P_R
*
* Pin assignments:
* ____________________________
* |Pin |Function |Input/Ouput |
* |----+----------+------------|
* |0 |Sen_L |Input |
* |1 |Sen_R |Input |
* |2 |Sen1 |Input |
* |3 |Sen2 |Input |
* |4 |Sen3 |Input |
* |5 |Sen4 |Input |
* |6 |S1 |Output |
* |7 |S2 |Output |
* |8 |S3 |Output |
* |9 |P_L |Output |
* |10 |P_R |Output |
* |11 |Track |Output |
* |12 |Direction |Output |
* |13 |S4 |Output |
* |============================|
*/
#include <Servo.h>
Servo P_L;
Servo P_R;
//define Servos
int Direction = 12; //Use DPDT non-latching relay
int Track = 11;
int S1 = 6;
int S2 = 7;
int S3 = 8;
int S4 = 13;
//Assign outputs to their pins
int Sen_L = 0;
int Sen_R = 1;
int Sen1 = 2;
int Sen2 = 3;
int Sen3 = 4;
int Sen4 = 5;
//Assign digital sensors to their pins
//Use reed switches
const unsigned int maxSpeed = 100; //Maximum speed of train
const unsigned int wait = 1000; //Duration braking/acceleration
unsigned int numRepeat = 0;
int num;
//Define variables
unsigned int pLeft = 165;
unsigned int pRight = 70;
//Point servo angle values
const unsigned int stationStopMin = 4000;
const unsigned int stationStopMax = 6000;
const unsigned int sidingStop = 5000;
//Delay constants
//Delays in milliseconds
//int cnt = 0;
void setup() {
pinMode(Direction, OUTPUT);
pinMode(Track, OUTPUT);
pinMode(S1, OUTPUT);
pinMode(S2, OUTPUT);
pinMode(S3, OUTPUT);
pinMode(S4, OUTPUT);
//Define as outputs
pinMode(Sen_L, INPUT_PULLUP);
pinMode(Sen_R, INPUT_PULLUP);
pinMode(Sen1, INPUT_PULLUP);
pinMode(Sen2, INPUT_PULLUP);
pinMode(Sen3, INPUT_PULLUP);
pinMode(Sen4, INPUT_PULLUP);
//Define as inputs with pull-up resistors enabled
P_L.attach(9);
P_R.attach(10);
//Attach servo control wires to their pins
//Serial.begin(9600);
}
int Dec(const unsigned int Max, const unsigned int dly);
int Acc(const unsigned int Max, const unsigned int dly);
void SidingSet(const unsigned int pLeft, const unsigned int pRight);
//int RepeatInc(unsigned int Repeats);
unsigned int change_pRight(unsigned int pRight);
unsigned int change_pLeft(unsigned int pLeft);
void fullSiding_R(const unsigned int pRight, const unsigned int spd);
void fullSiding_L(const unsigned int pLeft, const unsigned int spd);
//int debug(int cnt);
//Define functions
void loop() {
P_L.write(pLeft);
P_R.write(pRight);
//Set servos to default positions
SidingSet(pLeft, pRight); //Set sidings
//Perform only at first loop instance
for(;;) {
digitalWrite(Direction, LOW); //Set direction of travel (Left-Right)
analogWrite(Track, maxSpeed); //Write PWM to track of duty cycle maxSpeed
while(digitalRead(Sen_L) == 1) {
} //Wait until Sen_L is triggered
//cnt = debug(cnt);
Dec(maxSpeed, wait); //Decelerate train to stop
delay(/*random(stationStopMin, stationStopMax)*/10000); //Wait between 'x' to 'y' seconds at station
Acc(maxSpeed, wait); //Accelerate train
fullSiding_R(pRight, maxSpeed); //Wait for train to enter siding
//cnt = debug(cnt);
digitalWrite(Track, LOW); //Turn off track (stop train)
pRight = change_pRight(pRight);
SidingSet(pLeft, pRight);
delay(sidingStop); //Wait for 'x' seconds before sending out next train
Serial.println("Exit");
digitalWrite(Direction, HIGH); //Reverse direction of travel (Right-Left)
analogWrite(Track, maxSpeed); //Write PWM to track of duty cycle maxSpeed
while(digitalRead(Sen_R) == 1) {
} //Wait for Sen_R to trigger
//cnt = debug(cnt);
Dec(maxSpeed, wait); //Decelerate train to stop
delay(random(stationStopMin, stationStopMax)); //Wait between 'x' to 'y' seconds at station
Acc(maxSpeed, wait); //Accelerate train
fullSiding_L(pLeft, maxSpeed); //Wait for train to enter siding
//cnt = debug(cnt);
digitalWrite(Track, LOW); //Turn off track (stop train)
pLeft = change_pLeft(pLeft);
SidingSet(pLeft, pRight);
delay(sidingStop); //Wait for 'x' seconds before sending out next train
}
}
int Dec(const unsigned int Max, const unsigned int dly) {
for(int i = Max; i >= 0; i--) {
analogWrite(Track, i); //Set Track PWM to i duty cycle
delay((float) dly/Max); //Wait for dly milliseconds (dly/max seconds per loop
}
//digitalWrite(Track, LOW);
//loop until i < 0. Decrement i on each loop
}
int Acc(const unsigned int Max, const unsigned int dly) {
for(int i = 0; i <= Max; i++) {
analogWrite(Track, i); //Set Track PWM to i duty cycle
delay((float) dly/Max); //Wait for dly seconds (dly/max seconds per loop
}
//loop until i < 0. Increment i on each loop
}
void SidingSet(const unsigned int pLeft, const unsigned int pRight) {
if(pLeft == 165) {
digitalWrite(S2, HIGH); //Make S2 active
digitalWrite(S1, LOW); //Make S1 inactive
}
else {
digitalWrite(S2, LOW); //Make S2 inactive
digitalWrite(S1, HIGH); //Make S1 active
}
if(pRight == 70) {
digitalWrite(S3, HIGH); //Make S3 active
digitalWrite(S4, LOW); //Make S4 inactive
}
else{
digitalWrite(S3, LOW); //Make S3 inactive
digitalWrite(S4, HIGH); //Make S4 active
}
}
//int RepeatInc(unsigned int Repeats) {
// if(Repeats == 0) {
// Repeats++;
// }
//}
//Increment Repeats to 1 if it equals 0
unsigned int change_pRight(unsigned int pRight) {
int k;
int a;
//Define local variables
num = random(0,10); //Generate a random number of 0 or 1
if(num % 2) {
k = pRight;
pRight = 100;
a = 1;
}
else {
k = pRight;
pRight = 70;
a = -1;
}
// Serial.println(pRight);
//
// Serial.print("Random number: ");
// Serial.println(num);
for(;k <= pRight; k = k+a) {
P_R.write(k);
delay(50); //Wait 10 milliseconds on each loop
}
//Change point by looping until k < pRight
return pRight;
}
unsigned int change_pLeft(unsigned int pLeft) {
int k;
int a;
//Define local variables
num = random(0,10); //Generate random number of 0 or 1
if(num % 2) {
k = pLeft;
pLeft = 135;
a = -1;
}
else {
k = pLeft;
pLeft = 165;
a = 1;
}
for(;k <= pLeft; k = k+a) {
P_L.write(k);
delay(50); //Wait 10 milliseconds on each loop
}
//Change point by looping until k < pRight
return pLeft;
}
void fullSiding_R(const unsigned int pRight, const unsigned int spd) {
if(pRight == 70) {
while(digitalRead(Sen3) == 1) {
}
}
else {
while(digitalRead(Sen4) == 1) {
}
}
analogWrite(Track, (spd/2));
delay(1000);
//Wait for train to enter active siding
}
void fullSiding_L(const unsigned int pLeft, const unsigned int spd) {
if(pLeft == 165) {
while(digitalRead(Sen2) == 1) {
}
}
else {
while(digitalRead(Sen1) == 1) {
}
}
analogWrite(Track, (spd/2));
delay(1000);
//Wait for train to enter active siding
}
//int debug(int cnt) {
// Serial.print(cnt);
// delay(2000);
// Serial.println(": Triggered");
//
// cnt++;
// return cnt;
//}