rotary_encoder_embedded/
angular_velocity.rs1use embedded_hal::digital::InputPin;
2
3use crate::Direction;
4use crate::RotaryEncoder;
5
6const DEFAULT_VELOCITY_INC_FACTOR: f32 = 0.2;
8const DEFAULT_VELOCITY_DEC_FACTOR: f32 = 0.01;
10const DEFAULT_VELOCITY_ACTION_MS: u64 = 25;
12pub type Velocity = f32;
14
15const PIN_MASK: u8 = 0x03;
17const PIN_EDGE: u8 = 0x02;
18
19pub struct AngularVelocityMode {
22 pin_state: [u8; 2],
24 velocity: Velocity,
26 velocity_inc_factor: f32,
28 velocity_dec_factor: f32,
30 velocity_action_ms: u64,
32 previous_time_millis: u64,
34}
35
36impl<DT, CLK> RotaryEncoder<AngularVelocityMode, DT, CLK>
37where
38 DT: InputPin,
39 CLK: InputPin,
40{
41 pub fn set_velocity_inc_factor(&mut self, inc_factor: f32) {
43 self.mode.velocity_inc_factor = inc_factor;
44 }
45
46 pub fn set_velocity_dec_factor(&mut self, dec_factor: f32) {
48 self.mode.velocity_dec_factor = dec_factor;
49 }
50
51 pub fn set_velocity_action_ms(&mut self, action_ms: u64) {
53 self.mode.velocity_action_ms = action_ms;
54 }
55
56 pub fn decay_velocity(&mut self) {
59 self.mode.velocity -= self.mode.velocity_dec_factor;
60 if self.mode.velocity < 0.0 {
61 self.mode.velocity = 0.0;
62 }
63 }
64
65 pub fn update(&mut self, current_time_millis: u64) -> Direction {
70 self.mode.update(
71 self.pin_dt.is_high().unwrap_or_default(),
72 self.pin_clk.is_high().unwrap_or_default(),
73 current_time_millis,
74 )
75 }
76
77 pub fn velocity(&self) -> Velocity {
81 self.mode.velocity
82 }
83}
84
85impl AngularVelocityMode {
86 pub fn new() -> Self {
88 Self {
89 pin_state: [0xFF, 2],
90 velocity: 0.0,
91 previous_time_millis: 0,
92 velocity_action_ms: DEFAULT_VELOCITY_ACTION_MS,
93 velocity_dec_factor: DEFAULT_VELOCITY_DEC_FACTOR,
94 velocity_inc_factor: DEFAULT_VELOCITY_INC_FACTOR,
95 }
96 }
97
98 pub fn update(
100 &mut self,
101 dt_state: bool,
102 clk_state: bool,
103 current_time_millis: u64,
104 ) -> Direction {
105 self.pin_state[0] = (self.pin_state[0] << 1) | dt_state as u8;
106 self.pin_state[1] = (self.pin_state[1] << 1) | clk_state as u8;
107
108 let a = self.pin_state[0] & PIN_MASK;
109 let b = self.pin_state[1] & PIN_MASK;
110
111 let mut dir: Direction = Direction::None;
112
113 if a == PIN_EDGE && b == 0x00 {
114 dir = Direction::Anticlockwise;
115 } else if b == PIN_EDGE && a == 0x00 {
116 dir = Direction::Clockwise;
117 }
118
119 if dir != Direction::None {
120 if current_time_millis - self.previous_time_millis < self.velocity_action_ms
121 && self.velocity < 1.0
122 {
123 self.velocity += self.velocity_inc_factor;
124 if self.velocity > 1.0 {
125 self.velocity = 1.0;
126 }
127 }
128 } else {
129 self.previous_time_millis = current_time_millis;
130 }
131
132 dir
133 }
134}
135
136impl Default for AngularVelocityMode {
137 fn default() -> Self {
138 Self::new()
139 }
140}
141
142impl<DT, CLK, MODE> RotaryEncoder<MODE, DT, CLK>
143where
144 DT: InputPin,
145 CLK: InputPin,
146{
147 pub fn into_angular_velocity_mode(self) -> RotaryEncoder<AngularVelocityMode, DT, CLK> {
149 RotaryEncoder {
150 pin_dt: self.pin_dt,
151 pin_clk: self.pin_clk,
152 mode: AngularVelocityMode::new(),
153 }
154 }
155}