Forum Discussion
Simple State Machine not working as expected
Hi, guys!
So, I'm new here. I'm a student whose lab professor gave him the following assignment. Translated from spanish to english, it reads like this:An electrical engine is controlled by a single button. When the button is pushed, the engine is turned on. When the button is pushed again, the engine returns to 'off' status. Syntethize the engine's control circuit in VHDL.And then I have to program a FPGA with it, SignalTap it, and show the professor that it works as intended. The FPGA I'm using is a Cyclone III EP3C16F484C6. Since the pushable button I use continuously sends a '1' signal when it's not pushed, and a '0' signal while it's pushed, I wrote the following VHDL code for the assignment. ENTITY enginecontrol IS
PORT (clk,button: IN BIT; engine: OUT BIT);
END enginecontrol;
ARCHITECTURE behavior OF enginecontrol IS
TYPE statesec IS (A,B,C,D);
SIGNAL state: statesec:=A;
BEGIN
PROCESS (clk)
BEGIN
IF (clk'EVENT AND clk ='1') THEN
CASE state IS
WHEN A =>
IF button ='0' THEN
state<=B;
ELSE
state<=A;
END IF;
WHEN B =>
IF button ='1' THEN
state<=C;
ELSE
state<=B;
END IF;
WHEN C =>
IF button ='0' THEN
state<=D;
ELSE
state<=C;
END IF;
WHEN D =>
IF button='1' THEN
state<=A;
ELSE
state<=D;
END IF;
END CASE;
END IF;
END PROCESS;
engine<= '0' WHEN state=A ELSE
'1' WHEN state=B ELSE
'1' WHEN state=C ELSE
'0';
END behavior;Here, remember, button pushed is 0 and button released is 1. Engine 'on' is 1 and engine 'off' is 0. This code, I believe, clearly describes a state machine with four possible states. It starts at state A, with the engine off. If the button is pushed, it goes to state B, and the engine turns on. It will remain on state B as long as the button is pushed, and when the button is released, it goes to state C, engine still on. Push the button again, and you get state D, engine off. Let it go and the cycle begins again, at state A. This is the desired behavior! Always the same, reliable... But the real behavior is... random! Around 70% of the time, when you release a button, it goes from state B to A, instead of C, or from state D to C, instead of A. This, of course, has undesired results on the output. Nowhere in the code I can see anything that could produce this behavior! And around 30% of the time, releasing a pushed button works as intended, and the machine goes to the correct next state. Since I won't be seeing my lab professor again until January 10th, can you guys tell me why this is happening? Many thanks for your time and help!6 Replies
- Altera_Forum
Honored Contributor
The second solution you suggested was perfect. I added a counter to lock each state upon arrival for 100 mseconds, staying just there and ignoring all button input during this small lock interval. Now the machine works 100% as intended.
Thanks a lot for your help! You've made an student happy! - Altera_Forum
Honored Contributor
You can also use your state machine for debouncing but add extra interval of time. This could be simpler to control:
s0: detect push = 0, decide toggle, move to s1 s1: stay for some time ignoring key, then move to s0 - Altera_Forum
Honored Contributor
There are different ways to debounce keys.
In your case you want to detect push = '0' once only over some practical interval. For example I will run a counter for 20 msec.
you will need to test this logic as I wrote it off head.pseudocode, on the clock edge... if push = '0' and count = max then -- first push detection push_L <= '1'; end if; if push = '0' and push_L = '0' then count <= 0; end if; if count < max then count <= count + 1; else push_L <= '0'; end if; if push = '0' and push_L = '0' then push_T <= not push_T; -- to your engine, hopefully without smoke end if; - Altera_Forum
Honored Contributor
Or you mean that sometimes the button sends '0' signals even after being released already? Even after having sent some '1' -I'm released!- signals, a rogue '0' signal can come after that??
If that's the case... I have no idea how to overcome it. - Altera_Forum
Honored Contributor
I assume by bouncing you mean the fact that you can push the button just for a moment, but several '0' signals are sent, instead of just one. Yes, I knew and explained that... This is why if I only used a toggle, the circuit would never work as intended. The state machine I made is my way of filtering off that bouncing, it is my 'debouncing logic'. Why doesn't it work? Could you explain to me how would you do it instead?
Many thanks! - Altera_Forum
Honored Contributor
According to your spec I don't need state machine just toggle a register upon push.
Regarding you state transitions, remeber push is momentary and may suffer bouncing. you can add debouncing logic.