|
|
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
|