Maybe not strictly a programming question, more on the modeling, but it will inform the code, and anyway I can't think of a better board for this....
I've coded a turnstyle which looks very like Wikipedia's, ie the insertion of a coin moves its state from Locked to Unlocked. Pic of their state diagram, attached.
(Built a really simple turnstyle (a boom, actually) with an opto-interrupter to check it's home, an electromagnet as the lock, and a button as the coin.... I'll post it somewhere for posterity this weekend. Further input was from here.)
But to my question:
Lets's say there are two events required to unlock it: perhaps swipe a card AND insert a coin, or a fingerprint and card, whatever.
Would the model still be the same with two events, thus:
Locked => Card AND coin => Unlocked
or, would it be better to have a sort of "half-unlocked" state after the card is swiped, thus:
I'm inclined to think the answer depends on the "mechanical" and security arrangements and on the way you want to write your program.
Presumably the card read and the coin are unlikely to happen at the same instant? Must one of them happen first? How do you deal with an incomplete transaction - for example a valid card is read but some other "illegal" person inserts a coin 30 minutes later.
But you might decide (probably should decide) to separate the validation code from the activation code so that when it comes to activation you know that valid data exists or not and simple code like if (okToOpen) { would be sufficient at that point in the code.
JimboZA:
Yep Robin that's more or less my thinking: I'd go for a state of "Card swiped" as an intermediate step.
Wise choice. Including trivial, redundant, or irrelevant things in a state diagram is easy to fix. In the extreme case a pencil and a brain is all that is needed to correct the problems.
But, failing to include an important state, event, or transition can easily turn into a nightmare once coding starts.
In other words it's better to include too many seemingly little things and have to rework the model than to have an incomplete model.
When I did access control for a living this part of the code, known as validation was the most complex and difficult part. For every extra thing is seems like you need four times the code complexity.
You seem to have it mainly. I would attach a timeout to every state and have some form of indicator of the timeout, like an led or buzzer.
It becomes very complex when you have things like buddy access, time profiles, over rides, time expired tags, diffrent security levels of user and so on. The sales men were forever coming back with even more weird situations.
JimboZA:
Yep Robin that's more or less my thinking: I'd go for a state of "Card swiped" as an intermediate step.
So Event: Swipe from State: Locked will give State: Card swiped.
Event: Coin from State: Card swiped will give State: Unlocked.
Event: Swipe from State: Card swiped will remain at State: Card swiped
Event: Timeout from State: Card swiped will revert to State: Locked
Event: Coin from State: Locked will remain at State: Locked (ie card swipe must precede coin insertion.)
This is fun 8) .... purely academic, and it's clarifying a lot of state machine stuff which is all good.
That's it, but I would rename some of your states to make the sequence clearer.
Locked, waiting for card.
Card swiped, waiting for coin.
I would also include user prompts like lighting a LED by the card reader when a card is to be read, lighting a LED by the coin slot when a coin is needed and lighting a green LED when access is permitted and a red LED when access is denied.
I built the mechanism last weekend and wrote the code, but not tested with the mechanism yet- I'm out of town on business.
So this weekend I'll test my code as is, make sure I have the simple version running and then enhance.
Mechanism, btw, is made of Mecanno. A strip on a hinge basically: the middle of the strip sits in the "U" of the opto interrupter, and the free end rests on the electromagnet. Lifting it simulates pushing the arm of the turnstyle, dropping it simulates the next arm clicking home behind you. The strip can easily be lifted even when the magnet is on: that represents forced entry and sets off an alarm.
I have wrote some programs using this thecnique. For some of them I can't imagine a simpler way to write them (I mean that for certain complexity the finite estate technique is the only way I find acceptable).
The analisys fase (aimed to this thecnique) is, in my opinion, as difficult as any other one (You have to think a lot and make the same effort).
But, opposite as somebody tells above in the thread, corrections to the logic (program flux) is, once you have an acceptable version of the code working, much easier using a finite state automat.
(The customer continuous claims for unexpected situations are common: the only solution I know is to ask him (her) to make him think and 'rethink'; then once you are reasonabily sure he has analyzed all the possibilities, you have to ask him again for ALL the situations. Finally, once you two are sure the analysis is correct, I would recommend ask him (her) once again. Then, write it down and use it to make him understand that there were some possibilities missing).