Add "Auto" mode to FrequencyField (#959)

* Add "Auto" mode to FrequencyField
* Use exponential function instead of hyperbolic
* Fix tabs
* Back to hyperbolic, better feel
This commit is contained in:
Kyle Reed 2023-05-07 13:01:43 -07:00 committed by GitHub
parent dfadd38e32
commit f22046eccc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 20 additions and 2 deletions

View file

@ -87,7 +87,22 @@ bool FrequencyField::on_key(const ui::KeyEvent event) {
}
bool FrequencyField::on_encoder(const EncoderEvent delta) {
set_value(value() + (delta * step));
if (step == 0) { // 'Auto' mode.'
auto ms = RTT2MS(halGetCounterValue());
auto delta_ms = last_ms_ <= ms ? ms - last_ms_ : ms;
last_ms_ = ms;
// The goal is to map 'scale' to a range of about 10 to 10M.
// The faster the encoder is rotated, the larger the step.
// Linear doesn't feel right. Hyperbolic felt better.
// To get these magic numbers, I graphed the function until the
// curve shape seemed about right then tested on device.
delta_ms = std::min(145ull, delta_ms) + 5; // Prevent DIV/0
int64_t scale = 200'000'000 / (0.001'55 * pow(delta_ms, 5.45)) + 8;
set_value(value() + (delta * scale));
} else {
set_value(value() + (delta * step));
}
return true;
}