Skip to content

Commit

Permalink
Fix volume dial backlash
Browse files Browse the repository at this point in the history
  • Loading branch information
goodhoko committed Dec 14, 2023
1 parent 8554094 commit 7928ce0
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 3 deletions.
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ license = "MIT"
edition = "2018"

[dependencies]
arrayvec = { version = "0.5.2", default-features = false }
stm32f4xx-hal = { version = "0.9", features = ["rt", "stm32f411", "usb_fs"] }
embedded-hal = "0.2"
cortex-m = "0.7"
Expand Down
31 changes: 28 additions & 3 deletions src/counter.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,51 @@
use hal::{prelude::*, qei::Qei, stm32::TIM1};
use hal::{
prelude::*,
qei::Qei,
stm32::TIM1,
timer::{Instant, MonoTimer},
};
use stm32f4xx_hal as hal;

const DETENT_RESET_TIMOUT_MS: u32 = 200;

pub struct Counter<PINS> {
qei: Qei<TIM1, PINS>,
last_count: u16,
timer: MonoTimer,
last_update: Instant,
}

impl<PINS> Counter<PINS> {
pub fn new(qei: Qei<TIM1, PINS>) -> Self {
pub fn new(qei: Qei<TIM1, PINS>, timer: MonoTimer) -> Self {
let last_count = qei.count();
Counter { qei, last_count }
Counter { qei, last_count, last_update: timer.now(), timer }
}

pub fn poll(&mut self) -> Option<i8> {
let count = self.qei.count();
let diff = count.wrapping_sub(self.last_count) as i16;

// Sometimes it happens that last_count gets out of sync with the physical detents.
// We require count to increment by 4 to fire a single tick but when last_count lands in between
// detents we get backlash or missed ticks.
// Assume that when the dial rests for more than DETENT_RESET_TIMOUT_MS it is aligned to a detent
// and reset last_count to current position.
if self.last_update.elapsed() > self.timer.frequency().0 * (DETENT_RESET_TIMOUT_MS / 1000) {
self.last_count = count;
}

if diff != 0 {
self.last_update = self.timer.now();
}
if diff.abs() >= 4 {
self.last_count = count;
Some((diff / 4) as i8)
} else {
None
}
}

pub fn current_count(&self) -> u16 {
self.qei.count()
}
}
6 changes: 6 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ use crate::{
rgb_led::{LedStrip, Pulser},
serial::{Command, Report, SerialProtocol},
};
use arrayvec::ArrayString;
use core::fmt::Write;
use cortex_m_rt::entry;
use embedded_hal::digital::v2::OutputPin;
use hal::{
Expand Down Expand Up @@ -184,6 +186,10 @@ fn main() -> ! {
_ => {},
}

let mut buf = ArrayString::<[u8; 256]>::new();
write!(&mut buf, "count: {}", counter.current_count()).expect("can write count");
protocol.debug(buf.as_str());

if let Some(diff) = counter.poll() {
if !encoder_button.is_pressed() {
protocol.report(Report::DialValue { diff }).unwrap();
Expand Down

0 comments on commit 7928ce0

Please sign in to comment.