Skip to main content
Skip table of contents

13.2.10 Interrupt Counter with Debounce [T-Series Datasheet]


T4 Capable DIO: DIO4, DIO5, DIO6, DIO7, DIO8, DIO9 (aka FIO4, FIO5, FIO6, FIO7, EIO0, EIO1)

T7 Capable DIO: DIO0, DIO1, DIO2, DIO3, DIO6, DIO7 (aka FIO0, FIO1, FIO2, FIO3, FIO6, FIO7)

T8 Capable DIO: DIO0, DIO1, DIO2, DIO3, DIO4, DIO5, DIO6, DIO7, DIO8, DIO9, DIO10, DIO11, DIO12, DIO13, DIO14, DIO15 (aka FIO0, FIO1, FIO2, FIO3, FIO4, FIO5, FIO6, FIO7, EIO0, EIO1, EIO2, EIO3, EIO4, EIO5, EIO6, EIO7)

Requires Clock Source: No

Index: 9

Streamable: No.

Interrupt Counter with Debounce will increment its count by 1 when it receives a rising edge, a falling edge, or any edge (2x counting).  After seeing an applicable edge, any further edges will be ignored during the debounce time.

This interrupt-based digital I/O extended feature (DIO-EF) is not purely implemented in hardware, but rather firmware must service each edge.  See the discussion of edge rate limits at the bottom of this page.

Debounce Modes (DIO#_EF_CONFIG_B)

The exact behavior of the counting/debouncing is controlled by an index value written to DIO#_EF_CONFIG_B.

  • 0:  Count falling, debounce all, self-restarting timeout.
  • 1:  Count rising, debounce all, self-restarting timeout.
  • 2:  Count & debounce all, self-restarting timeout.
  • 3:  Count & debounce falling, fixed timeout.
  • 4:  Count & debounce rising, fixed timeout.
  • 5:  Timeout starts on falling edge.  During timeout, a rising edge cancels and a falling edge restarts the timeout.  After timeout any edge causes a count.
  • 6:  Timeout starts on rising edge.  During timeout, a falling edge cancels and a rising edge restarts the timeout.  After timeout any edge causes a count.

Self-restarting timeout means that during timeout any edge will restart the timeout with the value specified with DIO#_EF_CONFIG_A.

Mode 0 is commonly used with a normally-open push-button switch that is actuated by a person.  We only want to count the push (falling edge), but expect bounce on the push & release (falling & rising edges) so need to debounce both.

Mode 4 might be used with some sort of device that outputs a fixed length positive pulse.  For example, say a device provides a 1000 µs pulse, and there is always at least 5000 µs between pulses.  Set the debounce timeout to 2000 µs so that the timeout period safely covers the entire pulse, but the timeout will for sure be done before another pulse can occur.

Modes 5 & 6 implement a requirement that the state of the line must remain low or high for some amount of time.  For example, if you use mode 5 with a push-button switch and set DIO#_EF_CONFIG_A = 50000, that means that someone must push the switch and hold it down solidly for at least 50ms, and then the count will occur when they release the switch.  An advantage to these modes is that they will ignore brief transient signals.


DIO#_EF_ENABLE: 0 = Disable, 1 = Enable
DIO#_EF_CONFIG_A: Debounce timeout in microseconds (µs, 0-1000000).
DIO#_EF_CONFIG_B: Debounce mode index. 
DIO#_EF_CONFIG_B: Not used.
DIO#_EF_CONFIG_B: Not used.


No update operations can be performed on Interrupt Counter with Debounce.


Results are read from the following register.

DIO#_EF_READ_A: Returns the current Count


DIO#_EF_READ_A_AND_RESET: Reads the current count then clears the counter. Note that there is a brief period of time between reading and clearing during which edges can be missed. During normal operation this time period is 10-30 µs. If missed edges at this point can not be tolerated then reset should not be used.


Enable a debounce counter on DIO0 (use DIO4 on the T4):

DIO0_EF_CONFIG_A = 20000   // 20 ms debounce time
DIO0_EF_CONFIG_B = 0       // count falling, debounce all, self-restarting timeout

Results can be read from the READ registers defined above. 

Edge Rate Limits

This interrupt-based digital I/O extended feature (DIO-EF) is not purely implemented in hardware, but rather firmware must service each edge. This makes it substantially slower than other DIO-EF that are purely hardware-based.  To avoid missed edges, the aggregate limit for edges seen by all interrupt-based DIO-EF is 70k edges/second.  If stream mode is active, the limit is reduced to 20k edges/second.  Excessive processor loading (e.g. a busy Lua script) can also reduce these limits.  Note that interrupt features must process all edges, rising & falling, even if a given feature is configured to only look at one or the other. Additionally, note that intensive interrupt based features may limit the maximum streaming rates due to processor loading.

The more proper way to think of the edge limit, and understand error that could be introduced when using multiple interrupt-based DIO-EF, is to consider that the interrupt that processes an edge can take up to 14 μs to complete.  When a particular channel sees an applicable edge, an IF (interrupt flag) is set for that channel that tells the processor it needs to run an ISR (interrupt service routine) for that channel.  Once an ISR is started, it runs to completion and no other ISR can run until it is done (except that stream interrupts are higher priority and will preempt other interrupts).  When an ISR completes, it clears the IF for that channel.  So it is okay to have edges on multiple channels at the same time, as long as there is not another edge on any of those channels before enough time to process all the initial edges.

Say that channel A & B have an edge occur at the same time and an ISR starts to process the edge on channel A.  If channel A has another edge during the first 14 μs, that edge will be lost.  If channel B has another edge during the first 14 μs, the initial edge will be lost.  If channel B has another edge during the second 14 μs (during the ISR for channel B), the new edge will be lost.

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.