RKTK API Docs RKTK Home Repo

rktk_drivers_common/
encoder.rs

1//! Encoder driver implementations.
2
3use embassy_futures::select::{Either, select, select_slice};
4use embassy_time::Timer;
5use embedded_hal::digital::InputPin;
6use embedded_hal_async::digital::Wait;
7use rktk::drivers::interface::encoder::{EncoderDirection, EncoderDriver};
8
9/// General encoder driver that can be used with any digital input pin.
10pub struct GeneralEncoder<PIN: Wait + InputPin, const ENCODER_COUNT: usize> {
11    encoders: [(PIN, PIN); ENCODER_COUNT],
12}
13
14impl<PIN: Wait + InputPin, const ENCODER_COUNT: usize> GeneralEncoder<PIN, ENCODER_COUNT> {
15    pub fn new(encoders: [(PIN, PIN); ENCODER_COUNT]) -> Self {
16        Self { encoders }
17    }
18}
19
20impl<PIN: Wait + InputPin, const ENCODER_COUNT: usize> EncoderDriver
21    for GeneralEncoder<PIN, ENCODER_COUNT>
22{
23    async fn read_wait(&mut self) -> (u8, EncoderDirection) {
24        let mut futures = self
25            .encoders
26            .iter_mut()
27            .enumerate()
28            .map(|(i, (a, b))| async move {
29                let dir = match select(a.wait_for_any_edge(), b.wait_for_any_edge()).await {
30                    Either::First(_) => {
31                        Timer::after_ticks(100).await;
32                        if a.is_high().unwrap() ^ b.is_high().unwrap() {
33                            EncoderDirection::Clockwise
34                        } else {
35                            EncoderDirection::CounterClockwise
36                        }
37                    }
38                    Either::Second(_) => {
39                        Timer::after_ticks(100).await;
40                        if a.is_high().unwrap() ^ b.is_high().unwrap() {
41                            EncoderDirection::CounterClockwise
42                        } else {
43                            EncoderDirection::Clockwise
44                        }
45                    }
46                };
47                (i as u8, dir)
48            })
49            .collect::<heapless::Vec<_, ENCODER_COUNT>>();
50
51        select_slice(&mut futures).await.0
52    }
53}