| Crates.io | pot-head |
| lib.rs | pot-head |
| version | 0.1.0 |
| created_at | 2025-12-28 19:52:06.82255+00 |
| updated_at | 2025-12-28 19:52:06.82255+00 |
| description | A no_std Rust library for processing potentiometer inputs with filters, curves, and response modes |
| homepage | |
| repository | https://github.com/HybridChild/pot-head |
| max_upload_size | |
| id | 2009308 |
| size | 147,122 |
A no_std Rust library for processing potentiometer inputs in embedded systems.
pot-head transforms raw ADC values into clean, processed output values through configurable filters, curves, and response modes.
The library provides a complete processing pipeline for analog inputs in resource-constrained embedded systems. Perfect for audio equipment, industrial control panels, and any embedded device with physical controls.
Design Philosophy: Pure mathematical abstraction—no I/O, no interrupts, no HAL integration. Just transformations.
PotHead<u16, f32>)See docs/FEATURES.md for complete feature documentation.
Input processing follows a fixed order:
Input (TIn)
→ Normalize to f32 (0.0-1.0)
→ Noise Filter
→ Response Curve
→ Hysteresis
→ Snap Zones
→ Grab Mode
→ Denormalize to TOut
→ Output (TOut)
[dependencies]
pot-head = "0.1"
# Optional features
pot-head = { version = "0.1", features = ["std-math", "moving-average", "grab-mode"] }
use pot_head::{PotHead, Config, ResponseCurve, NoiseFilter, HysteresisMode, SnapZone, SnapZoneType};
// Define static configuration (stored in flash)
static VOLUME_CONFIG: Config<u16, f32> = Config {
input_min: 0,
input_max: 4095, // 12-bit ADC
output_min: -60.0, // -60dB to 0dB (silence to unity gain)
output_max: 0.0,
curve: ResponseCurve::Logarithmic, // Requires 'std-math' feature
filter: NoiseFilter::ExponentialMovingAverage { alpha: 0.3 },
hysteresis: HysteresisMode::ChangeThreshold { threshold: 0.01 }, // 1% threshold
snap_zones: &[
SnapZone::new(-60.0, 0.02, SnapZoneType::Snap), // Snap to min below 2%
SnapZone::new(0.0, 0.02, SnapZoneType::Snap), // Snap to max above 98%
],
grab_mode: GrabMode::PassThrough,
};
// Validate at compile time
const _: () = {
match VOLUME_CONFIG.validate() {
Ok(()) => {},
Err(e) => panic!("Invalid config"),
}
};
// Create potentiometer instance from static config
let mut volume_pot = PotHead::new(&VOLUME_CONFIG);
// In your main loop:
loop {
let adc_value: u16 = read_adc(); // Your hardware-specific ADC read
let volume_db: f32 = volume_pot.update(adc_value);
set_audio_volume(volume_db); // Your application logic
}
cargo doc --open - API documentation| Feature | Description | Dependencies | Default |
|---|---|---|---|
std-math |
Logarithmic response curves | libm |
✅ |
grab-mode |
Pickup/PassThrough modes | None | ✅ |
moving-average |
Moving average filter | heapless |
❌ |
Static ROM Configuration:
Typical costs:
PotHead<u16, u16> (integer scaling): 188 bytes RAMPotHead<u16, f32> (typical audio/control): 188 bytes RAMWINDOW_SIZE × 4 bytes additional (if enabled)Binary sizes (library logic):
Measured on ARM Cortex-M4F/M7 (thumbv7em-none-eabihf). See reports/sizeof_report.md and reports/binary_report.md for detailed analysis.
Update cycle (update() call):
| Platform | Configuration | Time | Cycles |
|---|---|---|---|
| RP2040 (Cortex-M0+, 125 MHz, no FPU) | Baseline (linear, no filter) | 8.99µs | 1,123 |
| With EMA filter | 12.72µs | 1,590 | |
| With logarithmic curve | 32.52µs | 4,065 | |
| Full featured | 47.02µs | 5,877 | |
| RP2350 (Cortex-M33F, 150 MHz, with FPU) | Baseline (linear, no filter) | 0.86µs | 128 |
| With EMA filter | 1.00µs | 150 | |
| With logarithmic curve | 1.76µs | 264 | |
| Full featured | 2.28µs | 341 |
See reports/rp2040_benchmarks.md and reports/rp2350_benchmarks.md for complete benchmark data.
Licensed under either of:
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
Designed for the Rust embedded ecosystem.
Maintained by: Esben Dueholm Nørgaard (HybridChild)