diff --git a/src/main.cpp b/src/main.cpp index 6e23cb7..5a8700b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -138,12 +138,29 @@ static void saveConfig() { // PWM helpers // --------------------------------------------------------------------------- +// Tracks the GPIO currently bound to each PWM channel so channels that get +// freed (meter count shrinks, or a pin is changed/cleared) are detached +// instead of being left driving PWM on their old pin. +static int8_t attachedPin[8] = { -1, -1, -1, -1, -1, -1, -1, -1 }; + static void attachMeters() { - for (int i = 0; i < meterCount && i < 8; i++) { - if (meters[i].pin > 0) { + for (int i = 0; i < 8; i++) { + int pin = (i < meterCount && meters[i].pin > 0) ? meters[i].pin : -1; + + // Release the channel if it's no longer used or its pin changed. + if (attachedPin[i] != -1 && attachedPin[i] != pin) { + ledcDetachPin(attachedPin[i]); + pinMode(attachedPin[i], OUTPUT); + digitalWrite(attachedPin[i], LOW); // drive freed pin low so the meter reads zero + Serial.printf("[PWM] detach ch%d pin%d\n", i, attachedPin[i]); + attachedPin[i] = -1; + } + + if (pin > 0 && attachedPin[i] != pin) { ledcSetup(i, PWM_FREQ, PWM_RES); - ledcAttachPin(meters[i].pin, i); - Serial.printf("[PWM] attach ch%d pin%d\n", i, meters[i].pin); + ledcAttachPin(pin, i); + attachedPin[i] = pin; + Serial.printf("[PWM] attach ch%d pin%d\n", i, pin); } } }