feat(01-01): LED driver — dual strip initialization and output
- led_driver.h declares StripWand (NeoGrbwFeature/RMT) + StripSchrank (NeoWs2801Spi2MhzMethod) - led_driver.cpp implements initStrips, showBothStrips, setAllWand/Schrank, applyBrightness helpers - showBothStrips calls stripWand.Show() first (non-blocking DMA) then stripSchrank.Show() (blocking SPI) - Brightness clamped to [0.0f, BRIGHTNESS_MAX] before scaling
This commit is contained in:
59
firmware/src/led_driver.cpp
Normal file
59
firmware/src/led_driver.cpp
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
#include "led_driver.h"
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
// Strip object definitions
|
||||||
|
// StripWand: SK6812 RGBW via RMT (DMA, non-blocking transfer)
|
||||||
|
StripWand stripWand(LED_COUNT_WAND, PIN_SK6812);
|
||||||
|
// StripSchrank: WS2801 RGB via hardware SPI at 2MHz (no pin arg — uses hardware SPI pins)
|
||||||
|
StripSchrank stripSchrank(LED_COUNT_SCHRANK);
|
||||||
|
|
||||||
|
void initStrips() {
|
||||||
|
stripWand.Begin();
|
||||||
|
stripSchrank.Begin();
|
||||||
|
|
||||||
|
// Clear both strips to off on startup
|
||||||
|
stripWand.ClearTo(RgbwColor(0, 0, 0, 0));
|
||||||
|
stripSchrank.ClearTo(RgbColor(0, 0, 0));
|
||||||
|
|
||||||
|
showBothStrips();
|
||||||
|
|
||||||
|
Serial.println("LED driver: Wand 300 RGBW (SK6812 RMT), Schrank 160 RGB (WS2801 SPI 2MHz)");
|
||||||
|
}
|
||||||
|
|
||||||
|
void showBothStrips() {
|
||||||
|
// RMT DMA runs concurrently; both strips finish in ~10ms window
|
||||||
|
stripWand.Show(); // Start non-blocking DMA transfer first
|
||||||
|
stripSchrank.Show(); // Blocks ~4ms (480 bytes at 2MHz); RMT DMA runs in parallel
|
||||||
|
}
|
||||||
|
|
||||||
|
RgbwColor applyBrightnessW(RgbwColor c, float factor) {
|
||||||
|
// Clamp factor to [0.0f, BRIGHTNESS_MAX] before scaling
|
||||||
|
factor = std::max(0.0f, std::min(factor, BRIGHTNESS_MAX));
|
||||||
|
return RgbwColor(
|
||||||
|
static_cast<uint8_t>(c.R * factor),
|
||||||
|
static_cast<uint8_t>(c.G * factor),
|
||||||
|
static_cast<uint8_t>(c.B * factor),
|
||||||
|
static_cast<uint8_t>(c.W * factor)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
RgbColor applyBrightnessR(RgbColor c, float factor) {
|
||||||
|
// Clamp factor to [0.0f, BRIGHTNESS_MAX] before scaling
|
||||||
|
factor = std::max(0.0f, std::min(factor, BRIGHTNESS_MAX));
|
||||||
|
return RgbColor(
|
||||||
|
static_cast<uint8_t>(c.R * factor),
|
||||||
|
static_cast<uint8_t>(c.G * factor),
|
||||||
|
static_cast<uint8_t>(c.B * factor)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setAllWand(RgbwColor color) {
|
||||||
|
// NeoPixelBus ClearTo fills the entire strip with the given color
|
||||||
|
stripWand.ClearTo(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setAllSchrank(RgbColor color) {
|
||||||
|
// NeoPixelBus ClearTo fills the entire strip with the given color
|
||||||
|
stripSchrank.ClearTo(color);
|
||||||
|
}
|
||||||
18
firmware/src/led_driver.h
Normal file
18
firmware/src/led_driver.h
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <NeoPixelBus.h>
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
// SK6812: RGBW (4 bytes/LED) — MUST use NeoGrbwFeature, never NeoRgbFeature
|
||||||
|
using StripWand = NeoPixelBus<NeoGrbwFeature, NeoEsp32Rmt0Ws2812xMethod>;
|
||||||
|
// WS2801: RGB (3 bytes/LED), 2MHz SPI for cable-safe 5m run
|
||||||
|
using StripSchrank = NeoPixelBus<NeoRgbFeature, NeoWs2801Spi2MhzMethod>;
|
||||||
|
|
||||||
|
extern StripWand stripWand;
|
||||||
|
extern StripSchrank stripSchrank;
|
||||||
|
|
||||||
|
void initStrips();
|
||||||
|
void showBothStrips();
|
||||||
|
void setAllWand(RgbwColor color);
|
||||||
|
void setAllSchrank(RgbColor color);
|
||||||
|
RgbwColor applyBrightnessW(RgbwColor c, float factor);
|
||||||
|
RgbColor applyBrightnessR(RgbColor c, float factor);
|
||||||
Reference in New Issue
Block a user