rotary-encoder-embedded

A rotary encoder library for embedded rust applications

rotary encoder

features

examples

Examples use the stm32h7xx-hal crate and are compatible with any project using embedded-hal. It is recommended to use the interrupt driven example.

simple example

rust fn main() -> ! { // Configure DT and CLK pins, typically pullup input let rotary_dt = gpio_pin_1.into_pull_up_input() let rotary_clk = gpio_pin_2.into_pull_up_input(); // Initialize the rotary encoder let mut rotary_encoder = RotaryEncoder::new( rotary_dt, rotary_clk, ); // Optional, configure sensitivity if needed rotary_encoder.set_sensitivity(Sensitivity::Low); // Application loop loop { // Update the encoder, which will compute its direction rotary_encoder.update(); match rotary_encoder.direction() { Direction::Clockwise => { // Increment some value } Direction::AntiClockwise => { // Decrement some value } Direction::None => { // Do nothing } } } }

interrupt driven example

Trigger GPIO pin interrupts for both DT and CLK on both rising and falling edges

```rust static ROTARY_ENCODER: Mutex>> = Mutex::new(RefCell::new(None));

fn main() -> ! { // Configure DT typically as pullup input & interrupt on rising/falling edges let mut rotarydt = rotarydt.intopullupinput(); rotarydt.makeinterruptsource(syscfg); rotarydt.triggeronedge(exti, Edge::RisingFalling); rotarydt.enableinterrupt(exti); // Configure CLK typically as pullup input & interrupt on rising/falling edges let mut rotaryclk = rotaryclk.intopullupinput(); rotaryclk.makeinterruptsource(syscfg); rotaryclk.triggeronedge(exti, Edge::RisingFalling); rotaryclk.enableinterrupt(exti); // Initialize Rotary Encoder and safely store in static global interrupt::free(|cs| { ROTARYENCODER.borrow(cs).replace(Some( RotaryEncoder::new( rotarydt, rotary_clk, ) )); });

loop {}

} /// Called from the GPIO interrupt vector fn handlerotaryinterrupt() { // Retrieve Rotary Encoder from safely stored static global interrupt::free(|cs| { if let Some(ref mut rotaryencoder) = ROTARYENCODER.borrow(cs).borrowmut().derefmut() { // Borrow the pins to clear the pending interrupt bit (which varies depending on HAL) let mut pins = rotaryencoder.borrowpins(); pins.0.clearinterruptpendingbit(); pins.1.clearinterruptpendingbit(); // Update the encoder, which will compute its direction rotaryencoder.update(); match rotaryencoder.direction() { Direction::Clockwise => { // Increment some value } Direction::AntiClockwise => { // Decrement some value } Direction::None => { // Do nothing } } } }); } ```

angular velocity example

For experimental angular velocity support use the RotaryEncoderWithVelocity struct. This functionality is gated behind the angular-velocity crate feature flag.

rust fn main() -> ! { // Configure DT and CLK pins, typically pullup input let rotary_dt = gpio_pin_1.into_pull_up_input() let rotary_clk = gpio_pin_2.into_pull_up_input(); // Initialize Rotary Encoder with Velocity functionality let mut rotary_encoder = RotaryEncoderWithVelocity::new( rotary_dt, rotary_clk, ); // Optional settings rotary_encoder.set_sensitivity(Sensitivity::Low); rotary_encoder.set_velocity_action_ms(5); // The window of time that the velocity may increase rotary_encoder.set_velocity_inc_factor(0.2); // How quickly the velocity increases over time rotary_encoder.set_velocity_dec_factor(0.01); // How quickly the velocity decreases over time // Application loop loop { // Update the encoder which will compute its direction and velocity // As velocity is a function of time, we need the current time // current_time should be a monotonously rising time in ms (akin to Arduino's `millis()`) rotary_encoder.update(current_time); // Get the velocity let velocity = rotary_encoder.velocity(); // Match the direction match rotary_encoder.direction() { Direction::Clockwise => { // Increment some value by some factor multiplied by velocity } Direction::AntiClockwise => { // Decrement some value by some factor multiplied by velocity } Direction::None => { // Do nothing } } // As velocity is a function of time, we need to reduce its value over time // This method could also be called from a Timer rotary_encoder.decay_velocity(); } }