3 Gauges, routines switched
This commit is contained in:
@@ -2,31 +2,30 @@
|
||||
#include <math.h>
|
||||
#include <FastLED.h>
|
||||
|
||||
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 <id> <idx> <on_ms> <off_ms> — use current LED colour
|
||||
// BLINK <id> <idx> <on_ms> <off_ms> <r> <g> <b> — 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user