Compare commits

...
4 Commits
Author SHA1 Message Date
ash 06479f0ca2 Fix orange 0xFFAA00->0xFF6600, pads 8-9 white->purple 2026-07-02 07:04:22 +00:00
ash 66058a6722 Set per-pad LED colors with dim off state
- Pad 0-1: Blue, 2-4: Orange, 5: Red, 6: White, 7: Amber, 8-9: White
- Off state (velocity=0): dim at ~8% brightness instead of black
- On state: full brightness of assigned color
- clear_all() sets dim colors instead of off
2026-07-02 06:45:42 +00:00
ash 4ddb9a00bf Reduce cal_max 1220->1180 to absorb ADC jitter at toe
Raw ADC jitter of ~40 counts at toe caused MIDI flickering
between 127 and ~123. Lowering cal_max so the >= cal_max
clamp at 127 absorbs the noise.
2026-07-02 06:40:30 +00:00
ash c44bfb033b Fix button-to-MIDI latency: remove blocking serial, reduce debounce, faster loop
Latency sources fixed:
- debounce 50ms -> 5ms (switch_stub.cpp:15)
- Removed [MIDI OUT] Serial.printf from send_cc() (midi_transport.cpp:93-98)
- Removed [APP] Switch pressed/released prints from update() (app_task.cpp:39,43)
- Removed [APP] Switch -> CC print from process_switch_event() (app_task.cpp:140-143)
- loop() delay 10ms -> 1ms (main.cpp:390)

Serial output at 115200 baud was taking 2-5ms per printf call
in the critical button-to-MIDI path, adding 7-15ms+ total latency
per button press. All removed from hot path.
2026-07-02 06:22:23 +00:00
6 changed files with 35 additions and 17 deletions
-6
View File
@@ -36,11 +36,9 @@ void AppTask::update() {
bool is_pressed = switch_driver->is_pressed(i);
if (is_pressed && !last_switch_state[i]) {
Serial.printf("[APP] Switch %d pressed\n", i);
process_switch_event(i, true);
last_switch_state[i] = true;
} else if (!is_pressed && last_switch_state[i]) {
Serial.printf("[APP] Switch %d released\n", i);
process_switch_event(i, false);
last_switch_state[i] = false;
}
@@ -136,10 +134,6 @@ void AppTask::process_switch_event(uint8_t switch_id, bool pressed) {
if (pressed) {
midi_transport->send_cc(channel, cc_num, value);
}
Serial.printf("[APP] Switch %d -> Ch%d CC%d Val%d (%s)\n",
switch_id, channel, cc_num, value,
pressed ? "PRESS" : "RELEASE");
break;
}
}
+1 -1
View File
@@ -11,7 +11,7 @@ ExpressionPedal::ExpressionPedal(uint8_t adc_pin)
, last_read_time(0)
, current_raw(0)
, cal_min(36)
, cal_max(1220)
, cal_max(1180)
{
}
+32 -7
View File
@@ -142,6 +142,35 @@ static uint32_t velocity_to_color(uint8_t velocity) {
return launchpad_palette[velocity];
}
static const uint32_t pad_base_colors[10] = {
0x0000FF, // 0: Blue
0x0000FF, // 1: Blue
0xFF6600, // 2: Orange
0xFF6600, // 3: Orange
0xFF6600, // 4: Orange
0xFF0000, // 5: Red
0xFFFFFF, // 6: White
0xFFBF00, // 7: Amber
0x9900FF, // 8: Purple
0x9900FF, // 9: Purple
};
static void apply_pad_color(uint8_t index, uint8_t velocity) {
if (index >= 10) return;
uint32_t base = pad_base_colors[index];
uint8_t r = (base >> 16) & 0xFF;
uint8_t g = (base >> 8) & 0xFF;
uint8_t b = base & 0xFF;
if (velocity == 0) {
r = (uint16_t)r * 20 / 255;
g = (uint16_t)g * 20 / 255;
b = (uint16_t)b * 20 / 255;
}
mux_ptr->set_led_color(index, r, g, b);
}
DefaultLedStub::DefaultLedStub() : initialized(false) {
for (int i = 0; i < NUM_LEDS; i++) {
led_states[i].active = false;
@@ -203,18 +232,14 @@ void DefaultLedStub::begin() {
void DefaultLedStub::set_led_state(uint8_t note, uint8_t channel, uint8_t velocity, int8_t led_index) {
if (!initialized || !mux_ptr) return;
// Direct index mode (used by CC feedback)
// Direct index mode (used by CC feedback / pad colors)
if (led_index >= 0 && led_index < NUM_LEDS) {
led_states[led_index].active = (velocity > 0);
led_states[led_index].note = note;
led_states[led_index].channel = channel;
led_states[led_index].velocity = velocity;
led_states[led_index].timestamp = millis();
uint32_t color = velocity_to_color(velocity);
uint8_t r = (color >> 16) & 0xFF;
uint8_t g = (color >> 8) & 0xFF;
uint8_t b = color & 0xFF;
mux_ptr->set_led_color(led_index, r, g, b);
apply_pad_color(led_index, velocity);
mux_ptr->show();
Serial.printf("[LED] Set LED %d: note=%d ch=%d vel=%d\n", led_index, note, channel, velocity);
return;
@@ -265,7 +290,7 @@ void DefaultLedStub::clear_all() {
led_states[i].note = 0;
led_states[i].channel = 0;
led_states[i].timestamp = 0;
mux_ptr->set_led_color(i, 0, 0, 0);
apply_pad_color(i, 0);
}
mux_ptr->show();
Serial.println("[LED] All cleared");
+1 -1
View File
@@ -387,5 +387,5 @@ void loop() {
handle_serial_command(cmd);
}
delay(10);
delay(1);
}
-1
View File
@@ -94,7 +94,6 @@ void UsbMidiTransport::send_cc(uint8_t channel, uint8_t cc, uint8_t value) {
if (!initialized) return;
uint8_t packet[4] = {0x0B, (uint8_t)(0xB0 | (channel - 1)), cc, value};
usb_midi.writePacket(packet);
Serial.printf("[MIDI OUT] Ch:%d CC:%d:%d\n", channel, cc, value);
}
bool UsbMidiTransport::is_connected() {
+1 -1
View File
@@ -11,7 +11,7 @@ DefaultSwitchStub::DefaultSwitchStub() : initialized(false) {
switch_states[i].current_state = false;
switch_states[i].previous_state = false;
switch_states[i].last_change_time = 0;
switch_states[i].debounce_time = 50;
switch_states[i].debounce_time = 5;
}
}