Another thread got me thinking about what condition a state machine should leave one state in when it exits en route to the next.
Let's say 2 states x an y both illuminate the blue led, among other things.
So when we get to state x, it explicitly turns the blue led on. But it doesn't know what state y wants to do, and should probably not expect state y even to know of the existence of the blue led.
My thinking is that x should extinguish the blue led on exit from x, and if y wants it on, well that's y's business. But y might not even know there is a blue led and shouldn't be expected to turn it off if it doesn't want it.
Today, state y might want the blue led on, but maybe the requirement changes one day and then y doesn't want the blue led on. Or, there might be a need for new state z, and x didn't know that when it was coded.
So, what's the rule of thumb if there is one?- leave a state as you found it so to speak, and leave it to the next state to do its thing, even if that means repeating stuff done previously, which of course the later state wouldn't know.
States don't have internal states. They are atomic (can't be nested). So they can't "know" anything. If you think a state should "know" something, you probably need to add additional states.
The way you're describing x and y, they sound more like state changes than states. The states are "Led on" and "Led off".
Or on second thoughts, perhaps I should temper that last with "in the absence of any other knowledge".
You wouldn't want state x to turn an iron foundry off for example, but the system spec should presumably say that state x switches the blue led (= iron foundry ) on and leaves it on, and if another state z wants it off it will do that explicitly.
aarg:
States don't have internal states. They are atomic. So they can't "know" anything. If you think a state should "know" something, you probably need to add additional states.
Hm ok... so does that mean the event that moves us to my state x in the first place, should include the actual switching on of the blue led? So when it gets to state x, blue is on, not as a result of getting to state x, but of being sent there?
When an event happens (eg. serial input, switch press) then
Check what the current state is.
If the current state is A, then do X, and maybe change to state B.
If the current state is B, then do Y, and maybe change to state C.
And so on ...
That means based on the event and the current state, you do stuff then go to the next state. My backwards thinking was to get to the next state and do the actions there.
ardy_guy:
That means based on the event and the current state, you do stuff then go to the next state. My backwards thinking was to get to the next state and do the actions there.
I reckon both approaches are equally acceptable. A state variable is just a convenient way to keep track of part of a system - for example doorOpen = true or doorOpen = false. There may also need to be variables to record window states, or heating states.
Decisions to perform actions can be made based on states and may cause states to change. For example
if(doorOpen == true && heatingOn == true) {
// code to turn heating off
heatingON = false;
}
You can have a system that progresses through several states and only moves to the next state when something has been completed. But, equally, you could have a system that holds off from doing something until a certain state is reached.
I reckon the logic of the system should be written down in plain language first with the various states that need to be taken into account before any attempt is made to write code.
Robin2:
I reckon the logic of the system should be written down in plain language first with the various states that need to be taken into account before any attempt is made to write code.
No argument there, that's for sure.
(Although not necessarily in words: I was taught Fortran over 40 years ago using traditional flowcharts. Which ever way you do it: think first, code second.)
ardy_guy:
But y might not even know there is a blue led and shouldn't be expected to turn it off if it doesn't want it.
All states in a given state machine should have a specified value for every output. Even if it's specified as "don't care" (in other words, leave it however the last state left it).
Even if state Y doesn't care about that output, it still "knows" about it. If you think of things any other way then you're doing it wrong.
It can help to make tables. Make a list of all the states, one on each row, then define what every output is going to be for each of those states. There's no need to be rigid about it. Some examples you might use are "flashing every 1 second", "PWM scaled from A0 input", "always LOW", "Don't care", etc. The benefit of having a structured plan is more important than any kind of formal correctness.
Jiggy-Ninja: All states in a given state machine should have a specified value for every output. Even if it's specified as "don't care" (in other words, leave it however the last state left it).
Since starting this thread I pondered a bit more and arrived at that conclusion. Although the number of combinations may be huge, it is by definition of a Finite State Machine, finite.
I found a paper last night that said that the action triggered to move to one state from another could be a method. That method would cater for every output in the new state (where "cater for" could include the "don't care" case.)
So if state_blue had the blue led on and all others off except for yellow which it didn't care about, then there would be a method called from any state leading to state_blue which would explicitly turn blue on and red and green off, and not do anything to yellow.
ardy_guy:
I found a paper last night that said that the action triggered to move to one state from another could be a method. That method would cater for every output in the new state (where "cater for" could include the "don't care" case.)
So if state_blue had the blue led on and all others off except for yellow which it didn't care about, then there would be a method called from any state leading to state_blue which would explicitly turn blue on and red and green off, and not do anything to yellow.
I find it hard to get my head around all that. It seems to me to be too self-contained.
"Method" is the name commonly used in OOP languages for what are referred to as functions elsewhere. A method can do a lot or a little. I can't see it having any specific link to the concept of a state machine though methods could be used in a state machine program - indeed would be used if the program was being written in (say) Ruby.
I would approach your logic differently. If I had some preconditions that are essential before a certain state can be reached I would test to see if those exist. In my mind a certain state exists if something else (maybe several other somethings) has created the necessary preconditions. It would not necessarily be correct to have a function (or method) that could be called from anywhere and that automatically sets all those preconditions. Each precondition must arise because of logic that is appropriate for itself.
Think, for example about UK traffic lights that show a brief orange alongside a red before the change to green. You could say that green can only occur if there is already a red-orange combination. But it would be quite wrong to have a function to set red-orange just to facilitate green. The move to the red-orange combination must itself take account of other states.