|
|
View previous topic :: View next topic |
Author |
Message |
edgarruben
Joined: 15 Mar 2012 Posts: 4
|
Help with algorithm to recognize only last key pressed |
Posted: Tue Sep 26, 2017 5:47 am |
|
|
Good day / afternoon / evening to all. This time I need your help with a seemingly "simple" code, but it has been several days and I can not solve it. It's about the following:
Make sure you have 8 pushbuttons and 8 LEDs connected to a PIC16F628A, for example. Each time I press a button, the respective led lights up, and if I stop pressing it, it goes out. There are no problems there.
The problem arises when I press 2 or more keys at a time. When you press button A, you must turn on the LED A. If you press button B at the same time, LED A must be turned off and LED B should light up. If you hold down both keys, press a third key C, turn off the previous led; ie it should only react to the last key pressed and deactivate the previous ones.
I hope you can help me with this algorithm. I know you are experts on these topics. Greetings from Arequipa, Peru. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9246 Location: Greensville,Ontario
|
|
Posted: Tue Sep 26, 2017 4:39 pm |
|
|
It's not really 'simple' however reduce your problem to just 2 buttons and LEDs.
The first problem is switch 'bounce'. You'll need to get the buttons working reliably. Aside from hardware solutions like a cap across the contacts use a timer to 'scan' the inputs.
One solution...
By using a timer, say every 20ms, you should be able to 'read' the buttons correctly. every time a 'scan' takes place the current state of the buttons is loaded into a 'current' buffer. You compare this to the 'previous' buffer. Based on the comparison, you decide what action to take. If, say, the current and previous are the same then NO action is required. If the current has button B high, then LED B must be turned on, and all others off.
Try this for 2 buttons/LEDs. Once you get the code correct, add a 3rd button/LED, edit the code, compile, try and if it works add a 4th....eventually you'll get all 8 buttons/LEDs doing what you want.
There are several solutions of course, all are right, none are wrong.
Jay |
|
|
edgarruben
Joined: 15 Mar 2012 Posts: 4
|
|
Posted: Wed Sep 27, 2017 9:25 am |
|
|
Thanks for the suggestion. I'll try and tell you how it goes. |
|
|
edgarruben
Joined: 15 Mar 2012 Posts: 4
|
|
Posted: Mon Oct 02, 2017 4:34 am |
|
|
Aún tengo problemas con el código. Alguna otra sugerencia con el algoritmo? |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Mon Oct 02, 2017 6:41 am |
|
|
This is an English language forum. Please use English only.
It should help to stop thinking of buttons as being on or off, i.e. as states, but rather as events, i.e. when a button goes from off to on and vice-versa. in other words look for the changes in state. Then all you need to keep track of is the last button to change state from off to on.
The hardware may not help: if you are multiplexing then you may not be able to correctly detect all combinations of keys which are on at the same time. |
|
|
edgarruben
Joined: 15 Mar 2012 Posts: 4
|
|
Posted: Mon Oct 02, 2017 2:00 pm |
|
|
Thanks for the answer RF_Developer and sorry for the language.
I think the idea of using events instead of states is ok, but now my question is, how would be the code for that ? Could you please give me a code as an example ? The inputs are not multiplexed. Thanks for the answer. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Tue Oct 03, 2017 2:25 am |
|
|
A lot depends on how fast you are checking things, and how fast your action needs to be. However (overview only):
Visualise you have a static int8 variable holding 'last_keys', and another int8 variable 'keys', into which you write the current key pattern. Lets assume '1' is a key that is pressed, and '0' is a key that is not pressed. Then:
change_on = keys & (last_keys ^ 0xFF);
Now 'change_on' will hold all key bits that were '1' in keys, and were not '1' in 'last_keys'. You then load 'last_keys' with the value now in 'keys' before leaving to return next time you want to test.
Now you then test change_on for being non zero, and if it is, you have a key that has changed to 'pressed'
Visualise 0b0000000 in both
last_keys ^ 0xff = 0b11111111
keys & 0b11111111 = 0
So no key has gone on.
Now 'keys' has (say) bit 0 go on, so is 0b00000001:
last_keys ^ 0xFF = 0b11111111
keys & 0xFF = 0b00000001
So the bottom key has gone on.
last_keys is now loaded with the '1' from keys.
next time round, keys is still 1 (the key is being held).
last_keys ^ 0xFF = 0b11111110
keys & 0xFE = 0
No new key has gone on.
Now visualise while still holding the first key a second key goes on.
keys = 0b00000011
last_keys^0xFF =0b11111110 (key 0 was still on)
keys &0b11111110 = 0b00000010
So the second key has now gone 'on'. Last_keys is now 0b00000011
Now the first key releases.
keys = 0b00000010
last_keys^0xFF = 0b11111100
keys & 0b11111100 = 0
No new key has gone on.
etc..
The only other thing you have to deal with is handling when two keys are pressed at the same time. One way to deal with this is to give priority from one end of the row. So 'high' keys are typically always given priority over 'low' for example, so you only react to the top one. The other would always be to only set the key in 'last_keys' when it is handled, so the second key will then be seen the next time round the loop. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|