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
Debouncetrait, maybe just one from thedefaultmodule. - Some way to regularly call the
poll()method at about the right frequency (where “right” depends on theDebouncetrait implementation, about 100Hz fordefault::ActiveHighordefault::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.