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
This commit is contained in:
ash
2026-07-02 04:09:22 +00:00
parent 08d6fc8701
commit 8bde8efaff
3 changed files with 48 additions and 11 deletions
+9
View File
@@ -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);
};
+29 -8
View File
@@ -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);
}
+10 -3
View File
@@ -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)");