Skip to content

Commit f4b47ed

Browse files
authored
Exclude virtual busses from current calculation (wled#2262)
1 parent 8b2145b commit f4b47ed

File tree

2 files changed

+75
-57
lines changed

2 files changed

+75
-57
lines changed

wled00/FX.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,8 @@ class WS2812FX {
682682
ablMilliampsMax,
683683
currentMilliamps,
684684
triwave16(uint16_t),
685+
getLengthTotal(void),
686+
getLengthPhysical(void),
685687
getFps();
686688

687689
uint32_t
@@ -841,9 +843,6 @@ class WS2812FX {
841843

842844
uint16_t _cumulativeFps = 2;
843845

844-
void load_gradient_palette(uint8_t);
845-
void handle_palette(void);
846-
847846
bool
848847
_triggered;
849848

@@ -877,7 +876,10 @@ class WS2812FX {
877876

878877
void
879878
blendPixelColor(uint16_t n, uint32_t color, uint8_t blend),
880-
startTransition(uint8_t oldBri, uint32_t oldCol, uint16_t dur, uint8_t segn, uint8_t slot);
879+
startTransition(uint8_t oldBri, uint32_t oldCol, uint16_t dur, uint8_t segn, uint8_t slot),
880+
estimateCurrentAndLimitBri(void),
881+
load_gradient_palette(uint8_t),
882+
handle_palette(void);
881883

882884
uint16_t* customMappingTable = nullptr;
883885
uint16_t customMappingSize = 0;

wled00/FX_fcn.cpp

Lines changed: 69 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -259,12 +259,7 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
259259
#define MA_FOR_ESP 100 //how much mA does the ESP use (Wemos D1 about 80mA, ESP32 about 120mA)
260260
//you can set it to 0 if the ESP is powered by USB and the LEDs by external
261261

262-
void WS2812FX::show(void) {
263-
264-
// avoid race condition, caputre _callback value
265-
show_callback callback = _callback;
266-
if (callback) callback();
267-
262+
void WS2812FX::estimateCurrentAndLimitBri() {
268263
//power limit calculation
269264
//each LED can draw up 195075 "power units" (approx. 53mA)
270265
//one PU is the power it takes to have 1 channel 1 step brighter per brightness step
@@ -277,65 +272,72 @@ void WS2812FX::show(void) {
277272
actualMilliampsPerLed = 12; // from testing an actual strip
278273
}
279274

280-
if (ablMilliampsMax > 149 && actualMilliampsPerLed > 0) //0 mA per LED and too low numbers turn off calculation
281-
{
282-
uint32_t puPerMilliamp = 195075 / actualMilliampsPerLed;
283-
uint32_t powerBudget = (ablMilliampsMax - MA_FOR_ESP) * puPerMilliamp; //100mA for ESP power
284-
if (powerBudget > puPerMilliamp * _length) //each LED uses about 1mA in standby, exclude that from power budget
285-
{
286-
powerBudget -= puPerMilliamp * _length;
287-
} else
288-
{
289-
powerBudget = 0;
290-
}
275+
if (ablMilliampsMax < 150 || actualMilliampsPerLed == 0) { //0 mA per LED and too low numbers turn off calculation
276+
currentMilliamps = 0;
277+
busses.setBrightness(_brightness);
278+
return;
279+
}
280+
281+
uint16_t pLen = getLengthPhysical();
282+
uint32_t puPerMilliamp = 195075 / actualMilliampsPerLed;
283+
uint32_t powerBudget = (ablMilliampsMax - MA_FOR_ESP) * puPerMilliamp; //100mA for ESP power
284+
if (powerBudget > puPerMilliamp * pLen) { //each LED uses about 1mA in standby, exclude that from power budget
285+
powerBudget -= puPerMilliamp * pLen;
286+
} else {
287+
powerBudget = 0;
288+
}
291289

292-
uint32_t powerSum = 0;
290+
uint32_t powerSum = 0;
293291

294-
for (uint16_t i = 0; i < _length; i++) //sum up the usage of each LED
295-
{
296-
uint32_t c = busses.getPixelColor(i);
292+
for (uint8_t b = 0; b < busses.getNumBusses(); b++) {
293+
Bus *bus = busses.getBus(b);
294+
if (bus->getType() >= TYPE_NET_DDP_RGB) continue; //exclude non-physical network busses
295+
uint16_t len = bus->getLength();
296+
uint32_t busPowerSum = 0;
297+
for (uint16_t i = 0; i < len; i++) { //sum up the usage of each LED
298+
uint32_t c = bus->getPixelColor(i);
297299
byte r = c >> 16, g = c >> 8, b = c, w = c >> 24;
298300

299-
if(useWackyWS2815PowerModel)
300-
{
301-
// ignore white component on WS2815 power calculation
302-
powerSum += (MAX(MAX(r,g),b)) * 3;
303-
}
304-
else
305-
{
306-
powerSum += (r + g + b + w);
301+
if(useWackyWS2815PowerModel) { //ignore white component on WS2815 power calculation
302+
busPowerSum += (MAX(MAX(r,g),b)) * 3;
303+
} else {
304+
busPowerSum += (r + g + b + w);
307305
}
308306
}
309307

310-
311-
if (isRgbw) //RGBW led total output with white LEDs enabled is still 50mA, so each channel uses less
312-
{
313-
powerSum *= 3;
314-
powerSum = powerSum >> 2; //same as /= 4
308+
if (bus->isRgbw()) { //RGBW led total output with white LEDs enabled is still 50mA, so each channel uses less
309+
busPowerSum *= 3;
310+
busPowerSum = busPowerSum >> 2; //same as /= 4
315311
}
312+
powerSum += busPowerSum;
313+
}
316314

317-
uint32_t powerSum0 = powerSum;
318-
powerSum *= _brightness;
319-
320-
if (powerSum > powerBudget) //scale brightness down to stay in current limit
321-
{
322-
float scale = (float)powerBudget / (float)powerSum;
323-
uint16_t scaleI = scale * 255;
324-
uint8_t scaleB = (scaleI > 255) ? 255 : scaleI;
325-
uint8_t newBri = scale8(_brightness, scaleB);
326-
busses.setBrightness(newBri);
327-
currentMilliamps = (powerSum0 * newBri) / puPerMilliamp;
328-
} else
329-
{
330-
currentMilliamps = powerSum / puPerMilliamp;
331-
busses.setBrightness(_brightness);
332-
}
333-
currentMilliamps += MA_FOR_ESP; //add power of ESP back to estimate
334-
currentMilliamps += _length; //add standby power back to estimate
315+
uint32_t powerSum0 = powerSum;
316+
powerSum *= _brightness;
317+
318+
if (powerSum > powerBudget) //scale brightness down to stay in current limit
319+
{
320+
float scale = (float)powerBudget / (float)powerSum;
321+
uint16_t scaleI = scale * 255;
322+
uint8_t scaleB = (scaleI > 255) ? 255 : scaleI;
323+
uint8_t newBri = scale8(_brightness, scaleB);
324+
busses.setBrightness(newBri); //to keep brightness uniform, sets virtual busses too
325+
currentMilliamps = (powerSum0 * newBri) / puPerMilliamp;
335326
} else {
336-
currentMilliamps = 0;
327+
currentMilliamps = powerSum / puPerMilliamp;
337328
busses.setBrightness(_brightness);
338329
}
330+
currentMilliamps += MA_FOR_ESP; //add power of ESP back to estimate
331+
currentMilliamps += pLen; //add standby power back to estimate
332+
}
333+
334+
void WS2812FX::show(void) {
335+
336+
// avoid race condition, caputre _callback value
337+
show_callback callback = _callback;
338+
if (callback) callback();
339+
340+
estimateCurrentAndLimitBri();
339341

340342
// some buses send asynchronously and this method will return before
341343
// all of the data has been sent.
@@ -553,6 +555,20 @@ uint32_t WS2812FX::getLastShow(void) {
553555
return _lastShow;
554556
}
555557

558+
uint16_t WS2812FX::getLengthTotal(void) {
559+
return _length;
560+
}
561+
562+
uint16_t WS2812FX::getLengthPhysical(void) {
563+
uint16_t len = 0;
564+
for (uint8_t b = 0; b < busses.getNumBusses(); b++) {
565+
Bus *bus = busses.getBus(b);
566+
if (bus->getType() >= TYPE_NET_DDP_RGB) continue; //exclude non-physical network busses
567+
len += bus->getLength();
568+
}
569+
return len;
570+
}
571+
556572
void WS2812FX::setSegment(uint8_t n, uint16_t i1, uint16_t i2, uint8_t grouping, uint8_t spacing) {
557573
if (n >= MAX_NUM_SEGMENTS) return;
558574
Segment& seg = _segments[n];

0 commit comments

Comments
 (0)