  | 
	  | 
		 
	 
	
		| View previous topic :: View next topic   | 
	 
	
	
		| Author | 
		Message | 
	 
	
		
			opvini
 
 
  Joined: 27 Apr 2012 Posts: 50 Location: Brazil 
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				| onKeyUp method and deboucing for buttons - VBtn Library | 
			 
			
				 Posted: Thu Sep 06, 2012 12:32 am     | 
				     | 
			 
			
				
  | 
			 
			
				Hi... Well, I create a generic function to use with buttons that is very practice: the onKeyUp. It is necessary just create a int variable to each button, like below (here I just use 2 buttons):
 
 
The DEBOUCING was implemented:
 
 	  | Code: | 	 		  
 
//****************************************************************
 
//                           VBtn.c
 
//
 
//                Buttons Treatment Including:
 
//               Deboucing, onKeyUp, onKeyPress
 
//****************************************************************
 
//
 
//            Federal University of Ouro Preto - UFOP
 
//               Automation Engineer Department
 
//
 
// 
 
// Developed by:
 
//
 
// Vinicius Nunes Lage
 
// email: viniciusop[ @ ]gmail.com
 
// Class 09.1
 
// Last Modification: 29/04/2014
 
//
 
//
 
////////
 
//
 
// DEFINES:
 
//  MAX_DEBOUNCING   filter to debouncing
 
//
 
//
 
// SHARED API:
 
//
 
//  vbtn_init(VBtn, pin)
 
//    - initialize the VBtn with the pin
 
//
 
//  vbtn_input(VBtn)
 
//    - similar to the function input(), but with debouncing 
 
//
 
//  vbtn_onKeyUp(VBtn)
 
//    - onKeyUp event on VBtn
 
//
 
//  vbtn_onKeyPress(VBtn)
 
//    - onKeyPress event on VBtn
 
//
 
//****************************************************************
 
 
#ifndef MAX_DEBOUNCING 
 
   #define MAX_DEBOUNCING 400
 
#endif
 
 
struct VBtn{ 
 
   int16 pin; 
 
   int1  key_pressed;
 
   int1  key_up; 
 
   int1  key_press; 
 
   int16 dbc_count;
 
}; 
 
 
 
// novo input() com debouncing
 
int1 vbtn_input(struct VBtn *btn)
 
{
 
   if (!btn->key_pressed && input(btn->pin) && ++btn->dbc_count > MAX_DEBOUNCING)
 
   {  
 
      btn->dbc_count   = 1;
 
      btn->key_pressed = 1;
 
   } 
 
   else if (!input(btn->pin)) btn->key_pressed = 0;
 
          
 
   return (btn->key_pressed); 
 
} 
 
 
 
int1 vbtn_onKeyUp( struct VBtn *btn ){    
 
   if(      (btn->key_up==0) && !vbtn_input(btn->pin) ) { btn->key_up = 1; return(0); } 
 
   else if( (btn->key_up==1) && vbtn_input(btn->pin))   { btn->key_up = 0; return(1); } 
 
   else return(0); 
 
} 
 
 
 
int1 vbtn_onKeyPress( struct VBtn *btn ){ 
 
   if(     !btn->key_press && !vbtn_input(btn->pin) ){ btn->key_press = 1; return(1); } 
 
   else if (btn->key_press && vbtn_input(btn->pin))  { btn->key_press = 0; return(0); } 
 
   else return(0); 
 
} 
 
 
void init_vbtn(struct VBtn *btn, int16 PIN){
 
   btn->pin         = PIN; 
 
   btn->key_up      = 0; 
 
   btn->key_press   = 0; 
 
   btn->dbc_count   = 0;
 
   btn->key_pressed = 0;
 
}
 
 
 
//////////////////////////////////////////////////// END
 
 | 	  
 
 
 
SIMPLE EXAMPLE (pic 18F4550):
 
 
 	  | Code: | 	 		  
 
//****************************************************************
 
//
 
//                           EXAMPLE_VBtn.c
 
//
 
//****************************************************************
 
 
#include <18f4550.h>
 
 
// biblioteca para trabalhar com botoes
 
// incluindo debouncing, onKeyUp e onKeyPress
 
#include "VBtn.c"
 
 
#use delay(clock=20000000) 
 
#fuses HS
 
#use rs232(baud=9600, parity=N, bits=8, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
 
 
 
void main(){
 
 
   // declaration of 2 VButtons: btn1 and btn2
 
   struct VBtn btn1, btn2;
 
 
   // initialize btn1 and btn2 and set PIN_B7 and PIN_B6 to them
 
   init_vbtn(&btn1, PIN_B7);
 
   init_vbtn(&btn2, PIN_B6);
 
 
   while(1){
 
   
 
      // example using input with debouncing
 
 
      if( vbtn_input(&btn1) ) output_high(PIN_A0);
 
      else                    output_low(PIN_A0);
 
      
 
      if( vbtn_input(&btn2) ) output_high(PIN_A1);
 
      else                    output_low(PIN_A1);     
 
      
 
      
 
   }
 
 
} | 	  
 
 
Say if it is good for you!
 
Thanks!!!
 
 
EDITED: included deboucing
  Last edited by opvini on Mon May 05, 2014 7:47 am; edited 2 times in total | 
			 
		  | 
	 
	
		  | 
	 
	
		
			asmboy
 
 
  Joined: 20 Nov 2007 Posts: 2128 Location: albany ny 
			
			 
			 
			
			
			 
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Wed Sep 19, 2012 12:23 pm     | 
				     | 
			 
			
				
  | 
			 
			
				How do you set deadband between presses 
 
and validate  actual press down time, to avoid bouncing with dirty contacts?? | 
			 
		  | 
	 
	
		  | 
	 
	
		
			opvini
 
 
  Joined: 27 Apr 2012 Posts: 50 Location: Brazil 
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Mon Nov 12, 2012 5:06 am     | 
				     | 
			 
			
				
  | 
			 
			
				Hi asmboy...
 
I really do not treat the issue of dirt or poor contact of the buttons. But you can implement this using delay...
 
 
I make a new code, more complete:
 
 
 	  | Code: | 	 		  
 
 
////////////////////////////////////////////////////////////
 
 
struct struct_btn{
 
   int16 pin;
 
   int1 key_up;
 
   int1 key_press;
 
} btn1, btn2, btn3, btn4;
 
 
 
int1 onKeyUp( struct struct_btn *btn ){   
 
   if(      (btn->key_up==0) && !INPUT(btn->pin) ) { btn->key_up = 1; return(0); }
 
   else if( (btn->key_up==1) && INPUT(btn->pin))  { btn->key_up = 0; return(1); }
 
   else return(0);
 
}
 
 
int1 onKeyPress( struct struct_btn *btn ){
 
   if(     !btn->key_press && !INPUT(btn->pin) ){ btn->key_press = 1; return(1); }
 
   else if (btn->key_press && INPUT(btn->pin)) { btn->key_press = 0; return(0); }
 
   else return(0);
 
}
 
 
 
/////////////////////////////////////////////
 
 
 
 
 
// example using 2 buttons
 
 
 
int adm_onKeyUp(){
 
 
   if(      onKeyUp( &btn1 ) ) return(1);
 
   else if( onKeyUp( &btn2 ) ) return(2);
 
   else return(0);
 
   
 
}
 
 
int adm_onKeyPress(){
 
 
   if(      onKeyPress( &btn3 ) ) return(1);
 
   else if( onKeyPress( &btn4 ) ) return(2);
 
   else return(0);
 
   
 
}
 
 
 
 
 
void main(){
 
 
   //************************** initializing
 
   
 
   btn1.pin       = PIN_A3;
 
   btn1.key_up    = 0;
 
   btn1.key_press = 0;
 
   
 
   btn2.pin       = PIN_A1;
 
   btn2.key_up    = 0;
 
   btn2.key_press = 0;
 
   
 
   btn3.pin       = PIN_A4;
 
   btn3.key_up    = 0;
 
   btn3.key_press = 0;
 
   
 
   btn4.pin       = PIN_A2;
 
   btn4.key_up    = 0;
 
   btn4.key_press = 0;
 
   
 
   //**************************
 
 
while(1){
 
 
// returns 1 or 2 (button 1 or button 2 with keyUp)
 
adm_onKeyUp(); 
 
 
// returns 1 or 2 (button 1 or button 2 with keyPress)
 
adm_onKeyPress()
 
 
}
 
 
}
 
 | 	 
  | 
			 
		  | 
	 
	
		  | 
	 
	
		
			opvini
 
 
  Joined: 27 Apr 2012 Posts: 50 Location: Brazil 
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				| Bouncing treatment now | 
			 
			
				 Posted: Tue Apr 29, 2014 4:37 pm     | 
				     | 
			 
			
				
  | 
			 
			
				Hi asmboy,
 
Now I implement the bouncing treatment.
 
 
The full code is below.
 
I called the simple library "VBtn":
 
 
 	  | Code: | 	 		  
 
//****************************************************************
 
//                           VBtn.c
 
//
 
//                Buttons Treatment Including:
 
//               Deboucing, onKeyUp, onKeyPress
 
//****************************************************************
 
//
 
//            Federal University of Ouro Preto - UFOP
 
//               Automation Engineer Department
 
//
 
// 
 
// Developed by:
 
//
 
// Vinicius Nunes Lage
 
// email: viniciusop[ @ ]gmail.com
 
// Class 09.1
 
// Last Modification: 29/04/2014
 
//
 
//
 
////////
 
//
 
// DEFINES:
 
//  MAX_DEBOUNCING   filter to debouncing
 
//
 
//
 
// SHARED API:
 
//
 
//  vbtn_init(VBtn, pin)
 
//    - initialize the VBtn with the pin
 
//
 
//  vbtn_input(VBtn)
 
//    - similar to the function input(), but with debouncing 
 
//
 
//  vbtn_onKeyUp(VBtn)
 
//    - onKeyUp event on VBtn
 
//
 
//  vbtn_onKeyPress(VBtn)
 
//    - onKeyPress event on VBtn
 
//
 
//****************************************************************
 
 
#ifndef MAX_DEBOUNCING 
 
   #define MAX_DEBOUNCING 400
 
#endif
 
 
struct VBtn{ 
 
   int16 pin; 
 
   int1  key_pressed;
 
   int1  key_up; 
 
   int1  key_press; 
 
   int16 dbc_count;
 
}; 
 
 
 
// novo input() com debouncing
 
int1 vbtn_input(struct VBtn *btn)
 
{
 
   if (!btn->key_pressed && input(btn->pin) && ++btn->dbc_count > MAX_DEBOUNCING)
 
   {  
 
      btn->dbc_count   = 1;
 
      btn->key_pressed = 1;
 
   } 
 
   else if (!input(btn->pin)) btn->key_pressed = 0;
 
          
 
   return (btn->key_pressed); 
 
} 
 
 
 
int1 vbtn_onKeyUp( struct VBtn *btn ){    
 
   if(      (btn->key_up==0) && !vbtn_input(btn->pin) ) { btn->key_up = 1; return(0); } 
 
   else if( (btn->key_up==1) && vbtn_input(btn->pin))   { btn->key_up = 0; return(1); } 
 
   else return(0); 
 
} 
 
 
 
int1 vbtn_onKeyPress( struct VBtn *btn ){ 
 
   if(     !btn->key_press && !vbtn_input(btn->pin) ){ btn->key_press = 1; return(1); } 
 
   else if (btn->key_press && vbtn_input(btn->pin))  { btn->key_press = 0; return(0); } 
 
   else return(0); 
 
} 
 
 
void init_vbtn(struct VBtn *btn, int16 PIN){
 
   btn->pin         = PIN; 
 
   btn->key_up      = 0; 
 
   btn->key_press   = 0; 
 
   btn->dbc_count   = 0;
 
   btn->key_pressed = 0;
 
}
 
 
 
//////////////////////////////////////////////////// END
 
 | 	  
 
 
 
SIMPLE EXAMPLE (pic 18F4550):
 
 
 	  | Code: | 	 		  
 
//****************************************************************
 
//
 
//                           EXAMPLE_VBtn.c
 
//
 
//****************************************************************
 
 
#include <18f4550.h>
 
 
// biblioteca para trabalhar com botoes
 
// incluindo debouncing, onKeyUp e onKeyPress
 
#include "VBtn.c"
 
 
#use delay(clock=20000000) 
 
#fuses HS
 
#use rs232(baud=9600, parity=N, bits=8, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
 
 
 
void main(){
 
 
   // declaration of 2 VButtons: btn1 and btn2
 
   struct VBtn btn1, btn2;
 
 
   // initialize btn1 and btn2 and set PIN_B7 and PIN_B6 to them
 
   init_vbtn(&btn1, PIN_B7);
 
   init_vbtn(&btn2, PIN_B6);
 
 
   while(1){
 
   
 
      // example using input with debouncing
 
 
      if( vbtn_input(&btn1) ) output_high(PIN_A0);
 
      else                    output_low(PIN_A0);
 
      
 
      if( vbtn_input(&btn2) ) output_high(PIN_A1);
 
      else                    output_low(PIN_A1);     
 
      
 
      
 
   }
 
 
} | 	 
  | 
			 
		  | 
	 
	
		  | 
	 
	
		
			asmboy
 
 
  Joined: 20 Nov 2007 Posts: 2128 Location: albany ny 
			
			 
			 
			
			
			 
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Thu May 15, 2014 3:03 pm     | 
				     | 
			 
			
				
  | 
			 
			
				after a brief experiment it becomes clear that 
 
while functional and determinate as written,
 
the debounce timing produced can be 
 
 inconsistent as well as  variable and
 
 is influenced  by:
 
 
1- how often the check function is called. 
 
2- how many buttons are being monitored 
 
3-clock frequency
 
4- number of interrupts, and their call frequency
 
5-"sidetracking" by calls from main
 
 
in specific - i have ALWAYS preferred to time button up/down dynamics 
 
with a spare system timer and a simple BYTE check[4]
 
(for 4 buttons ) comparison table that counts down each table  element to zero on a multiple of appx 10 msecs from said system timer. | 
			 
		  | 
	 
	
		  | 
	 
	
		 | 
	 
 
  
	 
	    
	   | 
	
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
  
		 |