diff --git a/Gaugecontroller_no_VFD/Gaugecontroller_no_VFD.ino b/Gaugecontroller_no_VFD/Gaugecontroller_no_VFD.ino index 87499f5..7fb3189 100644 --- a/Gaugecontroller_no_VFD/Gaugecontroller_no_VFD.ino +++ b/Gaugecontroller_no_VFD/Gaugecontroller_no_VFD.ino @@ -13,10 +13,13 @@ static const uint8_t LED_DATA_PIN = 22; static const uint8_t INDICATOR_LED_DATA_PIN = 36; static const uint8_t BREATHE_FRAME_MS = 16; static const uint8_t LED_SHOW_MIN_INTERVAL_MS = 16; +static const uint8_t LED_SHOW_MOTION_INTERVAL_MS = 50; static const uint8_t RX_LINE_MAX = 120; static const uint16_t STEPPER_TIMER_HZ = 20000; static const uint8_t STEPPER_TIMER_PRESCALER = 8; static const uint32_t STEPPER_RATE_SCALE = 65536UL; +static const uint32_t LED_SHOW_FULL_RATE_LIMIT_Q16 = (500UL * STEPPER_RATE_SCALE) / STEPPER_TIMER_HZ; +static const uint32_t LED_SHOW_PAUSE_RATE_Q16 = (1500UL * STEPPER_RATE_SCALE) / STEPPER_TIMER_HZ; // For now, command and debug traffic share the same serial port. #define CMD_PORT Serial1 @@ -160,6 +163,7 @@ BlinkState blinkState[TOTAL_LEDS]; bool mainLedsDirty = false; bool indicatorLedsDirty = false; unsigned long lastLedShowMs = 0; +bool showIndicatorStripNext = false; // FastLED drives the shared strip as RGB. Each gauge's ledOrder string marks per-LED // type ('R' = RGB, 'G' = GRB); writes to GRB-ordered LEDs pre-swap R and G to compensate. @@ -192,20 +196,48 @@ inline CRGB readLed(uint8_t globalIdx) { return logicalLeds[globalIdx]; } +uint32_t maxStepperRateQ16() { + uint32_t maxRate = 0; + uint8_t oldSreg = SREG; + cli(); + for (uint8_t i = 0; i < GAUGE_COUNT; i++) { + uint32_t rate = steppers[i].rateQ16; + if (steppers[i].enabled && steppers[i].dir != 0 && rate > maxRate) { + maxRate = rate; + } + } + SREG = oldSreg; + return maxRate; +} + void showDirtyLeds() { if (!mainLedsDirty && !indicatorLedsDirty) return; - unsigned long nowMs = millis(); - if (nowMs - lastLedShowMs < LED_SHOW_MIN_INTERVAL_MS) return; + uint32_t maxStepRate = maxStepperRateQ16(); + if (maxStepRate >= LED_SHOW_PAUSE_RATE_Q16) return; - if (mainLedsDirty && mainLedController != nullptr) { - mainLedController->showLeds(255); - mainLedsDirty = false; - } - if (indicatorLedsDirty && indicatorLedController != nullptr) { + unsigned long nowMs = millis(); + uint8_t intervalMs = (maxStepRate > LED_SHOW_FULL_RATE_LIMIT_Q16) + ? LED_SHOW_MOTION_INTERVAL_MS + : LED_SHOW_MIN_INTERVAL_MS; + if (nowMs - lastLedShowMs < intervalMs) return; + + if (showIndicatorStripNext && indicatorLedsDirty && indicatorLedController != nullptr) { indicatorLedController->showLeds(255); indicatorLedsDirty = false; + showIndicatorStripNext = false; + } else if (mainLedsDirty && mainLedController != nullptr) { + mainLedController->showLeds(255); + mainLedsDirty = false; + showIndicatorStripNext = true; + } else if (indicatorLedsDirty && indicatorLedController != nullptr) { + indicatorLedController->showLeds(255); + indicatorLedsDirty = false; + showIndicatorStripNext = false; + } else { + return; } + lastLedShowMs = nowMs; }