From 8bde8efaff42880ef3121cde0ef1e79c4c2776e5 Mon Sep 17 00:00:00 2001 From: Ashley Strahle Date: Thu, 2 Jul 2026 04:09:22 +0000 Subject: [PATCH] Add expression pedal calibration: cal min/cal max - Remove fixed 0-4095 mapping, use cal_min/cal_max instead - Auto-calibrate minimum at boot (assumes pedal at heel) - 'cal min' sets current position as heel (0) - 'cal max' sets current position as toe (127) - Map cal_min->0, cal_max->127 with clamping - Update 'exp' command to show raw ADC + cal values --- include/expression_pedal.h | 9 +++++++++ src/expression_pedal.cpp | 37 +++++++++++++++++++++++++++++-------- src/main.cpp | 13 ++++++++++--- 3 files changed, 48 insertions(+), 11 deletions(-) diff --git a/include/expression_pedal.h b/include/expression_pedal.h index cfb2ab2..6810bce 100644 --- a/include/expression_pedal.h +++ b/include/expression_pedal.h @@ -11,6 +11,11 @@ public: void begin(); void update(UsbMidiTransport& midi); uint8_t get_value() const { return current_value; } + uint16_t get_raw() const { return current_raw; } + void set_cal_min(); + void set_cal_max(); + uint16_t get_cal_min() const { return cal_min; } + uint16_t get_cal_max() const { return cal_max; } private: uint8_t adc_pin; @@ -23,5 +28,9 @@ private: static const uint16_t READ_INTERVAL_MS = 20; uint32_t last_read_time; + uint16_t current_raw; + uint16_t cal_min; + uint16_t cal_max; + uint8_t adc_to_midi(uint16_t adc_value); }; diff --git a/src/expression_pedal.cpp b/src/expression_pedal.cpp index acd1e46..68fb726 100644 --- a/src/expression_pedal.cpp +++ b/src/expression_pedal.cpp @@ -9,18 +9,24 @@ ExpressionPedal::ExpressionPedal(uint8_t adc_pin) , midi_channel(1) , midi_cc(4) , last_read_time(0) + , current_raw(0) + , cal_min(0) + , cal_max(4095) { } void ExpressionPedal::begin() { - Serial.printf("[EXP] Expression pedal on ADC1_CH4 (GPIO%d)\n", adc_pin); + Serial.printf("[EXP] Expression pedal on ADC1_CH3 (GPIO%d)\n", adc_pin); analogReadResolution(12); pinMode(adc_pin, INPUT); delay(10); - uint16_t initial = analogRead(adc_pin); - current_value = adc_to_midi(initial); + current_raw = analogRead(adc_pin); + cal_min = current_raw; + current_value = adc_to_midi(current_raw); last_sent_value = current_value; - Serial.printf("[EXP] Initial ADC: %d -> MIDI: %d\n", initial, current_value); + Serial.printf("[EXP] Calibrating... press toe then type 'cal max'\n"); + Serial.printf("[EXP] Current ADC: %d -> MIDI: %d\n", current_raw, current_value); + Serial.printf("[EXP] cal_min=%d cal_max=%d (default)\n", cal_min, cal_max); } void ExpressionPedal::update(UsbMidiTransport& midi) { @@ -28,8 +34,8 @@ void ExpressionPedal::update(UsbMidiTransport& midi) { if (now - last_read_time < READ_INTERVAL_MS) return; last_read_time = now; - uint16_t raw = analogRead(adc_pin); - uint8_t new_value = adc_to_midi(raw); + current_raw = analogRead(adc_pin); + uint8_t new_value = adc_to_midi(current_raw); if (new_value > current_value + HYSTERESIS || new_value + HYSTERESIS < current_value || @@ -44,7 +50,22 @@ void ExpressionPedal::update(UsbMidiTransport& midi) { } } +void ExpressionPedal::set_cal_min() { + cal_min = current_raw; + if (cal_min >= cal_max) cal_max = cal_min + 1; + Serial.printf("[EXP] cal_min set to %d (ADC raw)\n", cal_min); +} + +void ExpressionPedal::set_cal_max() { + cal_max = current_raw; + if (cal_max <= cal_min) cal_min = cal_max - 1; + Serial.printf("[EXP] cal_max set to %d (ADC raw)\n", cal_max); +} + uint8_t ExpressionPedal::adc_to_midi(uint16_t adc_value) { - uint32_t scaled = (uint32_t)adc_value * 127 / 4095; - return (uint8_t)scaled; + if (adc_value <= cal_min) return 0; + if (adc_value >= cal_max) return 127; + uint32_t span = cal_max - cal_min; + uint32_t offset = adc_value - cal_min; + return (uint8_t)(offset * 127 / span); } diff --git a/src/main.cpp b/src/main.cpp index 7df0ce5..c374843 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -87,8 +87,13 @@ void handle_serial_command(const String& cmd) { mux.show(); Serial.println("[CMD] Pixel 1 WHITE (max brightness)"); } else if (cmd == "exp") { - uint16_t raw = analogRead(5); - Serial.printf("[CMD] EXP GPIO5 ADC=%d MIDI=%d\n", raw, exp_pedal.get_value()); + Serial.printf("[CMD] EXP ADC=%d MIDI=%d cal_min=%d cal_max=%d\n", + exp_pedal.get_raw(), exp_pedal.get_value(), + exp_pedal.get_cal_min(), exp_pedal.get_cal_max()); + } else if (cmd == "cal min") { + exp_pedal.set_cal_min(); + } else if (cmd == "cal max") { + exp_pedal.set_cal_max(); } else if (cmd == "usb") { Serial.printf("[CMD] USB mounted: %s\n", TinyUSBDevice.mounted() ? "YES" : "NO"); Serial.printf("[CMD] USB ready: %s\n", TinyUSBDevice.ready() ? "YES" : "NO"); @@ -132,7 +137,9 @@ void handle_serial_command(const String& cmd) { Serial.println(" read - raw button read"); Serial.println(" red/green/blue - solid colour"); Serial.println(" pixel0/pixel1 - single pixel test"); - Serial.println(" exp - expression pedal ADC/MIDI value"); + Serial.println(" exp - expression pedal ADC/MIDI/cal values"); + Serial.println(" cal min - set current pedal position as minimum (heel)"); + Serial.println(" cal max - set current pedal position as maximum (toe)"); Serial.println(" usb - USB connection status and descriptor info"); Serial.println(" gpiotest - raw GPIO pin diagnostic"); Serial.println(" rawled - bit-bang WS2812 (no library)");