Expand description
Debounce a noisy digital input signal.
Even digital input signals can be noisy. The example usually cited is the flapping of physical contacts in a button or switch, but RF line noise can also cause digital input signals to bounce. Robust devices and embedded systems must debounce inputs.
This crate is a batteries-included embedded-hal
InputPin
debouncer, using the integration-based algorithm described by
Kenneth A. Kuhn in a code sample on his website. You are
highly recommended to read the code comments there.
§Minimum supported Rust version
This crate makes use of trait bounds on a const fn
, which
requires Rust 1.61.
§Usage
You need to bring just a few things:
- An
InputPin
, perhaps provided by a peripheral access crate (PAC) or hardware abstraction layer (HAL) for your chip. - An implementation of the
Debounce
trait, maybe just one from thedefault
module. - Some way to regularly call the
poll()
method at about the right frequency (where “right” depends on theDebounce
trait implementation, about 100Hz fordefault::ActiveHigh
ordefault::ActiveLow
). This may be done in an interrupt service routine (ISR), or it could be a spin-delayed call from your main loop. - Storage for the debounce state. If you’re using an ISR for
polling, you’ll want this to be a
static
.
Once you’ve worked out these details, the unflappable
crate will
take care of the rest.
[dependencies]
unflappable = "0.2"
Your implementation will consist of three major steps:
§Create the debouncer.
If you’re storing state in a static
, that might be:
use unflappable::{debouncer_uninit, Debouncer, default::ActiveLow};
static DEBOUNCER: Debouncer<PinType, ActiveLow> = debouncer_uninit!();
§Initialize the debouncer.
Next, initialize the Debouncer
. You pass in the
input pin and get back the debounced pin. If you’re storing state
in a static
, that might look like this:
fn try_main() -> Result<(), Error> {
let switch_pin = get_pin_from_hardware(33);
let mut led_pin = get_pin_from_hardware(42);
let debounced_switch = unsafe { DEBOUNCER.init(switch_pin) }?;
loop {
if debounced_switch.is_high()? {
led_pin.set_high()?;
}
}
Ok(())
}
See the docs on the init()
method for
safety details. Generally, if you haven’t yet enabled interrupts
you’ll be fine.
§Poll the debouncer.
On a regular basis, make a call to the poll()
method of Debouncer
, which might look like this:
fn try_isr() -> Result<(), Error> {
unsafe {
DEBOUNCER.poll()?;
}
Ok(())
}
Again, see the docs on the relevant method for safety information.
The main idea here is that you should only ever poll()
from one
place in your code. We’d use a &mut
reference, but, well, it’s
in static storage.
Modules§
- default
- Some default configurations.
Macros§
- debouncer_
uninit - Create a new uninitialized
Debouncer
.
Structs§
- Debounced
- A debounced pin.
- Debouncer
- A pin debouncer.
- Init
Error - An error indicating that once-only initialization has been violated.
Enums§
- Deinit
Error - An error that arose during deinit.
- Poll
Error - An error that arose during polling.
Traits§
- Debounce
- Static configuration of the debouncing algorithm.