Indicator LEDs are now bog-standard red and green LEDs. Looks more original.
This commit is contained in:
@@ -6,11 +6,10 @@
|
|||||||
|
|
||||||
static const uint8_t GAUGE_COUNT = 4;
|
static const uint8_t GAUGE_COUNT = 4;
|
||||||
|
|
||||||
// Backlight/status LEDs and indicator LEDs use separate data strips because
|
// Backlight/status LEDs use an addressable strip. Indicator LEDs are
|
||||||
// their LED chipsets are not compatible on one chain. The command protocol
|
// single-colour active-high outputs on per-gauge pins. The command protocol
|
||||||
// still exposes one logical LED segment per gauge.
|
// still exposes one logical LED segment per gauge.
|
||||||
static const uint8_t LED_DATA_PIN = 22;
|
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 BREATHE_FRAME_MS = 16;
|
||||||
static const uint8_t LED_SHOW_MIN_INTERVAL_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 LED_SHOW_MOTION_INTERVAL_MS = 50;
|
||||||
@@ -34,14 +33,16 @@ struct GaugePins {
|
|||||||
bool stepActiveHigh;
|
bool stepActiveHigh;
|
||||||
bool enableActiveLow;
|
bool enableActiveLow;
|
||||||
const char* ledOrder; // one char per LED: 'G' = GRB, 'R' = RGB; length defines ledCount
|
const char* ledOrder; // one char per LED: 'G' = GRB, 'R' = RGB; length defines ledCount
|
||||||
|
int8_t indicatorRedPin; // logical LED index 3; -1 means not fitted
|
||||||
|
int8_t indicatorGreenPin; // logical LED index 4; -1 means not fitted
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr GaugePins gaugePins[GAUGE_COUNT] = {
|
constexpr GaugePins gaugePins[GAUGE_COUNT] = {
|
||||||
// dir, step, en, dirInv, stepHigh, enActiveLow, ledOrder
|
// dir, step, en, dirInv, stepHigh, enActiveLow, ledOrder, indRed, indGreen
|
||||||
{48, 49, -1, false, true, true, "RRRGGRR"}, // Gauge 0
|
{48, 49, -1, false, true, true, "RRRGGRR", 2, 3}, // Gauge 0
|
||||||
{8, 9, -1, true, true, true, "GGGRRRR"}, // Gauge 1
|
{8, 9, -1, true, true, true, "GGGRRRR", 35, 36}, // Gauge 1
|
||||||
{52, 53, -1, false, true, true, "GGGRRRR"}, // Gauge 2
|
{52, 53, -1, false, true, true, "GGGRRRR", 37, 38}, // Gauge 2
|
||||||
{50, 51, -1, false, true, true, "GGGRRRR"}, // Gauge 3
|
{50, 51, -1, false, true, true, "GGGRRRR", 39, 40}, // Gauge 3
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr uint8_t cstrLen(const char* s) {
|
constexpr uint8_t cstrLen(const char* s) {
|
||||||
@@ -149,21 +150,18 @@ bool rxOverflowed = false;
|
|||||||
|
|
||||||
CRGB logicalLeds[TOTAL_LEDS];
|
CRGB logicalLeds[TOTAL_LEDS];
|
||||||
CRGB mainLeds[TOTAL_MAIN_LEDS];
|
CRGB mainLeds[TOTAL_MAIN_LEDS];
|
||||||
CRGB indicatorLeds[TOTAL_INDICATOR_LEDS];
|
|
||||||
CLEDController* mainLedController = nullptr;
|
CLEDController* mainLedController = nullptr;
|
||||||
CLEDController* indicatorLedController = nullptr;
|
|
||||||
uint8_t gaugeLedOffset[GAUGE_COUNT];
|
uint8_t gaugeLedOffset[GAUGE_COUNT];
|
||||||
uint8_t gaugeLedCount[GAUGE_COUNT];
|
uint8_t gaugeLedCount[GAUGE_COUNT];
|
||||||
uint8_t gaugeMainLedOffset[GAUGE_COUNT];
|
uint8_t gaugeMainLedOffset[GAUGE_COUNT];
|
||||||
uint8_t gaugeIndicatorLedOffset[GAUGE_COUNT];
|
|
||||||
uint8_t ledPhysicalIdx[TOTAL_LEDS];
|
uint8_t ledPhysicalIdx[TOTAL_LEDS];
|
||||||
|
uint8_t ledGaugeIdx[TOTAL_LEDS];
|
||||||
|
uint8_t ledLocalIdx[TOTAL_LEDS];
|
||||||
bool ledIsIndicator[TOTAL_LEDS];
|
bool ledIsIndicator[TOTAL_LEDS];
|
||||||
bool ledRgSwap[TOTAL_LEDS];
|
bool ledRgSwap[TOTAL_LEDS];
|
||||||
BlinkState blinkState[TOTAL_LEDS];
|
BlinkState blinkState[TOTAL_LEDS];
|
||||||
bool mainLedsDirty = false;
|
bool mainLedsDirty = false;
|
||||||
bool indicatorLedsDirty = false;
|
|
||||||
unsigned long lastLedShowMs = 0;
|
unsigned long lastLedShowMs = 0;
|
||||||
bool showIndicatorStripNext = false;
|
|
||||||
|
|
||||||
// FastLED drives the shared strip as RGB. Each gauge's ledOrder string marks per-LED
|
// 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.
|
// type ('R' = RGB, 'G' = GRB); writes to GRB-ordered LEDs pre-swap R and G to compensate.
|
||||||
@@ -180,12 +178,32 @@ inline CRGB encodeForStrip(uint8_t globalIdx, CRGB color) {
|
|||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline int8_t indicatorPinFor(uint8_t gaugeIdx, uint8_t localIdx) {
|
||||||
|
if (localIdx == 3) return gaugePins[gaugeIdx].indicatorRedPin;
|
||||||
|
if (localIdx == 4) return gaugePins[gaugeIdx].indicatorGreenPin;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool indicatorIsOn(uint8_t localIdx, CRGB color) {
|
||||||
|
if (localIdx == 3) return color.r >= 128;
|
||||||
|
if (localIdx == 4) return color.g >= 128;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void writeIndicatorLed(uint8_t globalIdx, CRGB color) {
|
||||||
|
uint8_t gaugeIdx = ledGaugeIdx[globalIdx];
|
||||||
|
uint8_t localIdx = ledLocalIdx[globalIdx];
|
||||||
|
int8_t pin = indicatorPinFor(gaugeIdx, localIdx);
|
||||||
|
if (pin >= 0) {
|
||||||
|
digitalWrite(pin, indicatorIsOn(localIdx, color) ? HIGH : LOW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inline void writeLed(uint8_t globalIdx, CRGB color) {
|
inline void writeLed(uint8_t globalIdx, CRGB color) {
|
||||||
logicalLeds[globalIdx] = color;
|
logicalLeds[globalIdx] = color;
|
||||||
|
|
||||||
if (ledIsIndicator[globalIdx]) {
|
if (ledIsIndicator[globalIdx]) {
|
||||||
indicatorLeds[ledPhysicalIdx[globalIdx]] = encodeForStrip(globalIdx, color);
|
writeIndicatorLed(globalIdx, color);
|
||||||
indicatorLedsDirty = true;
|
|
||||||
} else {
|
} else {
|
||||||
mainLeds[ledPhysicalIdx[globalIdx]] = encodeForStrip(globalIdx, color);
|
mainLeds[ledPhysicalIdx[globalIdx]] = encodeForStrip(globalIdx, color);
|
||||||
mainLedsDirty = true;
|
mainLedsDirty = true;
|
||||||
@@ -211,7 +229,7 @@ uint32_t maxStepperRateQ16() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void showDirtyLeds() {
|
void showDirtyLeds() {
|
||||||
if (!mainLedsDirty && !indicatorLedsDirty) return;
|
if (!mainLedsDirty) return;
|
||||||
|
|
||||||
uint32_t maxStepRate = maxStepperRateQ16();
|
uint32_t maxStepRate = maxStepperRateQ16();
|
||||||
if (maxStepRate >= LED_SHOW_PAUSE_RATE_Q16) return;
|
if (maxStepRate >= LED_SHOW_PAUSE_RATE_Q16) return;
|
||||||
@@ -222,18 +240,9 @@ void showDirtyLeds() {
|
|||||||
: LED_SHOW_MIN_INTERVAL_MS;
|
: LED_SHOW_MIN_INTERVAL_MS;
|
||||||
if (nowMs - lastLedShowMs < intervalMs) return;
|
if (nowMs - lastLedShowMs < intervalMs) return;
|
||||||
|
|
||||||
if (showIndicatorStripNext && indicatorLedsDirty && indicatorLedController != nullptr) {
|
if (mainLedsDirty && mainLedController != nullptr) {
|
||||||
indicatorLedController->showLeds(255);
|
|
||||||
indicatorLedsDirty = false;
|
|
||||||
showIndicatorStripNext = false;
|
|
||||||
} else if (mainLedsDirty && mainLedController != nullptr) {
|
|
||||||
mainLedController->showLeds(255);
|
mainLedController->showLeds(255);
|
||||||
mainLedsDirty = false;
|
mainLedsDirty = false;
|
||||||
showIndicatorStripNext = true;
|
|
||||||
} else if (indicatorLedsDirty && indicatorLedController != nullptr) {
|
|
||||||
indicatorLedController->showLeds(255);
|
|
||||||
indicatorLedsDirty = false;
|
|
||||||
showIndicatorStripNext = false;
|
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1191,43 +1200,48 @@ void setup() {
|
|||||||
pinMode(gaugePins[i].enablePin, OUTPUT);
|
pinMode(gaugePins[i].enablePin, OUTPUT);
|
||||||
setEnable(i, true);
|
setEnable(i, true);
|
||||||
}
|
}
|
||||||
|
if (gaugePins[i].indicatorRedPin >= 0) {
|
||||||
|
pinMode(gaugePins[i].indicatorRedPin, OUTPUT);
|
||||||
|
digitalWrite(gaugePins[i].indicatorRedPin, LOW);
|
||||||
|
}
|
||||||
|
if (gaugePins[i].indicatorGreenPin >= 0) {
|
||||||
|
pinMode(gaugePins[i].indicatorGreenPin, OUTPUT);
|
||||||
|
digitalWrite(gaugePins[i].indicatorGreenPin, LOW);
|
||||||
|
}
|
||||||
|
|
||||||
initStepperRuntime(i);
|
initStepperRuntime(i);
|
||||||
setStepperLimits(i, gauges[i].minPos, gauges[i].maxPos);
|
setStepperLimits(i, gauges[i].minPos, gauges[i].maxPos);
|
||||||
gauges[i].lastUpdateMicros = micros();
|
gauges[i].lastUpdateMicros = micros();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flatten the per-gauge LED counts into logical offsets and separate
|
// Flatten the per-gauge LED counts into logical offsets and physical
|
||||||
// physical offsets for the main and indicator strips.
|
// offsets for the addressable main strip.
|
||||||
uint8_t ledOff = 0;
|
uint8_t ledOff = 0;
|
||||||
uint8_t mainLedOff = 0;
|
uint8_t mainLedOff = 0;
|
||||||
uint8_t indicatorLedOff = 0;
|
|
||||||
for (uint8_t i = 0; i < GAUGE_COUNT; i++) {
|
for (uint8_t i = 0; i < GAUGE_COUNT; i++) {
|
||||||
gaugeLedCount[i] = cstrLen(gaugePins[i].ledOrder);
|
gaugeLedCount[i] = cstrLen(gaugePins[i].ledOrder);
|
||||||
gaugeLedOffset[i] = ledOff;
|
gaugeLedOffset[i] = ledOff;
|
||||||
gaugeMainLedOffset[i] = mainLedOff;
|
gaugeMainLedOffset[i] = mainLedOff;
|
||||||
gaugeIndicatorLedOffset[i] = indicatorLedOff;
|
|
||||||
|
|
||||||
for (uint8_t localIdx = 0; localIdx < gaugeLedCount[i]; localIdx++) {
|
for (uint8_t localIdx = 0; localIdx < gaugeLedCount[i]; localIdx++) {
|
||||||
uint8_t globalIdx = ledOff + localIdx;
|
uint8_t globalIdx = ledOff + localIdx;
|
||||||
bool indicator = isIndicatorLedIndex(localIdx);
|
bool indicator = isIndicatorLedIndex(localIdx);
|
||||||
|
ledGaugeIdx[globalIdx] = i;
|
||||||
|
ledLocalIdx[globalIdx] = localIdx;
|
||||||
ledIsIndicator[globalIdx] = indicator;
|
ledIsIndicator[globalIdx] = indicator;
|
||||||
ledRgSwap[globalIdx] = gaugePins[i].ledOrder[localIdx] == 'G' ||
|
ledRgSwap[globalIdx] = gaugePins[i].ledOrder[localIdx] == 'G' ||
|
||||||
gaugePins[i].ledOrder[localIdx] == 'g';
|
gaugePins[i].ledOrder[localIdx] == 'g';
|
||||||
ledPhysicalIdx[globalIdx] = indicator
|
ledPhysicalIdx[globalIdx] = indicator
|
||||||
? indicatorLedOff + (localIdx - 3)
|
? 0
|
||||||
: mainLedOff + localIdx - (localIdx > 4 ? 2 : 0);
|
: mainLedOff + localIdx - (localIdx > 4 ? 2 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
ledOff += gaugeLedCount[i];
|
ledOff += gaugeLedCount[i];
|
||||||
indicatorLedOff += countIndicatorLedsForGauge(i);
|
|
||||||
mainLedOff += gaugeLedCount[i] - countIndicatorLedsForGauge(i);
|
mainLedOff += gaugeLedCount[i] - countIndicatorLedsForGauge(i);
|
||||||
}
|
}
|
||||||
mainLedController = &FastLED.addLeds<WS2812, LED_DATA_PIN, RGB>(mainLeds, TOTAL_MAIN_LEDS);
|
mainLedController = &FastLED.addLeds<WS2812, LED_DATA_PIN, RGB>(mainLeds, TOTAL_MAIN_LEDS);
|
||||||
indicatorLedController = &FastLED.addLeds<WS2812B, INDICATOR_LED_DATA_PIN, RGB>(indicatorLeds, TOTAL_INDICATOR_LEDS);
|
|
||||||
FastLED.setBrightness(255);
|
FastLED.setBrightness(255);
|
||||||
mainLedController->showLeds(255);
|
mainLedController->showLeds(255);
|
||||||
indicatorLedController->showLeds(255);
|
|
||||||
|
|
||||||
setupStepperTimer();
|
setupStepperTimer();
|
||||||
requestHomeAll();
|
requestHomeAll();
|
||||||
|
|||||||
Reference in New Issue
Block a user