const byte triggerInputPin = 3;
const byte triggerIsActive = LOW; // LOW o HIGH
const byte PinToSwitch = 12;
const byte OutPutOn = HIGH;
// the attention-mark ! is the not-operator which inverts the value
// !true = false !false = true !HIGH = LOW !LOW = HIGH
const byte OutPutOff = !OutPutOn;
// set InitialWaitTime to 0 if you don't want a delay between triggering and switching output
unsigned long InitialWaitTime = 050; // was 2000, 500, 50
unsigned long ActiveTime = 1000; // was 3000
unsigned long LockedTime = 100; // was 10000, 5000, 500
unsigned long MonoFlopTimer; // variable used for non-blocking timing
// constants of the state-machine
const byte sm_Idling = 0;
const byte sm_InitialWait = 1;
const byte sm_Activated = 2;
const byte sm_Locked = 3;
byte MonoFlopState = sm_Idling; // state-variable of the state-machine
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
}
unsigned long MyTestTimer = 0; // Timer-variables MUST be of type unsigned long
const byte OnBoard_LED = 13;
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 setup() {
Serial.begin(115200);
Serial.println("Setup-Start");
PrintFileNameDateTime();
pinMode(triggerInputPin,INPUT_PULLUP); // INPUT_PULLUP
digitalWrite(PinToSwitch,OutPutOff);
pinMode(PinToSwitch,OUTPUT);
}
void MonoFlopStateMachine() {
switch (MonoFlopState) {
case sm_Idling:
// check if trigger-input reads triggering signal
if (digitalRead(triggerInputPin) == triggerIsActive) {
MonoFlopTimer = millis(); // make snapshot of time
MonoFlopState = sm_InitialWait; // set next state of state-machine
Serial.println( F("trigger-signal detected start inital wait") );
}
break; // IMMIDIATELY jump down to END OF SWITCH
case sm_InitialWait:
// wait until initial waittime has passed by
if ( TimePeriodIsOver(MonoFlopTimer,InitialWaitTime) ) {
// if waittime HAS passed by
MonoFlopTimer = millis(); // make new snapshot of time
digitalWrite(PinToSwitch,OutPutOn); // switch IO-Pin to activated state
MonoFlopState = sm_Activated; // set next state of state-machine
Serial.println( F("InitialWaitTime is over switching output to ACTIVE") );
}
break; // IMMIDIATELY jump down to END OF SWITCH
case sm_Activated:
// check if time the IO-pin shall be active is over
if ( TimePeriodIsOver(MonoFlopTimer,ActiveTime) ){
// if activetime of IO-pin IS over
MonoFlopTimer = millis(); // make new snapshot of time
digitalWrite(PinToSwitch,OutPutOff); // switch IO-pin to DE-activated state
MonoFlopState = sm_Locked; // set next state of state-machine
Serial.println( F("Activetime is over switching output to IN-active") );
Serial.println( F("and starting locktime") );
}
break; // IMMIDIATELY jump down to END OF SWITCH
case sm_Locked:
// check if time the logic shall be locked against too early re-triggering is over
if ( TimePeriodIsOver(MonoFlopTimer,LockedTime) ){
// if locked time IS over
Serial.println( F("locktime is over change state to idling") );
MonoFlopState = sm_Idling; // set state-machine to idle-mode
}
break; // IMMIDIATELY jump down to END OF SWITCH
} // END OF SWITCH
}
void loop() {
BlinkHeartBeatLED(OnBoard_LED, 250);
// run down code of state-machine over and over again
// all the logic for reading in sensor-signal and switching output ON/OFF
// is inside the function
MonoFlopStateMachine();
}