From b6e4bfea33253f21fd237fd35cbc731d075f5fb9 Mon Sep 17 00:00:00 2001 From: "Adrian A. Baumann" Date: Sun, 19 Apr 2026 23:03:01 +0200 Subject: [PATCH] 3 Gauges, routines switched --- Gaugecontroller/Gaugecontroller.ino | 42 ++++++++++++++--------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/Gaugecontroller/Gaugecontroller.ino b/Gaugecontroller/Gaugecontroller.ino index 7156208..1a5ec6a 100644 --- a/Gaugecontroller/Gaugecontroller.ino +++ b/Gaugecontroller/Gaugecontroller.ino @@ -2,31 +2,30 @@ #include #include -static const uint8_t GAUGE_COUNT = 2; +static const uint8_t GAUGE_COUNT = 3; -// LED strip — one shared WS2812B strip, segmented per gauge. -// Set LED_DATA_PIN to the digital pin driving the strip data line. -// TOTAL_LEDS is computed automatically from gaugePins[].ledCount. +// One shared WS2812B strip, split into per-gauge segments. static const uint8_t LED_DATA_PIN = 22; -// For now: commands come over USB serial +// For now, command and debug traffic share the same serial port. #define CMD_PORT Serial1 #define DEBUG_PORT Serial1 struct GaugePins { uint8_t dirPin; uint8_t stepPin; - int8_t enablePin; // -1 if unused + int8_t enablePin; // -1 means there is no enable pin bool dirInverted; bool stepActiveHigh; bool enableActiveLow; - uint8_t ledCount; // WS2812B LEDs on this gauge's strip segment (0 if none) + uint8_t ledCount; // LEDs assigned to this gauge }; constexpr GaugePins gaugePins[GAUGE_COUNT] = { // dir, step, en, dirInv, stepHigh, enActiveLow, leds {50, 51, -1, false, true, true, 7}, // Gauge 0 {8, 9, -1, true, true, true, 7}, // Gauge 1 + {52, 53, -1, false, true, true, 7}, // Gauge 2 }; constexpr uint8_t sumLedCounts(uint8_t i = 0) { @@ -47,8 +46,8 @@ struct Gauge { long targetPos = 0; long minPos = 0; - long maxPos = 3780; // adjust to your usable travel - long homingBackoffSteps = 3800; // should exceed reverse travel slightly + long maxPos = 3780; + long homingBackoffSteps = 3800; // Deliberately a touch past full reverse travel. float velocity = 0.0f; float maxSpeed = 5000.0f; @@ -77,14 +76,11 @@ struct BlinkState { LedFx fx = FX_BLINK; CRGB onColor; unsigned long lastMs = 0; - // FX_BLINK uint16_t onMs = 500; uint16_t offMs = 500; bool currentlyOn = false; - // FX_BREATHE: smooth triangle-wave fade uint16_t periodMs = 2000; uint16_t cyclePos = 0; - // FX_DFLASH: two quick flashes then pause uint8_t dphase = 0; }; @@ -170,6 +166,7 @@ void updateHoming(uint8_t id) { return; case HS_START: + // No endstop here; homing just walks back far enough to hit the hard stop. g.velocity = 0.0f; g.stepAccumulator = 0.0f; g.homingStepsRemaining = g.homingBackoffSteps; @@ -266,6 +263,7 @@ void updateGauge(uint8_t id) { } float dir = (error > 0) ? 1.0f : (error < 0 ? -1.0f : 0.0f); + // Basic trapezoidal profile: brake if the remaining travel is shorter than the stop distance. float brakingDistance = (g.velocity * g.velocity) / (2.0f * g.accel + 0.0001f); if ((float)labs(error) <= brakingDistance) { @@ -286,6 +284,7 @@ void updateGauge(uint8_t id) { g.velocity = dir * 5.0f; } + // Integrate fractional steps until there is enough to emit a real pulse. g.stepAccumulator += g.velocity * dt; while (g.stepAccumulator >= 1.0f) { @@ -565,9 +564,7 @@ bool parseLed(const String& line) { bool parseBlink(const String& line) { int id, onMs, offMs, r, g, b; char idxToken[16]; - // Accept both forms: - // BLINK — use current LED colour - // BLINK — set colour in same command + // Optional RGB values let BLINK either reuse or replace the current colour. int count = sscanf(line.c_str(), "BLINK %d %15s %d %d %d %d %d", &id, idxToken, &onMs, &offMs, &r, &g, &b); if (count != 4 && count != 7) return false; @@ -590,7 +587,7 @@ bool parseBlink(const String& line) { CRGB color = (count == 7) ? CRGB(constrain(r, 0, 255), constrain(g, 0, 255), constrain(b, 0, 255)) - : CRGB(0, 0, 0); // placeholder; overwritten per-LED below when count==4 + : CRGB(0, 0, 0); // Placeholder; replaced with the live LED colour below. unsigned long nowMs = millis(); for (int i = idxFirst; i <= idxLast; i++) { @@ -697,6 +694,7 @@ void updateBlink() { uint32_t newPos = (uint32_t)bs.cyclePos + dt; bs.cyclePos = (uint16_t)(newPos % bs.periodMs); bs.lastMs = nowMs; + // Cheap triangle wave. It does the job and nobody has complained yet. uint16_t half = bs.periodMs >> 1; uint8_t bri = (bs.cyclePos < half) ? (uint8_t)((uint32_t)bs.cyclePos * 255 / half) @@ -707,7 +705,7 @@ void updateBlink() { break; } case FX_DFLASH: { - static const uint16_t dur[4] = {100, 100, 100, 700}; + static const uint16_t dur[4] = {100, 100, 100, 700}; // on, off, on, longer off if ((nowMs - bs.lastMs) >= dur[bs.dphase]) { bs.lastMs = nowMs; bs.dphase = (bs.dphase + 1) & 3; @@ -781,7 +779,7 @@ void setup() { gauges[i].lastUpdateMicros = micros(); } - // Compute per-gauge LED offsets and initialise the strip. + // Flatten the per-gauge LED counts into offsets on the shared strip. uint8_t ledOff = 0; for (uint8_t i = 0; i < GAUGE_COUNT; i++) { gaugeLedOffset[i] = ledOff; @@ -801,12 +799,14 @@ void loop() { readCommands(); updateBlink(); + for (uint8_t i = 0; i < GAUGE_COUNT; i++) { + updateGauge(i); + } + if (ledsDirty) { FastLED.show(); ledsDirty = false; } - for (uint8_t i = 0; i < GAUGE_COUNT; i++) { - updateGauge(i); - } + }