const byte IR_Pin = 2; //Pin2 as IR sense pin.
const byte LEDpin = 13; //Pin13 as Output pin.
const byte heartBeatLED_Pin = 12;
// self-explaining names that represent numbers (internally)
enum myStates {
waiting_for_detection,
detected_led_on,
detected_led_off,
no_detection_wait
} myStateVar; // variable with name "myStateVar" used for the logic of the state-machine
unsigned long myTimer = 0; // Timer-variables MUST be of type unsigned long
const unsigned long LED_OnTime = 5000;
const unsigned long noObstacleWaitTime = 1000;
void setup() {
Serial.begin(115200);
Serial.println( F("Setup-Start") );
PrintFileNameDateTime(); // execute lines of code inside function "void PrintFileNameDateTime() {"
pinMode(IR_Pin, INPUT);
pinMode(LEDpin, OUTPUT);
pinMode(heartBeatLED_Pin, OUTPUT);
myStateVar = waiting_for_detection;
}
void loop() {
BlinkHeartBeatLED(heartBeatLED_Pin, 250); // execute lines of code inside function "void BlinkHeartBeatLED(int IO_Pin, int BlinkPeriod) {"
myMonoStableStateMachine(); // execute lines of code inside function "void myMonoStableStateMachine() {"
}
void myMonoStableStateMachine() {
switch (myStateVar) {
// in case the variable with name "myStateVar"
// has the value represented by the name "waiting_for_detection"
// execute mutually exclusive the code below
// until the line with the "break;"
case waiting_for_detection:
if (digitalRead(IR_Pin) == HIGH ) {
Serial.println( F("object detected switching on LED") );
myTimer = millis(); // store snapshot of time
digitalWrite(LEDpin, HIGH);
myStateVar = detected_led_on;
}
break; // IMMIDIATELY jump down to END-OF-SWITCH
// in case the variable with name "myStateVar"
// has the value represented by the name "detected_led_on"
// execute mutually exclusive the code below
// until the line with the "break;"
case detected_led_on:
Print_a_dot(500);
if ( TimePeriodIsOver(myTimer, LED_OnTime) ) {
Serial.println( F("LED ON-time over switching LED off") );
digitalWrite(LEDpin, LOW);
myStateVar = detected_led_off;
}
break; // IMMIDIATELY jump down to END-OF-SWITCH
// in case the variable with name "myStateVar"
// has the value represented by the name "detected_led_off"
// execute mutually exclusive the code below
// until the line with the "break;"
case detected_led_off:
Print_a_dot(500);
if (digitalRead(IR_Pin) == LOW ) {
Serial.println( F("No object start ignore-waiting") );
myTimer = millis();
myStateVar = no_detection_wait;
}
break; // IMMIDIATELY jump down to END-OF-SWITCH
// in case the variable with name "myStateVar"
// has the value represented by the name "no_detection_wait"
// execute mutually exclusive the code below
// until the line with the "break;"
case no_detection_wait:
Print_a_dot(500);
if ( TimePeriodIsOver(myTimer, noObstacleWaitTime) ) {
Serial.println( F("ignore-waiting is over start wait for detection") );
Serial.println();
Serial.println();
myStateVar = waiting_for_detection;
}
break; // IMMIDIATELY jump down to END-OF-SWITCH
} // END-OF-SWITCH
}
void PrintFileNameDateTime() {
Serial.println( F("Code running comes from file ") );
Serial.println( F(__FILE__) );
Serial.print( F(" compiled ") );
Serial.print( F(__DATE__) );
Serial.print( F(" ") );
Serial.println( F(__TIME__) );
}
// easy to use helper-function for non-blocking timing
boolean TimePeriodIsOver (unsigned long &startOfPeriod, unsigned long TimePeriod) {
unsigned long currentMillis = millis();
if ( currentMillis - startOfPeriod >= TimePeriod ) {
// more time than TimePeriod has elapsed since last time if-condition was true
startOfPeriod = currentMillis; // a new period starts right here so set new starttime
return true;
}
else return false; // actual TimePeriod is NOT yet over
}
void BlinkHeartBeatLED(int IO_Pin, int BlinkPeriod) {
static unsigned long MyBlinkTimer;
pinMode(IO_Pin, OUTPUT);
if ( TimePeriodIsOver(MyBlinkTimer, BlinkPeriod) ) {
digitalWrite(IO_Pin, !digitalRead(IO_Pin) );
}
}
void Print_a_dot(unsigned long interval) {
static unsigned long myWaitTimer;
if ( TimePeriodIsOver (myWaitTimer,interval) ) {
Serial.print(".");
}
}