/*
Forum: https://forum.arduino.cc/t/changing-led-state-with-ir-sensors/1434325/2
Wokwi: https://wokwi.com/projects/457939146850369537
Simple Signal Light
starts with green signal
press red button (train enters block)
signal switches to red
press green button (train starts leaving block)
release green button (train hast completely left block)
signal switches to green again
ec2021
*/
constexpr byte redPin {12};
constexpr byte greenPin {11};
constexpr byte blockInPin {7};
constexpr byte blockOutPin {6};
enum class BLOCK {FREE, OCCUPIED};
BLOCK blockState = BLOCK::FREE;
class blockSensor {
private:
byte pin;
byte state = HIGH;
byte lastState = HIGH;
unsigned long lastChange = 0;
boolean changed() {
byte actState = digitalRead(pin);
if (actState != lastState) {
lastChange = millis();
lastState = actState;
}
if (actState != state && millis() - lastChange > 30) {
state = actState;
return true;
}
return false;
};
public:
void init(byte Pin) {
pin = Pin;
pinMode(pin, INPUT_PULLUP);
};
boolean pressed() {
if (changed()) {
return !state;
} else {
return false;
}
};
boolean released() {
if (changed()) {
return state;
} else {
return false;
}
};
};
blockSensor blockIn, blockOut;
void setup() {
Serial.begin(115200);
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
blockIn.init(blockInPin);
blockOut.init(blockOutPin);
signalToGreen();
Serial.println("Start");
}
void loop() {
stateMachine();
}
void signalToRed() {
digitalWrite(redPin, HIGH);
digitalWrite(greenPin, LOW);
}
void signalToGreen() {
digitalWrite(redPin, LOW);
digitalWrite(greenPin, HIGH);
}
void stateMachine() {
switch (blockState) {
case BLOCK::FREE:
if (blockIn.pressed()) {
Serial.println("Train entered block ...");
signalToRed();
blockState = BLOCK::OCCUPIED;
}
break;
case BLOCK::OCCUPIED:
if (blockOut.released()) {
Serial.println("Train left block ...");
signalToGreen();
blockState = BLOCK::FREE;
}
break;
}
}