1个不稳定版本
0.1.0 | 2023年4月15日 |
---|
1668 在 嵌入式开发 中
15KB
255 行
sb-rotary-encoder
无std
Rust包,用于处理旋转编码器信号。
特性
- 平台无关,依赖最少。
- 脉冲分割,用于处理有止点的编码器。
- 通过时间戳计算速度,可选的加速度。
- 整数处理,以获得最佳性能。
- 自动对齐有止点的编码器(见下文说明)。
有止点的编码器
市场上有两种旋转编码器:有止点的和无止点的。有止点提供了步进控制的体验,但也有一些需要注意的副作用。
脉冲数量
止点的分辨率通常低于生成的脉冲分辨率。因此,需要几个脉冲才能达到一个步骤并触发相应的事件。在实际应用中,这些编码器模型通常每个止点使用2个或4个脉冲。
切换点
为了获得最佳的用户体验,编码器应该在达到下一个步骤时触发事件,即达到每个止点的脉冲数量时。不幸的是,由于编码器转动非常快或由于组件本身的自然磨损,有时可能会错过脉冲检测。在这种情况下,明显的切换点会移动,这在进一步的移动中是可以注意到的。
使用示例
对于大多数用例,建议处理间隔为1ms,这适合RTOS或SysTick计数器的常见1kHz频率设置。
// Number of pulses required for one step. 4 is a typical value for encoders with detents.
const PULSE_DIVIDER: i32 = 4;
// Update frequency in Hz, used for velocity calculation
const UPDATE_FREQUENCY: i32 = 1000;
// Create a new instance of an encoder.
let mut encoder = sb_rotary_encoder::RotaryEncoder::new();
// Some dummy input signals to be replaced by the real pin states.
let input_a = true;
let input_b = false;
// Some dummy tick value, can also be `None` if you don't want to use the velocity feature.
let tick = Some(42);
// Process the input and get an event if a step was recognized.
if let Some(event) = encoder.update(input_a, input_b, tick, PULSE_DIVIDER) {
println!("{:?}", event);
// If timestamps were used, the velocity can be calculated.
// This is done as an additional step because it requires some calculations
// which may not be always needed.
if let Some(velocity) = event.velocity(UPDATE_FREQUENCY) {
println!("{:?}", velocity);
// The velocity allows to calculate a dynamic step value to accelerate the encoder
// when moved quickly.
let acceleration = velocity >> 4;
let step = event.step() + (event.step() * acceleration);
}
}
测试
运行 cargo test
进行单元测试。
许可证
在MIT许可证下发布。对本项目的任何贡献都必须在相同的许可证条件下提供。
作者:Oliver Rockstedt [email protected]