I have a simple board with 6 buttons, consisting of 3 columns and 2 rows I would like to detect the pressed button. My code below works with this fsm:
scan_fsm : process (reset, clk)
begin -- process key_scanner
if reset = '1' then
Send <= '0';
fsm_state <= start;
scannel_val <= "0000";
elsif clk'event and clk = '1' then
if state_inc = '1' then
scan_complete <= '0';
case fsm_state is
when start =>
Send <= '0';
scannel_val <= "0000";
my_switch <= "001";
fsm_state <= state1;
when state1 =>
case bcd_val is
when "01" =>
Send <= '1';
scannel_val <= "0001";
when "10" =>
Send <= '1';
scannel_val <= "0010"; -- Value 2
when others =>
scannel_val <= "0000";
Send <= '0';
end case;
my_switch <= "010";
fsm_state <= state2;
when state2 =>
case bcd_val is
when "01" =>
Send <= '1';
scannel_val <= "0011";
when "10" =>
Send <= '1';
scannel_val <= x"0100"; -- Value 4
when others =>
scannel_val <= "0000";
Send <= '0';
end case;
my_switch <= "100";
fsm_state <= state3;
when state3 =>
case bcd_val is
when "01" =>
Send <= '1';
scannel_val <= "0101";
when "10" =>
Send <= '1';
scannel_val <= "0110";
when others =>
scannel_val <= "0000";
Send <= '0';
end case;
my_switch <= "001";
fsm_state <= state1;
scan_complete <= '1';
when others => scannel_val <= "0000";
end case;
end if;
end if;
end process scan_fsm;
I have 4 states, start and a state for each column. I would like to improve my board and prevent glitches. I would like to add fatures like if 2 buttons pressed at the same time, I should get the first value which reached few miliseconds or nanoseconds before the other one. Also I would like to prevent a second value being read or a third when already a button is being pressed.
So, no matter how many buttons pressed, only one value should be read. I thought about adding a 5th state, idle, when this occurs but then how do I get out of idle?
Instead of idle I can also switch to state "start" but then this would make the send
signal "0" which would be false if already a button is being pressed. Also how many processes are in this FSM? What is a process in VHDL? Is it 3; reset, clk and state_inc? statce_inc becomes "1" every 200Hz with the help of a counter. I added some debouncing code I found from the internet but doesn't help :( Anyone has a debouncing suggestion?
Another issue, I would like to get rid of the state start
actually, the only reason I have it is because I should assign my_switch
to "001"
before state1
. In my first implementation I was assigning my_switch
to "001"
in state1
and "010"
in state2
and "100"
in state3
. In this implementation since my keypad is
______
|1|2|3|
|4|5|6|
When I pressed 2, 1 was displayed when I press 3, 2 was displayed. I was thinking Cpp/Java way but I was wrong... then I added a dummy state start
just to set my_switch
before entering the real scanning... So if I can solve this I can also save a state! Suggestions are welcome! I solved this with entering the first scan without a set value. Do you have better ideas?
my_switch
(column) is output signal andbcd_val
(row) is input , thusbcd_val
should be 2 bits long sorry for that I'm updating now the code \$\endgroup\$