Hello Group,
I have several TCRT sensors being used as track block occupancy detectors and an oval setup of track and the oval is split in two making two track occupancy blocks. Now as you can see by the code below the there are different states the block can be in: occupied or un occupied. Green being clear/un occupied and Red being occupied. There are 2 sensors per block, one for entering and one for exiting. The setup works fine in each direction. However here is where I am stuck at. If I choose to reverse the locomotive in either direction the "block" is un changed and will not clear unless the sensor has been tripped. I am having difficulty in figuring this piece of the puzzle out. Thanks in advance.
// CONSTANT VARIABLES
const int westblocksensor = A0; // BLOCK ONE
const int eastblocksensor = A1; // BLOCK ONE
const int westblocktwosensor = A2; // BLOCK TWO
const int eastblocktwosensor = A3; // BLOCK TWO
// VARIABLES THAT WILL CHANGE
int tcrtEBlockState = 0; // BLOCK ONE
int tcrtWBlockState = 0; // BLOCK ONE
int tcrtEBlockTwoState = 0; // BLOCK TWO
int tcrtWBlockTwoState = 0; // BLOCK TWO
int BLOCKONEGREEN = 11; // BLOCK ONE
int BLOCKONERED = 12; // BLOCK ONE
int BLOCKTWOGREEN = 10; // BLOCK TWO
int BLOCKTWORED = 9; // BLOCK TWO
//#define BLOCKONESTATE
//#define BLOCKLIGHTSTATES
void setup() {
// LEDS AS OUPUTS
Serial.begin(9600);
pinMode(BLOCKONEGREEN, OUTPUT); // BLOCK ONE
pinMode(BLOCKONERED, OUTPUT); // BLOCK ONE
pinMode(BLOCKTWOGREEN, OUTPUT); // BLOCK TWO
pinMode(BLOCKTWORED, OUTPUT); // BLOCK TWO
//pinMode(led, OUTPUT);
// TCRT5000 AS INPUTS
pinMode(westblocksensor, INPUT); // A0 BLOCK ONE
pinMode(eastblocksensor, INPUT); // A1 BLOCK ONE
pinMode(westblocktwosensor, INPUT); // A2 BLOCK TWO
pinMode(eastblocktwosensor, INPUT); // A3 BLOCK TWO
digitalWrite(BLOCKONEGREEN, HIGH); // DEFAULT GREEN ON
digitalWrite(BLOCKTWOGREEN, HIGH); // DEFAULT GREEN ON
} // END OF MASTER SETUP
// BLOCK LIGHT STATES
enum BLOCKLIGHTSTATES {
ST_GREEN, // GREEN
ST_GREENTWO, // GREEN TWO
ST_RED, // RED
ST_REDTWO, // RED TWO
};
enum BLOCKTWOLIGHTSTATES {
ST_GREENTHREE, // GREEN THREE
ST_GREENFOUR, // GREEN FOUR
ST_REDTHREE, // RED THREE
ST_REDFOUR, // RED FOUR
};
// STATE OF BLOCK ONE GREEN
BLOCKLIGHTSTATES BLOCKONESTATE = ST_GREEN; // BLOCK ONE
BLOCKTWOLIGHTSTATES BLOCKTWOSTATE = ST_GREENTHREE; // BLOCK TWO
// CURRENT TIME
static unsigned long currentTime;
void loop(){
// GET CURRENT TIME
currentTime = millis();
// read the state of the tcrt5000:
tcrtWBlockState = digitalRead(westblocksensor); // BLOCK ONE
tcrtEBlockState = digitalRead(eastblocksensor); // BLOCK ONE
tcrtWBlockTwoState = digitalRead(westblocktwosensor); // BLOCK TWO
tcrtEBlockTwoState = digitalRead(eastblocktwosensor); // BLOCK TWO
Serial.println(tcrtWBlockState); // BLOCK ONE
Serial.print(tcrtEBlockState); // BLOCK ONE
Serial.print(tcrtWBlockTwoState); // BLOCK TWO
Serial.print(tcrtEBlockTwoState); // BLOCK TWO
switch (BLOCKONESTATE) {
// GREEN LIGHT WILL SWITCH TO RED IF SENSORS ARE TRIGGERED
case ST_GREEN:
BLOCK1GREEN(tcrtWBlockState, tcrtEBlockState);
break;
case ST_GREENTWO:
BLOCK1GREEN1(tcrtWBlockState, tcrtEBlockState);
break;
case ST_RED:
BLOCK1RED(tcrtWBlockState, tcrtEBlockState);
break;
case ST_REDTWO:
BLOCK1RED1(tcrtWBlockState, tcrtEBlockState);
break;
}
switch (BLOCKTWOSTATE) {
// GREEN LIGHT WILL SWITCH TO RED IF SENSORS ARE TRIGGERED
case ST_GREENTHREE:
BLOCK2GREEN(tcrtWBlockTwoState, tcrtEBlockTwoState);
break;
case ST_GREENFOUR:
BLOCK2GREEN2(tcrtWBlockTwoState, tcrtEBlockTwoState);
break;
case ST_REDTHREE:
BLOCK2RED(tcrtWBlockTwoState, tcrtEBlockTwoState);
break;
case ST_REDFOUR:
BLOCK2RED2(tcrtWBlockTwoState, tcrtEBlockTwoState);
break;
}
} // END MASTER LOOP
// BLOCK ONE STATE
void BLOCK1GREEN(int tcrtWBlockState, int tcrtEBlockState){
digitalWrite(BLOCKONEGREEN, HIGH);
digitalWrite(BLOCKONERED, LOW);
if (tcrtWBlockState == LOW && tcrtEBlockState == HIGH) { // WEST TO EAST - LEFT TO RIGHT - COUNTER CLOCKWISE
// CHANGE TO RED
BLOCKONESTATE = ST_RED;
} else if (tcrtEBlockState == LOW && tcrtWBlockState == HIGH){ // EAST TO WEST - RIGHT TO LEFT - CLOCKWISE
// CHANGE TO RED
BLOCKONESTATE = ST_REDTWO;
}
} //END VOID
void BLOCK1GREEN1(int tcrtWBlockState, int tcrtEBlockState){
// DURATION RED TIMER
const unsigned long duration = 2000;
static unsigned long startTime = 0;
if (startTime == 0){
// TURN RED TIMER
digitalWrite(BLOCKONEGREEN, LOW);
digitalWrite(BLOCKONERED, HIGH);
startTime = currentTime;
// DO NOTHING
return;
}
// IF UNKNOWN SECONDS HAVE PASSED
if (currentTime - startTime >= duration){
// RESET VARIABLES START FROM ZERO
startTime = 0;
// CHANGE TO GREEN
BLOCKONESTATE = ST_GREEN;
}
} // END VOID
void BLOCK1RED(int tcrtWBlockState, int tcrtEBlockState){
digitalWrite(BLOCKONEGREEN, LOW);
digitalWrite(BLOCKONERED, HIGH);
if (tcrtWBlockState == HIGH && tcrtEBlockState == LOW){
// CHANGE TO GREEN
BLOCKONESTATE = ST_GREENTWO;
}
} // END VOID
void BLOCK1RED1(int tcrtWBlockState, int tcrtEBlockState){
digitalWrite(BLOCKONEGREEN, LOW);
digitalWrite(BLOCKONERED, HIGH);
if (tcrtWBlockState == LOW && tcrtEBlockState == HIGH){
// CHANGE TO GREEN
BLOCKONESTATE = ST_GREENTWO; // TIMER
}
} // END VOID
// BLOCK TWO STATE
void BLOCK2GREEN(int tcrtWBlockTwoState, int tcrtEBlockTwoState){
digitalWrite(BLOCKTWOGREEN, HIGH);
digitalWrite(BLOCKTWORED, LOW);
if (tcrtWBlockTwoState == LOW && tcrtEBlockTwoState == HIGH){
// CHANGE TO RED
BLOCKTWOSTATE = ST_REDTHREE;
} else if (tcrtEBlockTwoState == LOW && tcrtWBlockTwoState == HIGH){
// CHANGE TO RED
BLOCKTWOSTATE = ST_REDFOUR;
}
}
void BLOCK2GREEN2(int tcrtWBlockTwoState, int tcrtEBlockTwoState){
// DURATION RED TIMER
const unsigned long duration = 2000;
// START TIME
static unsigned long startTime = 0;
if (startTime == 0){
// TURN RED TIMER
digitalWrite(BLOCKTWOGREEN, LOW);
digitalWrite(BLOCKTWORED, HIGH);
// START TIMER
startTime = currentTime;
// DO NOTHING
return;
}
// IF UNKNOWN SECONDS HAVE PASSED
if (currentTime - startTime >= duration){
// RESET VARIABLES START FROM ZERO
startTime = 0;
// CHANGE TO GREEN
BLOCKTWOSTATE = ST_GREENTHREE;
}
}
void BLOCK2RED(int tcrtWBlockTwoState, int tcrtEBlockTwoState){
digitalWrite(BLOCKTWOGREEN, LOW);
digitalWrite(BLOCKTWORED, HIGH);
if (tcrtWBlockTwoState == HIGH && tcrtEBlockTwoState == LOW){
// CHANGE TO GREEN
BLOCKTWOSTATE = ST_GREENFOUR;
}
}
void BLOCK2RED2(int tcrtWBlockTwoState, int tcrtEBlockTwoState){
digitalWrite(BLOCKTWOGREEN, LOW);
digitalWrite(BLOCKTWORED, HIGH);
if (tcrtWBlockTwoState == LOW && tcrtEBlockTwoState == HIGH){
// CHANGE TO GREEN
BLOCKTWOSTATE = ST_GREENFOUR;
}
}