Das Konzept der StateMachine gefällt mir, und ich dachte, es verstanden zu haben. Alleine: Es funktioniert nicht. Im Serial Monitor werden zwar alle States durchlaufen, aber eine angeschlossene LED zeigt, dass die Intervalle nicht eingehalten werden. Es läuft viel zu schnell ab.
Der Code:
const byte triggerPin = 10; // Camera trigger
//Start time, used to calculate when this Timer has expired
unsigned long dummyTimerStart;
unsigned long carriageSettleTimer;
unsigned long triggerTimer;
unsigned long latencyTimer;
unsigned long dummyTimerEnd;
unsigned long currentMillis;
//Interval/delay when/where this Timer expires
const unsigned long dummyStartInterval = 1000UL; // 1000ms to simulate other code
const unsigned long carriageSettle = 500UL; // 500ms
const unsigned long triggerOpen = 1000UL; // trigger needs 2 ms in MF mode, 500 ms in AF
const unsigned long camLatency = 500UL;
const unsigned long dummyEndInterval = 1000UL; // 1000ms to simulate other code
enum States
{
StateDummyStart, StateCarriageSettle, StateTrigger, StateLatency, StateDummyEnd
};
States mState = StateDummyStart;
void setup() {
pinMode (triggerPin, OUTPUT);
// Serial.begin(57600);
}
void loop() {
currentMillis = millis();
StateMachine();
}
// StateMachine()
//======================================================================
void StateMachine()
{
switch (mState)
{
//******************************************
case StateDummyStart:
if (CheckTimer(dummyTimerStart, dummyStartInterval, true)) {
// Serial.println("StartDummy over");
mState = StateCarriageSettle;
}
break;
//******************************************
case StateCarriageSettle:
if (CheckTimer(carriageSettleTimer, carriageSettle, true)) {
// Serial.println("Carriage settle over");
digitalWrite (triggerPin, HIGH);
// Serial.println("Open trigger");
mState = StateTrigger;
}
break;
//******************************************
case StateTrigger:
if (CheckTimer(triggerTimer, triggerOpen, true)) {
digitalWrite (triggerPin, LOW);
// Serial.println("Close trigger");
mState = StateLatency;
}
break;
//******************************************
case StateLatency:
if (CheckTimer(latencyTimer, camLatency, true)) {
// Serial.println("Latency over");
mState = StateDummyEnd;
}
break;
//******************************************
case StateDummyEnd:
if (CheckTimer(dummyTimerEnd, dummyEndInterval, true)) {
// Serial.println("End Dummy over");
mState = StateDummyStart; //now switching to State StateCarriageSettle
}
break;
//******************************************
default:
// default code goes here
break;
}
} // END StateMachine
// Timer for actions needed 'after' a period of time.
boolean CheckTimer(unsigned long &lastMillis, const unsigned long Interval, boolean restart) {
// lastMillis = the time this "timer" was (re)started
// Interval = interval/delay needed.
// restart = do we restart this timer again and again?
// has this timer expired?
if (currentMillis - lastMillis >= Interval) {
//should this timer start again?
if (restart == true) {
lastMillis = currentMillis; //get ready for the next iteration
}
//This Timer did expire
return true;
}
return false;
} // END CheckTimer()