Searching \ for '[PIC] debouncing in c' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/languages.htm?key=c
Search entire site for: 'debouncing in c'.

Exact match. Not showing close matches.
PICList Thread
'[PIC] debouncing in c'
2006\04\03@184509 by David VanHorn

picon face
In general, I don't like to tie things like this to code execution speed, so
I use a timer to generate a 1mS system int and drive all the events at 10mS
and larger timing from that.

So in keyboard scanning, when I see a change on the inputs at the hardware
level, I load a byte in SRAM with the debounce time.
If I see another change, I reload the byte.

The 1mS tick int decs that byte to 0.
If the byte gets to 0, then I update the image of the keyboard, and signal
in a bit that the keyboard has changed.
When the key routine picks up the information, it clears this bit, which
prevents it from seeing a single long press as multiple single presses (and
provides a way to do auto-repeat)

2006\04\03@203035 by David VanHorn

picon face
> 2/ In a realtime environment, say spacewars, a faster response system,
> such as vertical counters can detect the end of the bouncing and give
> the faster response.


Ok, I must admit  I've read the vertical counter thing, but I just don't see
the light yet.
Can you rephrase it maybe?

Always willing to see another way.

2006\04\03@212803 by James Newtons Massmind

face picon face
>
> > 2/ In a realtime environment, say spacewars, a faster
> response system,
> > such as vertical counters can detect the end of the
> bouncing and give
> > the faster response.
>
>
> Ok, I must admit  I've read the vertical counter thing, but I
> just don't see the light yet.
> Can you rephrase it maybe?
>
> Always willing to see another way.

Given a switch that bounces, and there are some that don't, then the time
you wait for the switch to stop bouncing sets an upper limit on how
frequently the switch can be activated.

Vertical counters or other advanced debounce routines work in the least
possible time, providing reliable debounce while, at the same time, allowing
rapid actuation of the switch.

The primary application would be one where very low cost or primitive
switches must be used and will be opened and closed at a rate that
approaches the bounce rate of the switch.

For most applications, just use a good switch if you need speed and if you
don't, use a crappy switch and check it a few times a second.

---
James.


2006\04\03@213129 by David P Harris

picon face
David VanHorn wrote:

>>2/ In a realtime environment, say spacewars, a faster response system,
>>such as vertical counters can detect the end of the bouncing and give
>>the faster response.
>>    
>>
>
>
>Ok, I must admit  I've read the vertical counter thing, but I just don't see
>the light yet.
>Can you rephrase it maybe?
>
>Always willing to see another way.
>  
>
Instead of having the bits of a counter in a byte, you spread them over
several bytes.  The first byte contains the most insignificant bit of a
number of counters, the next byte the next significant bits of the
counters.  Now you can count all the counters at once using logic
operations.  It is useful where you only need 2-3 bits for a counter.  
So, in this application, you can have 8 2-bit counters in two bytes.

That help?

David


2006\04\03@222800 by Gerhard Fiedler

picon face
David VanHorn wrote:

>> 2/ In a realtime environment, say spacewars, a faster response system,
>> such as vertical counters can detect the end of the bouncing and give
>> the faster response.
>
> Ok, I must admit  I've read the vertical counter thing, but I just don't see
> the light yet.
> Can you rephrase it maybe?

If I understand this correctly, David (Harris) is pretty much talking about
the same thing you are talking about. Vertical counters are just a code and
space efficient means to do the counting for several input pins.

They're called "vertical" because you don't have a byte associated to an
input pin and count through the bits of that byte -- that would be
"horizontal" --, instead you have a bit associated to an input pin and
count through several instances of this bit in different bytes. Less waste
of storage (most of the bits in the "horizontal" counters are not used) and
less instructions (you may be able to read a whole port into a byte of a
vertical counter -- the data comes already in a "vertical" format).

Not sure this description was clearer :)  but it's hard to describe
vertical counters in words.

Gerhard

2006\04\03@230725 by David VanHorn

picon face
>
>
> They're called "vertical" because you don't have a byte associated to an
> input pin and count through the bits of that byte -- that would be
> "horizontal" --, instead you have a bit associated to an input pin and
> count through several instances of this bit in different bytes. Less waste
> of storage (most of the bits in the "horizontal" counters are not used)
> and
> less instructions (you may be able to read a whole port into a byte of a
> vertical counter -- the data comes already in a "vertical" format).


Hmm.. I think I see, I need to work through an AVR implementation.

In a recent case, I took an 8 bit keypad and debounced it with a single
byte, but what I was doing was treating the byte as a single entity. My
rules required that I see no change on any of the bits until the timer
expired.

Not sure this description was clearer :)  but it's hard to describe
> vertical counters in words.


:)  I think that's my problem, I'm having a hard time picturing it.

It's a fun business we're in, some things are so simple, yet so hard to
describe.

2006\04\04@072508 by olin piclist

face picon face
David P Harris wrote:
> Instead of having the bits of a counter in a byte, you spread them over
> several bytes.  The first byte contains the most insignificant bit of a
> number of counters, the next byte the next significant bits of the
> counters.  Now you can count all the counters at once using logic
> operations.  It is useful where you only need 2-3 bits for a counter.
> So, in this application, you can have 8 2-bit counters in two bytes.

Which of course has nothing directly to do with debouncing a switch.  This
is a technique for working on several counters in parallel with fewer
instruction than it would take to handle each one separately.  But it's
still using counters, which is how the debouncing is done.  Saying that
vertical counters is a special debouncing technique is misleading at best.


******************************************************************
Embed Inc, Littleton Massachusetts, (978) 742-9014.  #1 PIC
consultant in 2004 program year.  http://www.embedinc.com/products

2006\04\04@082842 by Gerhard Fiedler

picon face
David VanHorn wrote:

>> Not sure this description was clearer :)  but it's hard to describe
>> vertical counters in words.
>
> :)  I think that's my problem, I'm having a hard time picturing it.

Inputs A, B, C, ... G, H (8 inputs)

Counter bits 0, 1, 2 (3 bit-counters, count to 8)
  x: not used

One byte per line
Bit positions described by a letter (for the associated input) and a number
(for the bit position in the counter associated with that input)

Horizontal counters:
 Ax Ax Ax Ax Ax A2 A1 A0
 Bx Bx Bx Bx Bx B2 B1 B0
 Cx Cx Cx Cx Cx C2 C1 C0
 Dx Dx Dx Dx Dx D2 D1 D0
 Ex Ex Ex Ex Ex E2 E1 E0
 Fx Fx Fx Fx Fx F2 F1 F0
 Gx Gx Gx Gx Gx G2 G1 G0
 Hx Hx Hx Hx Hx H2 H1 H0

Vertical counters:
 H0 G0 F0 E0 D0 C0 B0 A0
 H1 G1 F1 E1 D1 C1 B1 A1
 H2 G2 F2 E2 D2 C2 B2 A2

See why they are called "vertical"? :)  The handling itself is more
complicated for vertical counters, but it has to be done only once for a
whole set of 8 inputs. (And Scott already explained how to do it :)

I don't think they make sense for two or three inputs. Not sure where the
threshold is. I guess the threshold depends also on the number of counts.

Gerhard

2006\04\04@094844 by Scott Dattalo

face
flavicon
face
On Tue, 2006-04-04 at 09:26 -0300, Gerhard Fiedler wrote:
{Quote hidden}

Your illustration succinctly makes the point! Also checkout:
http://www.dattalo.com/technical/software/pic/vertcnt.html


> I don't think they make sense for two or three inputs. Not sure where the
> threshold is. I guess the threshold depends also on the number of counts.

It takes 3 instructions to increment 8 2-bit vertical counters. It takes 6
instructions to increment 8 3-bit counters. It takes more than 8
instructions to increment 8 4-bit counters. So the break even point for
incrementing is around 3 or 4 bits. Depending on the situation, a 4-bit
vertical counter may be more advantageous than a 4-bit horizontal counter.
For switch debouncing, 0 (Wouter's implementation), 1 or 2 bits are
sufficient. For RTU SOE inputs or SBO's, 3 or 4 bits would cover most
applications.

Vertical adders take a minimum of 6 instructions per bit. However, I
haven't found a need yet for vertical adders.

Scott

2006\04\04@220541 by kravnus wolf

picon face
excellent explaination there. a definite keeper.

john

--- Scott Dattalo <spam_OUTscottTakeThisOuTspamdattalo.com> wrote:

{Quote hidden}

www.dattalo.com/technical/software/pic/vertcnt.html
{Quote hidden}

> --

2006\04\05@010658 by David P Harris

picon face
Olin Lathrop wrote:

>David P Harris wrote:
>  
>
>>Instead of having the bits of a counter in a byte, you spread them over
>>several bytes.  The first byte contains the most insignificant bit of a
>>number of counters, the next byte the next significant bits of the
>>counters.  Now you can count all the counters at once using logic
>>operations.  It is useful where you only need 2-3 bits for a counter.
>>So, in this application, you can have 8 2-bit counters in two bytes.
>>    
>>
>
>Which of course has nothing directly to do with debouncing a switch.  This
>is a technique for working on several counters in parallel with fewer
>instruction than it would take to handle each one separately.  But it's
>still using counters, which is how the debouncing is done.  Saying that
>vertical counters is a special debouncing technique is misleading at best.
>  
>
Gee, did I say that?  I don't think so, I was just trying to explain
vertical counters :-)   I agree, vertical counters is a general
technique that can be applied to debouncing.

David


2006\04\05@135531 by Peter

picon face


On Tue, 4 Apr 2006, Gerhard Fiedler wrote:

{Quote hidden}

No, it does not. Vertical counters can be expanded to more than 8 bits
easily.

Peter

2006\04\05@140022 by Peter

picon face

On Tue, 4 Apr 2006, Scott Dattalo wrote:

> Vertical adders take a minimum of 6 instructions per bit. However, I
> haven't found a need yet for vertical adders.

This looks like a good time to ask: do you have code to rotate the 8x8
matrix of vertical counter bits into a 8x8 matrix of horizontal counters
? (not necessarily in order ot adjacent) ?

thanks ;-)
peter

2006\04\05@141424 by David VanHorn

picon face
Ok, I guess I WAS getting it all along! :)
I typically use 25mS for debouncing in a 1mS int, so I'd have to run out to
5 bytes.

I'll have to work it up for the AVR and see how it compares.

Currently, it's like this for each counter:
no tabs in gmail... :(

Count_Thing:
lds    itemp,Thing_Counter ;2 clocks
and   itemp,itemp ;1 clock
breq   Count_Thing_Done ;2 if branch taken, 1 if not
dec   itemp ;1 clock
sts   Thing_Counter,itemp ;2 clocks
Count_Thing_Done: ;dummy label


7 clocks while decing, 5 if not, so at 1 MHz, that's 7 or 5 uS
I could take 2 more clocks out if I used a register for thing_counter, but
that would be silly.


--
Feel the power of the dark side!  Atmel AVR

2006\04\05@142005 by Scott Dattalo

face
flavicon
face
Peter wrote:
> On Tue, 4 Apr 2006, Scott Dattalo wrote:
>
>
>>Vertical adders take a minimum of 6 instructions per bit. However, I
>>haven't found a need yet for vertical adders.
>
>
> This looks like a good time to ask: do you have code to rotate the 8x8
> matrix of vertical counter bits into a 8x8 matrix of horizontal counters
> ? (not necessarily in order ot adjacent) ?

This is called a corner-bender. I don't have the code to do this, but
the fastest PIC solution is 128 cycles (2-cycles/bit). But like the
vertical adders, I've never needed to do this in firmware.

Scott

2006\04\05@144632 by David VanHorn

picon face
I wasn't clear there, this debouncer takes care of N keys.
A foreground task compares current key state to stored key state, and
re-loads the timer if it detects a change.  If the timer goes to 0, then I
save the state of the switches as debounced, and set a bit flag that tells
tasks that there are new switches.

Key_scan:
 ;assuming 8 keys on a port, but could be any  number
 ;could be multiple ports.

 in  temp,pina            ;get current key state
 lds  temp2,old_keys  ;State the last time I looked
 cp  temp,temp2        ;Same?
 breq  key_scan_check  ;Just let them run

 ldi  temp,Key_debounce_time ;Restart the debounce timer
 sts Thing_counter,temp   ;named so this meshes with the isr
 sts old_keys,temp2        ;save state for next scan
 ret                                 ;

Key_Scan_Check:
 lds  temp,thing_counter  ;keys stable?
 and  temp,temp  ;is it 0?
 brne  keys_done  if not, then just wait
 sts  debounced_keys,temp2 ;
 sbr  sysflags,1<<new_keys ;Sets a bit in sysflags
; When the appropriate routine has seen the keys, it clears
;this bit. Other routines can just look at debounced_keys
;for the current state.
Keys_done:

--
Feel the power of the dark side!  Atmel AVR

2006\04\05@163627 by Scott Dattalo

face
flavicon
face
David VanHorn wrote:
> I wasn't clear there, this debouncer takes care of N keys.
> A foreground task compares current key state to stored key state, and
> re-loads the timer if it detects a change.  If the timer goes to 0, then I
> save the state of the switches as debounced, and set a bit flag that tells
> tasks that there are new switches.
>
> Key_scan:
>   ;assuming 8 keys on a port, but could be any  number
>   ;could be multiple ports.

<snip>

David,

Your routine appears to handle only 1 switch press at a time. If you
want to handle multiple presses and still use debouncing, then here's an
AVR version of my debounce routine:

    ;Increment the vertical counter
        EOR     count_A,count_B
        COM     count_B

    ;See if any changes occurred
        IN      temp, pina
        EOR     temp, cva

    ;Reset the counter if no change has occurred
        AND     count_B,temp
        AND     count_A,temp

    ;If there is a pending change and the count has
    ;rolled over to 0, then the change has been filtered

        COM     temp            ;Invert the changes
        OR      temp, count_A   ;If count is 0, both A and B
        OR      temp, count_B   ;bits are 0

    ;Any bit in temp that is clear at this point means that the input
    ;has changed and the count has rolled over.

        COM     temp

    ;Now temp holds the state of inputs that have just been filtered
    ;to a new state. Update the changes:

        EOR     cva, temp

    ;leave with temp holding the state of all filtered bits that have
    ;change state

        RET


cva, count_A, count_B and temp are all in register memory.

Scott

PS This is the first AVR program I've ever "written". But I really just
babelfished PIC into AVR and may've made a mistake.

2006\04\05@170206 by David VanHorn

picon face
>
>
> David,
>
> Your routine appears to handle only 1 switch press at a time. If you
> want to handle multiple presses and still use debouncing, then here's an
> AVR version of my debounce routine:


It does as many as you'd like.
There's a non-int part that compares the old switch image to the current
switches, and if different, restarts the timer.

In the ISR, the timer is dec'd to 0, and on rolling to 0 we update the
debounced image in ram, and set a flag to say that the switches have changed
state.  Usually I have one task that needs to be woken up when something
changed, and others that just look at the current state of the debounced
image.


--
> Feel the power of the dark side!  Atmel AVR

2006\04\05@171735 by Scott Dattalo

face
flavicon
face
David VanHorn wrote:
>>
>>David,
>>
>>Your routine appears to handle only 1 switch press at a time. If you
>>want to handle multiple presses and still use debouncing, then here's an
>>AVR version of my debounce routine:
>
>
>
> It does as many as you'd like.

As long as all are stable for the debounce time interval... I'm sure
this approach is just fine for handling normal keypads. It certainly is
efficient to have just one timer for N-switches. However, imagine you
had one switch (or relay or whatever) that is constantly changing
states. This unstable input prevents the debounce timer from ever
terminating, which in turn means the other switches can not be read!

Scott

2006\04\05@172823 by David VanHorn

picon face
>
>
> As long as all are stable for the debounce time interval... I'm sure
> this approach is just fine for handling normal keypads. It certainly is
> efficient to have just one timer for N-switches. However, imagine you
> had one switch (or relay or whatever) that is constantly changing
> states. This unstable input prevents the debounce timer from ever
> terminating, which in turn means the other switches can not be read!


Sure, then you'd want to debounce that input separately.
My approach makes the assumption that all the switches in the group are
similar, and have similar response time needs.





> --
> Feel the power of the dark side!  Atmel AVR

2006\04\05@192010 by Gerhard Fiedler

picon face
Peter wrote:

>> I don't think they make sense for two or three inputs. Not sure where the
>> threshold is. I guess the threshold depends also on the number of counts.
>
> No, it does not. Vertical counters can be expanded to more than 8 bits
> easily.

I'm not sure we understand each other here... What I meant was that the
number of inputs from which on it makes sense to use vertical counters
depends on the number of counts you want to count for each input.

Let's say we have 8 inputs. That's maximum efficiency of the vertical
counters, and also maximum effort for the horizontal counters, so it's the
situation where typically vertical counters make most sense. And they do if
you count to 3, or to 7. But what if you count to 255? I think (not sure
though) that in this case, horizontal counters are better code-wise and the
same memory-wise.

Which means that the threshold (number of inputs) from which on it makes
sense to use vertical counters depends on the number of counts -- or am I
missing something?

This has nothing to do with the fact that of course vertical counters can
expanded easily (usually in byte steps, on normal PICs at least).

Gerhard

2006\04\05@204946 by Scott Dattalo

face
flavicon
face
Gerhard Fiedler wrote:
{Quote hidden}

Gerhard,

You're not missing anything. Each additional vertical bit takes 4 more
instructions:

   ; carryOut = carry from previous stage

    movf  carryOut,W    ; get the carry from the previous stage
    xorwf stageN,F      ; add it to this bit stage
    xorwf stageN,W      ; get the original bit back
    andwf carryOut,F    ; If there was a carry-in and this bit was
                        ; set, then we have a carry for the next stage.


There are optimizations for the first few bits, but the number of
instructions to increment a vertical are:

   instructions = (# of bits - 3)*4 + 6

So, an 8-bit vertical counter takes 26 instructions. If you're using the
vertical counters to count events, then the number of instructions
increase to:

   instructions = (# of bits) * 4 - 1

Or 31 cycles for 8 counters. Neither of these are too efficient compared
to the 8 or 16 instructions for the equivalent 8 horizontal counters.
However, imagine a design requiring 4 instructions per horizontal
counter. It's possible that the vertical counter comes out ahead. For
example, you might want to count the high-time on an I/O port during a
fixed period of time and stop counting if the counter has reached the
maximum (e.g. measure the duty cycle on 8 inputs). A horizontal
implementation would be:

     movf  PORT,W
     movwf temp

     clrz

     btfsc temp,0     ;Is bit 0 set?
      incf count0,F   ;yep, count it
     skpnz            ;did the counter overflow?
      decf count0,F   ;yep, remove that count. This counter is
                      ;through

   ; repeat for bits 1 through 7


The vertical solution would be something like:

  ; countEnable is initialized with 0xff at the very start.

  ; Read the current I/O port setting:

     movf  PORT,W

  ; if the counter is enabled and the I/O bit is high,
  ; then count it

     andwf countEnable,W
     movwf carryOut

     xorwf bit0,F
     xorwf bit0,W
     andwf carryOut,F

     movf  carryOut,W
     xorwf bit1,F
     xorwf bit1,W
     andwf carryOut,F

     movf  carryOut,W
     xorwf bit2,F
     xorwf bit2,W
     andwf carryOut,F

  ; repeat for bits 3 through 6

     movf  carryOut,W
     xorwf bit7,F
     xorwf bit7,W
     andwf carryOut,W

  ; All bits set in W correspond to counters that have rolled
  ; over. Turn off all of those counters

     xorwf countEnable,F

Both solutions take 35 instructions! But now imagine you add the twist
that you want to measure how long it takes for all 8 counters to reach
256. For this contrived example, the vertical counter implementation
takes only two more instructions:

     akpnz
      goto  allCountersHaveTerminated


Scott

2006\04\05@225716 by Gerhard Fiedler

picon face
Scott Dattalo wrote:

>> Which means that the threshold (number of inputs) from which on it makes
>> sense to use vertical counters depends on the number of counts -- or am I
>> missing something?
>
> You're not missing anything.

Thanks a lot -- you're the "vertical" man :)

Maybe summarizing and generalizing what I understand so far: with vertical
logic, you work basically with bits; that is, if you increment e.g. a 4 bit
counter, you do that bit by bit -- only that you do that with byte
instructions, 8 such bits side by side.

So the comparison (vertical vs horizontal) depends on how many such bits
need to be processed (the lesser, the more advantage for the horizontal
solution) and the specific processing (as some horizontal operations need a
lot more vertical operations to simulate them -- even though the IO
operations are vertical, the ALU works horizontally).

It seems that close to 8 (or multiples) inputs and relatively simple logic
(like a 2 bit counter) are the strongholds of vertical processing.

Gerhard

2006\04\06@133448 by Peter

picon face


On Wed, 5 Apr 2006, Gerhard Fiedler wrote:

{Quote hidden}

The vertical counter uses two instructions per counter bit with one to
eight inputs. It can be larger than 8 bits (simply add stages at linear
cost). A normal horizontal counter uses one byte per counter for any
count from 1 to 255, two for any from 256 to 65535 etc. The vertical
counter uses exactly as many bytes as there are bits in the counter.
Bits here, means counter depth, not number of inputs. Of course it makes
little sense to use it for just one or two input bits.

Peter

2006\04\06@161428 by Gerhard Fiedler

picon face
Peter wrote:

>>>> I don't think they make sense for two or three inputs. Not sure where the
>>>> threshold is. I guess the threshold depends also on the number of counts.
>>>
>>> No, it does not. Vertical counters can be expanded to more than 8 bits
>>> easily.
>>
>> I'm not sure we understand each other here... What I meant was that the
>> number of inputs from which on it makes sense to use vertical counters
>> depends on the number of counts you want to count for each input.
>>
>> Let's say we have 8 inputs. That's maximum efficiency of the vertical
>> counters, and also maximum effort for the horizontal counters, so it's the
>> situation where typically vertical counters make most sense. And they do if
>> you count to 3, or to 7. But what if you count to 255? I think (not sure
>> though) that in this case, horizontal counters are better code-wise and the
>> same memory-wise.
>
> The vertical counter uses two instructions per counter bit with one to
> eight inputs.

I'm sure Scott would like to know how you do that :)  Did you see his post?
He wrote:

> There are optimizations for the first few bits, but the number of
> instructions to increment a vertical are:
>
>     instructions = (# of bits - 3)*4 + 6


Anyway, you say it's 16 instructions for a vertical 8 bit counter, Scott
says it's 26 instructions. Both are more than the 8 instructions that 8
horizontal counters need to count up to 255.

Of course vertical counters are more efficient for 8 inputs with a 2 bit
counter each. But they don't seem to be necessarily more efficient for 8
inputs with an 8 bit counter each... Still not convinced that the
break-even point depends (among other things) on the number of counts (that
is, the number of bits in the counters)?

Gerhard

2006\04\07@134819 by Peter

picon face

On Thu, 6 Apr 2006, Gerhard Fiedler wrote:

> Peter wrote:
>>
>> The vertical counter uses two instructions per counter bit with one to
>> eight inputs.
>
> I'm sure Scott would like to know how you do that :)  Did you see his post?
> He wrote:

I meant four ;-( The point was that the vc uses the counter bits more
efficiently than a horizontal counter that counts to less than 255, if
five or more vertical counters are used. Since most debounce counters
etc count to less than 255, vertical counters are very nice to have to
do reading and debouncing chorded inputs. Also vertical counters are not
limited to 255 counts, you can add bits at linear cost.

Peter

More... (looser matching)
- Last day of these posts
- In 2006 , 2007 only
- Today
- New search...