View previous topic :: View next topic |
Author |
Message |
TaiChipY Guest
|
Switch debouncing |
Posted: Sat Mar 05, 2005 11:37 am |
|
|
Hardware: 18F452, PICDEM2, ICD2
I have one button with two functions and its working thru if ,switch case plan...
Now I need to "read" faster qlicks on the same button so i can add another function ( basicly, something like mouse )...
This is the example...
*********
first slow click ---> one option
second slow click --> second option
third DOUBLE click ---> third option
***********
Double click function should be enabled in ANY time by quick double pressing.
How to make this? |
|
|
Guest
|
|
Posted: Sat Mar 05, 2005 4:02 pm |
|
|
You'll need a state machine by implementing switch/case statements:
Here are your states...
STATE_IDLE // No button pressed
STATE_BUTTON_PRESSED_ONCE
STATE_BUTTON_INITIALLY_RELEASED
STATE_BUTTON_PRESSED_TWICE
STATE_WAIT_FOR_RELEASE
You'll start off in IDLE state. If you hit the button, then go to state BUTTON_PRESSED_ONCE. Once you release the button, you will want to start a timer (e.g. timer1), and jump to next state STATE_BUTTON_INITIALLY_RELEASED. While in state BUTTON_INITIALLY_RELEASED, you will poll to see if your timer exceeds, say 1/2 second, and also poll to see if the button is hit again before the 1/2 second elapses. If the 1/2 second elapses without a second button press, then this is one function. If you hit the button before the 1/2 second timeout, then you go to STATE_BUTTON_PRESSED_TWICE. This is is your other function. In STATE_BUTTON_PRESSED_TWICE, you simply wait until the button is released, then this is your third function.
Your state machine routine should return an int that will tell the main function whether or not any buttons are pressed. Thus the return values can take on #defines such as:
BUTTON_NONE
BUTTON_CLICK_1X
BUTTON_DOUBLECLICK
So the state machine should just distinguish between a single click or a quick double click. It is up to your other software to do its thing with each successive single-click. |
|
|
libor
Joined: 14 Dec 2004 Posts: 288 Location: Hungary
|
|
Posted: Sat Mar 05, 2005 5:05 pm |
|
|
Sorry for the off-topic...
are you aware of the circumstance that there is a patent Microsoft holds for double clicking? So I think, you cannot implement double-clicking in your product without paying a royalty to MS.
Read about it here.
Don't you get me wrong, I disagree with patenting such trivial things like this that was already used by the Neanthertal-man to knock on the cave-door two times when he wanted his wife to come and once when he wanted his brother's help.
Don't you think, guys accross the sea, it is time to tidy up your patenting rules, they are ridiculous. |
|
|
Sherpa Doug Guest
|
Microsoft patented Double-click |
Posted: Sat Mar 05, 2005 5:19 pm |
|
|
Instead of calling it "double click" you could call it a Morse code "i". In Morse code e = dot, i = dot dot, s = dot dot dot, and h = dot dot dot dot. Morse code is long since out of patent.
Sherpa Doug |
|
|
Humberto
Joined: 08 Sep 2003 Posts: 1215 Location: Buenos Aires, La Reina del Plata
|
|
Posted: Sat Mar 05, 2005 8:15 pm |
|
|
libor wrote: Quote: |
Don't you get me wrong, I disagree with patenting such trivial things like this that was already used by the Neanthertal-man to knock on the cave-door two times when he wanted his wife to come and once when he wanted his brother's help.
Don't you think, guys accross the sea, it is time to tidy up your patenting rules, they are ridiculous.
|
Good point. The same way they patented the use of the ancestral
word "windows" instead of finding a genuine patentable word.
But the "Winboys" are not so bad, they still enable us to use freely
the words "doors", "house", "chair".....
Humberto |
|
|
dave
Joined: 21 Dec 2003 Posts: 7 Location: Sheffield, South Yorks, UK
|
The worlds gone mad |
Posted: Sun Mar 06, 2005 1:20 am |
|
|
This means then that any instrument that has employed double clicking to enable software functions will have to be withdrawn, wonder how many airlines will be sued by MS.......
Dave |
|
|
Douglas Kennedy
Joined: 07 Sep 2003 Posts: 755 Location: Florida
|
|
Posted: Sun Mar 06, 2005 8:15 am |
|
|
The Queen of England had to get Bill Gates permission to double click him on the shoulder as part of dubbing him Sir "something or other" when getting his Knighthood.There is a tension between patents encouraging innovation and thwarting innovation. Here in the US you could get a patent for almost anything. That's where a big company will protect its turf. The big guy patents just about anything and the small guy can't afford the huge legal expense of challenging it. Conversly if Microsoft didn't patent double clicking some small guy might do it and shake Microsoft down. Only if you invent something that is no use to anybody are you sure of a smooth ride. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Sun Mar 06, 2005 9:06 am |
|
|
Quote: | Conversly if Microsoft didn't patent double clicking some small guy might do it and shake Microsoft down. |
Not if Microsoft can show prior use. |
|
|
TaiChipY Guest
|
|
Posted: Mon Mar 07, 2005 7:04 am |
|
|
Now that's the spirit :-))). Like Bi G. has sad: MS has no monopol on the market we just improve old stuff :--) ... On some strange way :-)
*********
After some thinking and after examining the help files ( i got one interesting example how to solve my problem: thru rtcc. Maybe the case was not so good idea ( becuse of "holding in loop part")...
So..
After INT_RTCC stuff i have started with POLL functions in which im using
if's for poll, start_debounce, debounce, end_debounce..
q.)
Im poll state i have this situation:
------------------------------------
if (Gstate == poll)
{
cButton_state = cButton; // confirmation
iButton_state = iButton; // Infos
rButton_state = rButton; // reset
clock = 0;
read_new_state();
clock = 0;
return;
}
void read_new_state() // --- used for defining new changes
{
if (iButton_state != iButtonOLD)
{
iButton_change = TRUE;
}
else
iButton_change = FALSE;
if (cButton_state != cButtonOLD)
{
cButton_change = TRUE;
}
else
cButton_change = FALSE;
....
}
----------------------------------------------
1. press -- activate iButton -- display welcome
2. press -- activate cButton -- display number of clicks
block cButton until countdown ends -- start countdown
Now, wenn you press again on iButton other function should run
until cButton reaches some max value. After the maxValue is reached
i set maxValue to 0 and display welcome ( start again ).
********************************
Second SLOW press on iButton (1x)
-- display time left
Second SLOW press on iButton (2x)
-- display temperature
FAST press on iButton
-- show logo
**************************
So basicly:
iButton is activated for first time -->
cButton value is set to 1 --> button blocked for some time
iButton should now be able to make the ******* part.
This is repeating part until the cButton value has reached maxClickValue then i do something else..
Q.
Now that you have all the infos :--)..
How can i define the right way for button state.
The interupt is triggered each cca 32 sec ( 8Mhz). |
|
|
TaiChipY Guest
|
|
Posted: Mon Mar 07, 2005 7:05 am |
|
|
Now that's the spirit :-))). Like Bi G. has sad: MS has no monopol on the market we just improve old stuff :--) ... On some strange way :-)
*********
After some thinking and after examining the help files ( i got one interesting example how to solve my problem: thru rtcc. Maybe the case was not so good idea ( becuse of "holding in loop part")...
So..
After INT_RTCC stuff i have started with POLL functions in which im using
if's for poll, start_debounce, debounce, end_debounce..
q.)
Im poll state i have this situation:
------------------------------------
Code: |
if (Gstate == poll)
{
cButton_state = cButton; // confirmation
iButton_state = iButton; // Infos
rButton_state = rButton; // reset
clock = 0;
read_new_state();
clock = 0;
return;
}
void read_new_state() // --- used for defining new changes
{
if (iButton_state != iButtonOLD)
{
iButton_change = TRUE;
}
else
iButton_change = FALSE;
if (cButton_state != cButtonOLD)
{
cButton_change = TRUE;
}
else
cButton_change = FALSE;
....
} |
----------------------------------------------
1. press -- activate iButton -- display welcome
2. press -- activate cButton -- display number of clicks
block cButton until countdown ends -- start countdown
Now, wenn you press again on iButton other function should run
until cButton reaches some max value. After the maxValue is reached
i set maxValue to 0 and display welcome ( start again ).
********************************
Second SLOW press on iButton (1x)
-- display time left
Second SLOW press on iButton (2x)
-- display temperature
FAST press on iButton
-- show logo
**************************
So basicly:
iButton is activated for first time -->
cButton value is set to 1 --> button blocked for some time
iButton should now be able to make the ******* part.
This is repeating part until the cButton value has reached maxClickValue then i do something else..
Q.
Now that you have all the infos :--)..
How can i define the right way for button state.
The interupt is triggered each cca 32 sec ( 8Mhz). |
|
|
valemike Guest
|
Re: Microsoft patented Double-click |
Posted: Mon Mar 07, 2005 7:44 am |
|
|
Sherpa Doug wrote: | Morse code is long since out of patent.
Sherpa Doug |
Speaking of things being "out of patent", how long can a patent exist until it is no longer renewable and open to the public to use? 20 years? 25 years? |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1909
|
|
Posted: Mon Mar 07, 2005 10:06 am |
|
|
With a patent, you have 20 years from the date you applied for the thing. Realistically, a patent has a "working life" of about 13 - 14 years at most. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Mon Mar 07, 2005 10:20 am |
|
|
A utility patent lasts 20 years from the date of the filing of the application. If a patent application is a continuation of another application, then the 20 years begins on the date the earliest application was filed.
A plant patent also lasts 20 years from the date of the filing of the patent application. If an earlier application has been filed for the same plant, then the 20 years begin of the date of filing of the earliest application.
Design patents only last for 14 years but the 14 years begin on the date the patent is actually granted.
For all patents, the patent protection does not actually begin until the patent is granted.
Patents may be extended only by a special act of Congress (except for certain spam patents).
I am speaking of US patents. |
|
|
TaiChipY Guest
|
|
Posted: Mon Mar 07, 2005 11:18 am |
|
|
Can someone please give me some code example how to solve my problem. Im newbee in this part and i really want to try this out so please be so kind...
Wenn im done i will start new topic on Billy G. ,double clicks and patents
TaiChipY
*********
Linux rules
********* |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Mon Mar 07, 2005 12:58 pm |
|
|
Here is some code for the PICDEM2 PLUS board
Code: |
#include <18F252.h>
#use delay(clock=10000000)
#fuses HS, NOWDT, PUT, NOLVP
#define DOUBLE_CLICK_TIME 500
#define SWITCH_READ_TIME 30
// Different types of click events
enum SWITCH_STATES
{
SINGLE_CLICK,
DOUBLE_CLICK
};
// Our system timer
int8 Miliseconds;
// How often we read the switch inputs
int8 Read_Switch_Timer = 0;
// Signal to read the switches
int1 Read_Switch_Flag = FALSE;
// Timeout value or in this case the double click time
int16 Click_Timer = 0;
enum SWITCH_STATES Switch_State;
// Timer 2 is our system tick
#int_timer2
void timer2_isr(void)
{
if (Miliseconds < 0xFF)
Miliseconds++;
}
// Handles what happens when we release a switch
void Switch_Released(void)
{
if (Click_Timer)
Switch_State = DOUBLE_CLICK;
else
Switch_State = SINGLE_CLICK;
Click_Timer = DOUBLE_CLICK_TIME;
}
// Handles what happens when we press a switch
void Switch_Pressed(void)
{
}
// Handles debouncing of the switches
void Switch_Read_Value(void)
{
static int1 last_read = 1;
static int1 last_state = 1;
int1 result;
static int8 debounce_count;
// Read the current result
result = input(PIN_A4);
// See if it changed
if (result != last_read)
{
// It did so debounce it
debounce_count = 5;
last_read = result;
}
// We are debouncing
else if (debounce_count)
{
debounce_count--;
// Done debouncing
if (debounce_count == 0)
{
// See if the state of the switch has changed
if (result != last_state)
{
// Determine what type of event occurred
if (result)
Switch_Released();
else
Switch_Pressed();
// Save the current state
last_state = result;
}
}
}
}
// What we do on a single click
void Single_Click_Event(void)
{
// Light an LED on RB3 of the picdem2 plus board
output_high(PIN_B3);
}
void Double_Click_Event(void)
{
// Turn off the LED on RB3 of the picdem2 plus board
output_low(PIN_B3);
}
// Handles all our switch timers
void Switch_Timers(void)
{
if (Read_Switch_Timer == 0)
Read_Switch_Timer--;
else
Read_Switch_Flag = TRUE;
if (Click_Timer)
{
Click_Timer--;
if (Click_Timer == 0)
{
switch (Switch_State)
{
case SINGLE_CLICK:
Single_Click_Event();
break;
case DOUBLE_CLICK:
Double_Click_Event();
break;
default:
break;
}
}
}
}
// Handles all our switch tasks
void Switch_Tasks(void)
{
if (Read_Switch_Flag)
{
Switch_Read_Value();
Read_Switch_Timer = SWITCH_READ_TIME;
Read_Switch_Flag = FALSE;
}
}
// System counter
void System_Tick(void)
{
while (Miliseconds)
{
Switch_Timers();
Miliseconds--;
}
}
void main (void)
{
// Setup timer2 to int every 1ms
setup_timer_2(T2_DIV_BY_4,125,5);
enable_interrupts(INT_TIMER2);
enable_interrupts(GLOBAL);
// Start counting now
Miliseconds = 0;
while(1)
{
System_Tick();
Switch_Tasks();
}
}
|
|
|
|
|