two simultaneous key to perform operation in PIC16F877

Thread Starter

ecaits

Joined Jan 6, 2014
56
Dear Friends,

Right now I am using 4 key to perform the operation like UP, DOWN, OK & EXIT in my project. But Now I want to perform EXIT operation by remaining three keys. How can I prepare the code???

I mean I want to reduce the keypad from 4 keys to 3 keys....

I am using PIC16F877 with hi-tech C compiler..

Thank you,
 

djsfantasi

Joined Apr 11, 2010
9,163
Theoretically, you could program 7 different functions with three keys, using all combinations.

But to your problem. I see two approaches. Use one key combination for one of the functions. For example, the three keys could be UP, DOWN and OK. However if OK and DOWN were pressed together, that would mean EXIT.
Another way is to treat the third key like a "shift" key on a PC keyboard. For example, two keys would be used for UP and DOWN, but if the third key was pressed, their functions would be OK and EXIT.
 

joeyd999

Joined Jun 6, 2011
5,287
Button 1: press for UP
Button 2: press for DOWN
Button 3a: press and release for OK
Button 3b: press and hold for EXIT

I'd also make button 1 and 2 press and hold to repeat.
 

ErnieM

Joined Apr 24, 2011
8,377
Another way is if you have a display of any type UP and/or DOWN can put you into either an OK or EXIT mode, then the third key activates that mode.

Otherwise you have to see if two keys are pressed together. That gets tricky with a human pressing the buttons as no human can ever get them to go down or up exactly together in time, so short windows need to be opened.

(I prefer joeyd's answer over mine.)
 
Last edited:

Thread Starter

ecaits

Joined Jan 6, 2014
56
Theoretically, you could program 7 different functions with three keys, using all combinations.

But to your problem. I see two approaches. Use one key combination for one of the functions. For example, the three keys could be UP, DOWN and OK. However if OK and DOWN were pressed together, that would mean EXIT.
Another way is to treat the third key like a "shift" key on a PC keyboard. For example, two keys would be used for UP and DOWN, but if the third key was pressed, their functions would be OK and EXIT.
Yes I want to do the one key combination for one of the function. But I am not getting that how can I do that???
 

THE_RB

Joined Feb 11, 2008
5,438
Button 1: press for UP
Button 2: press for DOWN
Button 3a: press and release for OK
Button 3b: press and hold for EXIT

I'd also make button 1 and 2 press and hold to repeat.
Two excellent suggestions. EXIT is the one function where you don't care how long it takes, and don't want to do anything after it. So a "long press" to exit is a nice solution.


ErnieM said:
...
Otherwise you have to see if two keys are pressed together. That gets tricky with a human pressing the buttons as no human can ever get them to go down or up exactly together in time, so short windows need to be opened.
I don't see detecting two keys together as tricky, and already have a good system for it.

I poll all keys together (usually on the one port) and if any port value (any combination of keys) remains stable for >30mS the debounce routine logs that as a "stable state", and can then be tested for which buttons (which pins) are pressed.

Then the other task the debounce routine does is to make sure all buttons are released >30mS before it can happen again.

So debouncing is done on the entire port (all buttons) at the same time, in one simple operation. :)
 

ErnieM

Joined Apr 24, 2011
8,377
I don't see detecting two keys together as tricky, and already have a good system for it.
That is very similar to how I debounce my buttons, and yep, do em all in one bunch too.

But I would worry about making my users hit two buttons within 30 mS to score a double hit; I'd be a bit more forgiving about how that happens, meaning if one button was pressed I'd be checking for another button pressed before it is released... or something like that. I'd be "user testing" (even if I am the only user) to make sure it works as I like.

Anything I don't see as straightforward that may need several code-test-code again loops I define as "tricky."

Years back I settled on a pattern of 5 buttons: UP, DOWN, LEFT, RIGHT, and in the center ENTER. Whenever possible they work in conjunction with a 4 line x 20 character alphanumeric LCD. That makes it easy to create multiple menus to drill down to specific items to update.

It is pure pleasure to say update say a date with UP and DOWN buttons to set the month, then go RIGHT to change the day, then again to change the year... or hit left to go back.

ENTER starts accepting the new input, but I have also added a "ARE YOU SURE?" yes/no menu if you want to forgetaboutit.

Heck, I copied the 5 button interface off my cable remote control after seeing how well it worked.
 

MMcLaren

Joined Feb 14, 2010
861
I don't see detecting two keys together as tricky, and already have a good system for it.
May I look at how you did that, please? Is there a handy example of that system in a program on your web site, by any chance? If not, please don't worry about it (I don't want to impose).

TIA. Mike
 
Last edited:

MMcLaren

Joined Feb 14, 2010
861
... Years back I settled on a pattern of 5 buttons: UP, DOWN, LEFT, RIGHT, and in the center ENTER. Whenever possible they work in conjunction with a 4 line x 20 character alphanumeric LCD. That makes it easy to create multiple menus to drill down to specific items to update.
That seems like the most intuitive system to me, too, Ernie. And you can use the buttons in different contexts. That is, as you mentioned, use the <up> and <down> arrows to scroll through a menu, or in a different context, to increment or decrement a displayed value. You can even auto-repeat keys selectively according to context.

Mike
 
Last edited:

THE_RB

Joined Feb 11, 2008
5,438
May I look at how you did that, please? Is there a handy example of that system in a program on your web site, by any chance? If not, please don't worry about it (I don't want to impose).
...
Sorry Mike I can't remember doing it on any of my released code, generally I try to avoid multiple buttons pressed where possible (for the reasons people have mentioned). It would have been on other projects where a minimal number of buttons was dictated.

Assuming a loop at a fixed interval (like 1mS etc);
1. read the port with buttons
2. if the read is different to last read, reset debounce counter, else inc it
3. if debounce counter >30mS process buttons
(processing buttons sets a "buttons released" flag if the 30mS stable state was all buttons released. Or if that flag is set, it is the first stable buttons pressed state after the buttons were stable released)

Hope that makes sense.
 

MMcLaren

Joined Feb 14, 2010
861
I'm sure it would make sense if I could actually see it, but, that's ok. As I said, I didn't want to impose. I just figured if anyone could make that kind of scheme work elegantly, you'd be the one to do it.

Cheerful regards, Mike
 

THE_RB

Joined Feb 11, 2008
5,438
Hi Mike, I looks through some older projects and what I found was basically this code;

Rich (BB code):
unsigned char pins_new;
unsigned char pins_last;
unsigned char pins_safe;
unsigned char pins_debounce;

  // this is done once every mS in main loop
  // code to read and debounce 8 switches on 8 pins
  pins_new = PORTB;
  if(pins_new == pins_last)
  {
    pins_debounce++;
    if(pins_debounce > 30)
    {
      pins_safe = pins_new;
      pins_debounce--;
    }
  }
  else
  {
    pins_debounce = 0;
    pins_last = pins_new;
  }
It's "elegant" enough in that it auto debounces all 8 inputs, and any value in pins_safe is a pin value that had been proven to be stable for at least 30mS contiguously. Whatever the last stable PORT value is always in pins_safe.

It's very fast and compiles down to a handful of ASM instructions.

I'm sure I also used it for buttons but there was a limit to how many projects I was going to look through. :)

On buttons to detect a dual press I think you would need to have much larger than 30mS safe period, more like 150mS?
 

MMcLaren

Joined Feb 14, 2010
861
Ah, ok. Now I see. That is very simple and elegant. I was also concerned, like ErnieM, that 30-ms was too short an interval to impose on a user. 150-ms seems much more reasonable.

Thank you... Cheerful regards, Mike
 
Top