Reduced code size by:

- removing WS2812FX::setMode()
- removing WS2812FX::setColor()
- removing floating point in transition
- color handling modification in set.cpp
- replaced uint8_t with unsigned in function parameters
- inlined WS2812FX::isUpdating()
- (MAY BE BREAKING) alexa & smartnest update
This commit is contained in:
Blaz Kristan 2024-10-02 20:14:25 +02:00
parent ee380c5377
commit ba3a61f623
11 changed files with 61 additions and 106 deletions

View File

@ -49,7 +49,7 @@ private:
void setColor(int r, int g, int b)
{
strip.setColor(0, r, g, b);
strip.getMainSegment().setColor(0, RGBW32(r, g, b, 0));
stateUpdated(CALL_MODE_DIRECT_CHANGE);
char msg[18] {};
sprintf(msg, "rgb(%d,%d,%d)", r, g, b);

View File

@ -30,6 +30,7 @@
#include <vector>
#include "const.h"
#include "bus_manager.h"
#define FASTLED_INTERNAL //remove annoying pragma messages
#define USE_GET_MILLISECOND_TIMER
@ -654,7 +655,7 @@ typedef struct Segment {
void blurCol(int col, fract8 blur_amount, bool smear = false);
void moveX(int delta, bool wrap = false);
void moveY(int delta, bool wrap = false);
void move(uint8_t dir, uint8_t delta, bool wrap = false);
void move(unsigned dir, unsigned delta, bool wrap = false);
void drawCircle(uint16_t cx, uint16_t cy, uint8_t radius, uint32_t c, bool soft = false);
inline void drawCircle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB c, bool soft = false) { drawCircle(cx, cy, radius, RGBW32(c.r,c.g,c.b,0), soft); }
void fillCircle(uint16_t cx, uint16_t cy, uint8_t radius, uint32_t c, bool soft = false);
@ -781,25 +782,22 @@ class WS2812FX { // 96 bytes
#endif
finalizeInit(), // initialises strip components
service(), // executes effect functions when due and calls strip.show()
setMode(uint8_t segid, uint8_t m), // sets effect/mode for given segment (high level API)
setColor(uint8_t slot, uint32_t c), // sets color (in slot) for given segment (high level API)
setCCT(uint16_t k), // sets global CCT (either in relative 0-255 value or in K)
setBrightness(uint8_t b, bool direct = false), // sets strip brightness
setRange(uint16_t i, uint16_t i2, uint32_t col), // used for clock overlay
purgeSegments(), // removes inactive segments from RAM (may incure penalty and memory fragmentation but reduces vector footprint)
setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t grouping = 1, uint8_t spacing = 0, uint16_t offset = UINT16_MAX, uint16_t startY=0, uint16_t stopY=1),
setMainSegmentId(uint8_t n),
setMainSegmentId(unsigned n = 0),
resetSegments(), // marks all segments for reset
makeAutoSegments(bool forceReset = false), // will create segments based on configured outputs
fixInvalidSegments(), // fixes incorrect segment configuration
setPixelColor(unsigned n, uint32_t c), // paints absolute strip pixel with index n and color c
show(), // initiates LED output
setTargetFps(uint8_t fps),
setTargetFps(unsigned fps),
setupEffectData(); // add default effects to the list; defined in FX.cpp
inline void restartRuntime() { for (Segment &seg : _segments) seg.markForReset(); }
inline void setTransitionMode(bool t) { for (Segment &seg : _segments) seg.startTransition(t ? _transitionDur : 0); }
inline void setColor(uint8_t slot, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0) { setColor(slot, RGBW32(r,g,b,w)); }
inline void setPixelColor(unsigned n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0) { setPixelColor(n, RGBW32(r,g,b,w)); }
inline void setPixelColor(unsigned n, CRGB c) { setPixelColor(n, c.red, c.green, c.blue); }
inline void fill(uint32_t c) { for (unsigned i = 0; i < getLengthTotal(); i++) setPixelColor(i, c); } // fill whole strip with color (inline)
@ -815,9 +813,9 @@ class WS2812FX { // 96 bytes
checkSegmentAlignment(),
hasRGBWBus() const,
hasCCTBus() const,
isUpdating() const, // return true if the strip is being sent pixel updates
deserializeMap(uint8_t n=0);
deserializeMap(unsigned n = 0);
inline bool isUpdating() const { return !BusManager::canAllShow(); } // return true if the strip is being sent pixel updates
inline bool isServicing() const { return _isServicing; } // returns true if strip.service() is executing
inline bool hasWhiteChannel() const { return _hasWhiteChannel; } // returns true if strip contains separate white chanel
inline bool isOffRefreshRequired() const { return _isOffRefreshRequired; } // returns true if strip requires regular updates (i.e. TM1814 chipset)
@ -844,9 +842,9 @@ class WS2812FX { // 96 bytes
uint16_t
getLengthPhysical() const,
getLengthTotal() const, // will include virtual/nonexistent pixels in matrix
getFps() const;
getLengthTotal() const; // will include virtual/nonexistent pixels in matrix
inline uint16_t getFps() const { return (millis() - _lastShow > 2000) ? 0 : _cumulativeFps +1; } // Returns the refresh rate of the LED strip
inline uint16_t getFrameTime() const { return _frametime; } // returns amount of time a frame should take (in ms)
inline uint16_t getMinShowDelay() const { return MIN_SHOW_DELAY; } // returns minimum amount of time strip.service() can be delayed (constant)
inline uint16_t getLength() const { return _length; } // returns actual amount of LEDs on a strip (2D matrix may have less LEDs than W*H)
@ -859,15 +857,12 @@ class WS2812FX { // 96 bytes
uint32_t now, timebase;
uint32_t getPixelColor(unsigned) const;
inline uint32_t getLastShow() const { return _lastShow; } // returns millis() timestamp of last strip.show() call
inline uint32_t getLastShow() const { return _lastShow; } // returns millis() timestamp of last strip.show() call
const char *
getModeData(uint8_t id = 0) const { return (id && id<_modeCount) ? _modeData[id] : PSTR("Solid"); }
const char *getModeData(unsigned id = 0) const { return (id && id < _modeCount) ? _modeData[id] : PSTR("Solid"); }
inline const char **getModeDataSrc() { return &(_modeData[0]); } // vectors use arrays for underlying data
const char **
getModeDataSrc() { return &(_modeData[0]); } // vectors use arrays for underlying data
Segment& getSegment(uint8_t id);
Segment& getSegment(unsigned id);
inline Segment& getFirstSelectedSeg() { return _segments[getFirstSelectedSegId()]; } // returns reference to first segment that is "selected"
inline Segment& getMainSegment() { return _segments[getMainSegmentId()]; } // returns reference to main segment
inline Segment* getSegments() { return &(_segments[0]); } // returns pointer to segment vector structure (warning: use carefully)

View File

@ -499,7 +499,7 @@ void Segment::moveY(int delta, bool wrap) {
// @param dir direction: 0=left, 1=left-up, 2=up, 3=right-up, 4=right, 5=right-down, 6=down, 7=left-down
// @param delta number of pixels to move
// @param wrap around
void Segment::move(uint8_t dir, uint8_t delta, bool wrap) {
void Segment::move(unsigned dir, unsigned delta, bool wrap) {
if (delta==0) return;
switch (dir) {
case 0: moveX( delta, wrap); break;

View File

@ -1464,49 +1464,11 @@ void WS2812FX::show() {
_lastShow = showNow;
}
/**
* Returns a true value if any of the strips are still being updated.
* On some hardware (ESP32), strip updates are done asynchronously.
*/
bool WS2812FX::isUpdating() const {
return !BusManager::canAllShow();
}
/**
* Returns the refresh rate of the LED strip. Useful for finding out whether a given setup is fast enough.
* Only updates on show() or is set to 0 fps if last show is more than 2 secs ago, so accuracy varies
*/
uint16_t WS2812FX::getFps() const {
if (millis() - _lastShow > 2000) return 0;
return _cumulativeFps +1;
}
void WS2812FX::setTargetFps(uint8_t fps) {
void WS2812FX::setTargetFps(unsigned fps) {
if (fps > 0 && fps <= 120) _targetFps = fps;
_frametime = 1000 / _targetFps;
}
void WS2812FX::setMode(uint8_t segid, uint8_t m) {
if (segid >= _segments.size()) return;
if (m >= getModeCount()) m = getModeCount() - 1;
if (_segments[segid].mode != m) {
_segments[segid].setMode(m); // do not load defaults
}
}
//applies to all active and selected segments
void WS2812FX::setColor(uint8_t slot, uint32_t c) {
if (slot >= NUM_COLORS) return;
for (segment &seg : _segments) {
if (seg.isActive() && seg.isSelected()) {
seg.setColor(slot, c);
}
}
}
void WS2812FX::setCCT(uint16_t k) {
for (segment &seg : _segments) {
if (seg.isActive() && seg.isSelected()) {
@ -1553,7 +1515,7 @@ uint8_t WS2812FX::getFirstSelectedSegId() const {
return getMainSegmentId();
}
void WS2812FX::setMainSegmentId(uint8_t n) {
void WS2812FX::setMainSegmentId(unsigned n) {
_mainSegment = 0;
if (n < _segments.size()) {
_mainSegment = n;
@ -1629,7 +1591,7 @@ void WS2812FX::purgeSegments() {
}
}
Segment& WS2812FX::getSegment(uint8_t id) {
Segment& WS2812FX::getSegment(unsigned id) {
return _segments[id >= _segments.size() ? getMainSegmentId() : id]; // vectors
}
@ -1844,7 +1806,7 @@ void WS2812FX::loadCustomPalettes() {
}
//load custom mapping table from JSON file (called from finalizeInit() or deserializeState())
bool WS2812FX::deserializeMap(uint8_t n) {
bool WS2812FX::deserializeMap(unsigned n) {
// 2D support creates its own ledmap (on the fly) if a ledmap.json exists it will overwrite built one.
char fileName[32];

View File

@ -126,10 +126,10 @@ void onAlexaChange(EspalexaDevice* dev)
} else {
colorKtoRGB(k, rgbw);
}
strip.setColor(0, RGBW32(rgbw[0], rgbw[1], rgbw[2], rgbw[3]));
strip.getMainSegment().setColor(0, RGBW32(rgbw[0], rgbw[1], rgbw[2], rgbw[3]));
} else {
uint32_t color = dev->getRGB();
strip.setColor(0, color);
strip.getMainSegment().setColor(0, color);
}
stateUpdated(CALL_MODE_ALEXA);
}

View File

@ -6,6 +6,7 @@
*/
#include "const.h"
#include "pin_manager.h"
#include <vector>
//colors.cpp

View File

@ -80,6 +80,7 @@ byte scaledBri(byte in)
void applyBri() {
if (!realtimeMode || !arlsForceMaxBri)
{
//DEBUG_PRINTF_P(PSTR("Applying strip brightness: %d (%d,%d)\n"), (int)briT, (int)bri, (int)briOld);
strip.setBrightness(scaledBri(briT));
}
}
@ -144,7 +145,6 @@ void stateUpdated(byte callMode) {
if (transitionActive) {
briOld = briT;
tperLast = 0;
} else
strip.setTransitionMode(true); // force all segments to transition mode
transitionActive = true;
@ -184,22 +184,21 @@ void handleTransitions()
updateInterfaces(interfaceUpdateCallMode);
if (transitionActive && strip.getTransition() > 0) {
float tper = (millis() - transitionStartTime)/(float)strip.getTransition();
if (tper >= 1.0f) {
int ti = millis() - transitionStartTime;
int tr = strip.getTransition();
if (ti/tr) {
strip.setTransitionMode(false); // stop all transitions
// restore (global) transition time if not called from UDP notifier or single/temporary transition from JSON (also playlist)
if (jsonTransitionOnce) strip.setTransition(transitionDelay);
transitionActive = false;
jsonTransitionOnce = false;
tperLast = 0;
applyFinalBri();
return;
}
if (tper - tperLast < 0.004f) return; // less than 1 bit change (1/255)
tperLast = tper;
briT = briOld + ((bri - briOld) * tper);
applyBri();
byte briTO = briT;
int deltaBri = (int)bri - (int)briOld;
briT = briOld + (deltaBri * ti / tr);
if (briTO != briT) applyBri();
}
}
@ -234,8 +233,8 @@ void handleNightlight()
colNlT[1] = effectSpeed;
colNlT[2] = effectPalette;
strip.setMode(strip.getFirstSelectedSegId(), FX_MODE_STATIC); // make sure seg runtime is reset if it was in sunrise mode
effectCurrent = FX_MODE_SUNRISE;
strip.getFirstSelectedSeg().setMode(FX_MODE_STATIC); // make sure seg runtime is reset if it was in sunrise mode
effectCurrent = FX_MODE_SUNRISE; // colorUpdated() will take care of assigning that to all selected segments
effectSpeed = nightlightDelayMins;
effectPalette = 0;
if (effectSpeed > 60) effectSpeed = 60; //currently limited to 60 minutes

View File

@ -837,8 +837,9 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
}
// temporary values, write directly to segments, globals are updated by setValuesFromFirstSelectedSeg()
uint32_t col0 = selseg.colors[0];
uint32_t col1 = selseg.colors[1];
uint32_t col0 = selseg.colors[0];
uint32_t col1 = selseg.colors[1];
uint32_t col2 = selseg.colors[2];
byte colIn[4] = {R(col0), G(col0), B(col0), W(col0)};
byte colInSec[4] = {R(col1), G(col1), B(col1), W(col1)};
byte effectIn = selseg.mode;
@ -919,7 +920,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
//set brightness
updateVal(req.c_str(), "&A=", &bri);
bool col0Changed = false, col1Changed = false;
bool col0Changed = false, col1Changed = false, col2Changed = false;
//set colors
col0Changed |= updateVal(req.c_str(), "&R=", &colIn[0]);
col0Changed |= updateVal(req.c_str(), "&G=", &colIn[1]);
@ -976,7 +977,6 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
}
//set color from HEX or 32bit DEC
byte tmpCol[4];
pos = req.indexOf(F("CL="));
if (pos > 0) {
colorFromDecOrHexString(colIn, (char*)req.substring(pos + 3).c_str());
@ -989,10 +989,11 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
}
pos = req.indexOf(F("C3="));
if (pos > 0) {
byte tmpCol[4];
colorFromDecOrHexString(tmpCol, (char*)req.substring(pos + 3).c_str());
uint32_t col2 = RGBW32(tmpCol[0], tmpCol[1], tmpCol[2], tmpCol[3]);
col2 = RGBW32(tmpCol[0], tmpCol[1], tmpCol[2], tmpCol[3]);
selseg.setColor(2, col2); // defined above (SS= or main)
if (!singleSegment) strip.setColor(2, col2); // will set color to all active & selected segments
col2Changed = true;
}
//set to random hue SR=0->1st SR=1->2nd
@ -1003,29 +1004,22 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
col0Changed |= (!sec); col1Changed |= sec;
}
//swap 2nd & 1st
pos = req.indexOf(F("SC"));
if (pos > 0) {
byte temp;
for (unsigned i=0; i<4; i++) {
temp = colIn[i];
colIn[i] = colInSec[i];
colInSec[i] = temp;
}
col0Changed = col1Changed = true;
}
// apply colors to selected segment, and all selected segments if applicable
if (col0Changed) {
uint32_t colIn0 = RGBW32(colIn[0], colIn[1], colIn[2], colIn[3]);
selseg.setColor(0, colIn0);
if (!singleSegment) strip.setColor(0, colIn0); // will set color to all active & selected segments
col0 = RGBW32(colIn[0], colIn[1], colIn[2], colIn[3]);
selseg.setColor(0, col0);
}
if (col1Changed) {
uint32_t colIn1 = RGBW32(colInSec[0], colInSec[1], colInSec[2], colInSec[3]);
selseg.setColor(1, colIn1);
if (!singleSegment) strip.setColor(1, colIn1); // will set color to all active & selected segments
col1 = RGBW32(colInSec[0], colInSec[1], colInSec[2], colInSec[3]);
selseg.setColor(1, col1);
}
//swap 2nd & 1st
pos = req.indexOf(F("SC"));
if (pos > 0) {
std::swap(col0,col1);
col0Changed = col1Changed = true;
}
bool fxModeChanged = false, speedChanged = false, intensityChanged = false, paletteChanged = false;
@ -1055,6 +1049,9 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
if (speedChanged) seg.speed = speedIn;
if (intensityChanged) seg.intensity = intensityIn;
if (paletteChanged) seg.setPalette(paletteIn);
if (col0Changed) seg.setColor(0, col0);
if (col1Changed) seg.setColor(1, col1);
if (col2Changed) seg.setColor(2, col2);
if (custom1Changed) seg.custom1 = custom1In;
if (custom2Changed) seg.custom2 = custom2In;
if (custom3Changed) seg.custom3 = custom3In;

View File

@ -234,12 +234,12 @@ void parseNotifyPacket(uint8_t *udpIn) {
//apply colors from notification to main segment, only if not syncing full segments
if ((receiveNotificationColor || !someSel) && (version < 11 || !receiveSegmentOptions)) {
// primary color, only apply white if intented (version > 0)
strip.setColor(0, RGBW32(udpIn[3], udpIn[4], udpIn[5], (version > 0) ? udpIn[10] : 0));
strip.getMainSegment().setColor(0, RGBW32(udpIn[3], udpIn[4], udpIn[5], (version > 0) ? udpIn[10] : 0));
if (version > 1) {
strip.setColor(1, RGBW32(udpIn[12], udpIn[13], udpIn[14], udpIn[15])); // secondary color
strip.getMainSegment().setColor(1, RGBW32(udpIn[12], udpIn[13], udpIn[14], udpIn[15])); // secondary color
}
if (version > 6) {
strip.setColor(2, RGBW32(udpIn[20], udpIn[21], udpIn[22], udpIn[23])); // tertiary color
strip.getMainSegment().setColor(2, RGBW32(udpIn[20], udpIn[21], udpIn[22], udpIn[23])); // tertiary color
if (version > 9 && udpIn[37] < 255) { // valid CCT/Kelvin value
unsigned cct = udpIn[38];
if (udpIn[37] > 0) { //Kelvin

View File

@ -221,6 +221,7 @@ void WLED::loop()
strip.finalizeInit(); // also loads default ledmap if present
if (aligned) strip.makeAutoSegments();
else strip.fixInvalidSegments();
BusManager::setBrightness(bri); // fix re-initialised bus' brightness
doSerializeConfig = true;
}
if (loadLedmap >= 0) {
@ -571,10 +572,11 @@ void WLED::beginStrip()
} else {
// fix for #3196
if (bootPreset > 0) {
bool oldTransition = fadeTransition; // workaround if transitions are enabled
fadeTransition = false; // ignore transitions temporarily
strip.setColor(0, BLACK); // set all segments black
fadeTransition = oldTransition; // restore transitions
// set all segments black (no transition)
for (unsigned i = 0; i < strip.getSegmentsNum(); i++) {
Segment &seg = strip.getSegment(i);
if (seg.isActive()) seg.colors[0] = BLACK;
}
col[0] = col[1] = col[2] = col[3] = 0; // needed for colorUpdated()
}
briLast = briS; bri = 0;

View File

@ -584,7 +584,6 @@ WLED_GLOBAL bool transitionActive _INIT(false);
WLED_GLOBAL uint16_t transitionDelay _INIT(750); // global transition duration
WLED_GLOBAL uint16_t transitionDelayDefault _INIT(750); // default transition time (stored in cfg.json)
WLED_GLOBAL unsigned long transitionStartTime;
WLED_GLOBAL float tperLast _INIT(0.0f); // crossfade transition progress, 0.0f - 1.0f
WLED_GLOBAL bool jsonTransitionOnce _INIT(false); // flag to override transitionDelay (playlist, JSON API: "live" & "seg":{"i"} & "tt")
WLED_GLOBAL uint8_t randomPaletteChangeTime _INIT(5); // amount of time [s] between random palette changes (min: 1s, max: 255s)
WLED_GLOBAL bool useHarmonicRandomPalette _INIT(true); // use *harmonic* random palette generation (nicer looking) or truly random