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

onKeyUp method and deboucing for buttons - VBtn Library

 
Post new topic   Reply to topic    CCS Forum Index -> Code Library
View previous topic :: View next topic  
Author Message
opvini



Joined: 27 Apr 2012
Posts: 50
Location: Brazil

View user's profile Send private message

onKeyUp method and deboucing for buttons - VBtn Library
PostPosted: Thu Sep 06, 2012 12:32 am     Reply with quote

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: 2116
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Wed Sep 19, 2012 12:23 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Nov 12, 2012 5:06 am     Reply with quote

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

View user's profile Send private message

Bouncing treatment now
PostPosted: Tue Apr 29, 2014 4:37 pm     Reply with quote

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: 2116
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Thu May 15, 2014 3:03 pm     Reply with quote

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.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> Code Library All times are GMT - 6 Hours
Page 1 of 1

 
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