Sound Byte Libs 0.5.1-121-g3358a44
C++ firmware library for audio applications on 32-bit ARM Cortex-M processors
Loading...
Searching...
No Matches
pot.hpp
Go to the documentation of this file.
1/**
2 * @file pot.hpp
3 * @brief Potentiometer component — smoothed, calibrated ADC with su output
4 * @ingroup components
5 *
6 * Pot is a source adapter (L1/L2, FDP-072): raw ADC counts in, normalized
7 * signal units out. Pipeline: raw → EWMA (raw domain) → two-point
8 * calibration → su [0, 1]. Deadband operates in su.
9 *
10 * Acquisition is owned by the component: feed values with update(), or read
11 * straight from a DMA scan buffer with update_dma() (ISR-safe).
12 *
13 * Usage:
14 * sbl::components::input::Pot knob;
15 * knob.update_dma(adc_buf, 0);
16 * if (knob.changed()) { apply(knob.value()); } // deadbanded su
17 * widget.set_cutoff_su(knob.smoothed()); // full-resolution su
18 */
19
20#ifndef SBL_HW_COMPONENTS_INPUT_POT_HPP_
21#define SBL_HW_COMPONENTS_INPUT_POT_HPP_
22
23#include <cstdint>
24#include <sbl/hw/util/ewma.hpp>
27
28namespace sbl {
29namespace components {
30namespace input {
31
32struct PotConfig {
34 float deadband = 0.001f; ///< su — ~64 counts of a 16-bit span
35};
36
37/**
38 * @brief Potentiometer with EWMA smoothing, calibration and deadband
39 *
40 * @note All public methods are ISR-safe — pure state machine, no hardware
41 * I/O; 32-bit stores are atomic on Cortex-M. Call update from exactly
42 * one context.
43 */
44class Pot {
45public:
46 explicit Pot(const PotConfig& config = {})
47 : filter_(static_cast<uint8_t>(config.smoothing)),
48 deadband_(config.deadband) {}
49
50 /** @brief Feed a new raw ADC sample through EWMA → calibration → deadband */
51 void update(uint16_t raw) {
52 raw_ = raw;
53 filter_.update(raw);
54 float s = smoothed();
55
56 float delta = s - stable_value_;
57 if (delta < 0.0f) delta = -delta;
58 if (delta >= deadband_) {
59 stable_value_ = s;
60 changed_ = true;
61 }
62 }
63
64 /** @brief Read one channel from a DMA scan buffer and update (ISR-safe) */
65 void update_dma(const uint16_t* buffer, uint8_t channel_index) {
66 update(static_cast<const volatile uint16_t*>(buffer)[channel_index]);
67 }
68
69 /** @brief Stable (deadbanded) value in su [0, 1] */
70 float value() const { return stable_value_; }
71
72 /**
73 * @brief Calibrated, smoothed value in su [0, 1] — no deadband
74 *
75 * Use for parameters driven unconditionally (no changed() gate):
76 * full resolution, no deadband quantization steps.
77 */
78 float smoothed() const {
79 return static_cast<float>(calibration_.normalize(filter_.value())) *
80 (1.0f / static_cast<float>(PotCalibration::kOutputMax));
81 }
82
83 /** @brief Last raw (unfiltered) ADC count — for calibration routines */
84 uint16_t raw() const { return raw_; }
85
86 /** @brief Apply two-point calibration */
87 void set_calibration(PotCalibration cal) { calibration_ = cal; }
88
89 /**
90 * @brief True if value moved past deadband since last check
91 *
92 * Resets the flag on read — call once per update cycle.
93 */
94 bool changed() {
95 bool c = changed_;
96 changed_ = false;
97 return c;
98 }
99
100 /** @brief Override deadband threshold in su (default: 0.001) */
101 void set_deadband(float deadband_su) { deadband_ = deadband_su; }
102
103 /** @brief Reset all state (filter, stable value, changed flag) */
104 void reset() {
105 filter_.reset();
106 raw_ = 0;
107 stable_value_ = 0.0f;
108 changed_ = false;
109 }
110
111private:
113 PotCalibration calibration_;
114 uint16_t raw_ = 0;
115 float deadband_;
116 float stable_value_ = 0.0f;
117 bool changed_ = false;
118};
119
120} // namespace input
121} // namespace components
122} // namespace sbl
123
124#endif // SBL_HW_COMPONENTS_INPUT_POT_HPP_
Potentiometer with EWMA smoothing, calibration and deadband.
Definition pot.hpp:44
void update(uint16_t raw)
Feed a new raw ADC sample through EWMA → calibration → deadband.
Definition pot.hpp:51
bool changed()
True if value moved past deadband since last check.
Definition pot.hpp:94
void reset()
Reset all state (filter, stable value, changed flag)
Definition pot.hpp:104
void update_dma(const uint16_t *buffer, uint8_t channel_index)
Read one channel from a DMA scan buffer and update (ISR-safe)
Definition pot.hpp:65
float value() const
Stable (deadbanded) value in su [0, 1].
Definition pot.hpp:70
float smoothed() const
Calibrated, smoothed value in su [0, 1] — no deadband.
Definition pot.hpp:78
Pot(const PotConfig &config={})
Definition pot.hpp:46
void set_deadband(float deadband_su)
Override deadband threshold in su (default: 0.001)
Definition pot.hpp:101
uint16_t raw() const
Last raw (unfiltered) ADC count — for calibration routines.
Definition pot.hpp:84
void set_calibration(PotCalibration cal)
Apply two-point calibration.
Definition pot.hpp:87
uint16_t update(uint16_t raw)
Feed a new sample and return the smoothed value.
Definition ewma.hpp:46
uint16_t value() const
Return current smoothed value without updating.
Definition ewma.hpp:63
void reset()
Reset filter state (next update will re-seed)
Definition ewma.hpp:71
CV Input component — smoothed ADC reading with su output (FDP-072)
Exponentially Weighted Moving Average filter.
Smoothing
Smoothing presets for the raw-domain EWMA filter.
Definition input.hpp:40
@ Medium
alpha=1/8, settles in ~24 samples (pots, knobs)
Root namespace for all Sound Byte Libs code.
Definition assert.hpp:51
Two-point ADC calibration.
uint32_t normalize(uint32_t raw) const
Normalize raw ADC reading to [0, kOutputMax], clamped.
float deadband
su — ~64 counts of a 16-bit span
Definition pot.hpp:34