CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Debounce a Switch and Increment a value ?
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
scottc



Joined: 16 Aug 2010
Posts: 95

View user's profile Send private message

PostPosted: Tue Oct 26, 2010 4:51 pm     Reply with quote

PCM, Thats an excellent explanation,

I tested the routine in a TIMER0 ISR and it appears to work fine also.
I'm using a 18f part so timer0 is 16bits

Here is how I implementated it.
Code:

#int_timer0
void Push_Button(void)    //Function increments Count by 1 regardless
{                         //of how long Enc_SW is pressed in
  set_timer0(0);
  static int1 pushed = false;

   if (!pushed && !Enc_Sw)   // Switch is Pressed / down
   {
      pushed = true;
      while ( get_timer0() <53036) ;   //5MS Interrupt
     
      if (++count == 4) count = 1;     // Increment the count 
         
   } else if (Enc_Sw)                  // Switch is Released / up
      pushed = false;     
}

void main(void)

 setup_timer_0 (RTCC_DIV_1|RTCC_INTERNAL);
   CLEAR_INTERRUPT (INT_TIMER0);
   ENABLE_INTERRUPTS (GLOBAL);
   ENABLE_INTERRUPTS (INT_TIMER0);
   SET_TIMER0(0);

}

I believe its correct, but comments welcome if it is not.

Thanks Scott
pmuldoon



Joined: 26 Sep 2003
Posts: 216
Location: Northern Indiana

View user's profile Send private message

PostPosted: Thu Oct 28, 2010 7:57 am     Reply with quote

Are you really intending to spend 5 out of 6.4mS in the interrupt routine?
scottc



Joined: 16 Aug 2010
Posts: 95

View user's profile Send private message

PostPosted: Thu Oct 28, 2010 10:41 am     Reply with quote

Intent was to spend about 5ms in the isr as a pseudo debounce for the
pushbutton switch.

Thanks Scott
pmuldoon



Joined: 26 Sep 2003
Posts: 216
Location: Northern Indiana

View user's profile Send private message

PostPosted: Thu Oct 28, 2010 11:21 am     Reply with quote

It works, but just a bit unusual since your PIC will only have 14/64ths of its potential processing time available to do anything else.

Here is yet another debounce technique. I had an existing piece of hardware that had 2 pushbuttons (SELECT, ENTER) and a 2-line LCD for an interface.
I needed to make the buttons responsive & debounced, yet I wanted a way to keep a careless user from accidentally getting into the setup/config
stuff. I detect a button press quickly, and can also detect a button held for about 2-secs (to access setup screens). The interrupt routine sets the flags that tell the rest of the program that a button was pushed. It is the responsibility of the routine responding to the button press to reset the flag.

I'm just showing the SELECT button to keep it simple.
It's running with a 4MHz crystal and no divisor on the Timer_1 setup, so each count is 1 uS.

Code:

#define PB_SELECT PIN_D6      // SELECT pushbutton
#define DEBOUNCE_TIME 3      // # of (10mS) interupt cycles Pushbutton must be held for before validating
#define LONG_PRESS_TIME 200   // number of 10mS interrupts before keypress is considered to be a long press (up to 254)

// Global Flags set by interrupt when button press detected, cleared by responding routing
int1   PBselectHit=0;      // Flag indicating PB has been detected and debounced.
int1    PBselectLongPress=0; // indicates a LONG_PRESS_TIME has expired

/********************* Timer1 Interrupt Handler *************************************/
#int_timer1
void Timer1Handler()
{
   static unsigned int    SelectActive=0,
                                                                  
   set_timer1(get_timer1()-10000);                // set the timer to fire again in 10mS
   // pushbutton debounce SELECT
   if(input(PB_SELECT))
   {
      if(SelectActive++ == DEBOUNCE_TIME) // button must be held continuously for this many interrupt cycles
         PBselectHit = TRUE;   // flag must be reset by function waiting for keypress
      if(SelectActive == LONG_PRESS_TIME)
         PBselectLongPress = TRUE;  // flag must be reset by function waiting for keypress

      if(SelectActive > LONG_PRESS_TIME)      // long press detected
         SelectActive = LONG_PRESS_TIME+1;   // clamp counter
   }
   else
   {
      SelectActive = 0;      // otherwise reset debounce counter and start over
   }   
}
scottc



Joined: 16 Aug 2010
Posts: 95

View user's profile Send private message

PostPosted: Thu Oct 28, 2010 6:52 pm     Reply with quote

Thanks for sharing your example pmuldoon, interesting code.

I am using my routine with a pic18f2331 running at 10Mhz, I did not
notice any problems with the pic slowing down. The code may not be optimal but does appear to work good.

I get in and out of the button routine fast. Each press of the button will increment the count variable. I test the variable and depending on its value jump to a rotary encoder routine and display another value on
a LCD running in 4bit interface mode. Similar to say using a car radio
and tuning a station.

The actual lcd routine running in 4bit mode, 20chr x 2 line is running at
1.25 Ms for each write to the display. Tests so far seem fairly fluid.
Hit the button, jump to a menu, Spin the encoder, write to the display.
The only ISR in the code is the push button routine, so all in all not too
bad.

Got to just love the pic processor man, awesome little chip Smile
and lets not forget the ccs compiler thats awesome too.

Thanks Scott
MassaM



Joined: 08 Jun 2019
Posts: 31

View user's profile Send private message Visit poster's website

PostPosted: Sun Jul 14, 2019 6:01 pm     Reply with quote

pmuldoon wrote:

Here is yet another debounce technique. I had an existing piece of hardware that had 2 pushbuttons (SELECT, ENTER) and a 2-line LCD for an interface.
I needed to make the buttons responsive & debounced, yet I wanted a way to keep a careless user from accidentally getting into the setup/config
stuff. I detect a button press quickly, and can also detect a button held for about 2-secs (to access setup screens). The interrupt routine sets the flags that tell the rest of the program that a button was pushed. It is the responsibility of the routine responding to the button press to reset the flag.


Hello pmuldoon,

Apologies as I don't intend to hijack this discussion thread, but your code is helping me in my project and may I ask your help on this thread please?

https://www.ccsinfo.com/forum/viewtopic.php?p=224938#224938

Appreciated!
_________________
while(!dead)
{
keepLearning();
}
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2
Page 2 of 2

 
Jump to:  
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