Skip to content

Commit c1b0877

Browse files
committed
Bus implementation.
Added separate DDP listener. LED settings overhaul. Minor fixes: - reduced LED memory - boot brightness fix - reduced debug frequency - added usermod time spent debug - mDNS glitch fix
1 parent 46b66c7 commit c1b0877

File tree

11 files changed

+1206
-965
lines changed

11 files changed

+1206
-965
lines changed

wled00/bus_manager.h

Lines changed: 157 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,20 @@
1010
#include "bus_wrapper.h"
1111
#include <Arduino.h>
1212

13+
// enable additional debug output
14+
#ifdef WLED_DEBUG
15+
#ifndef ESP8266
16+
#include <rom/rtc.h>
17+
#endif
18+
#define DEBUG_PRINT(x) Serial.print(x)
19+
#define DEBUG_PRINTLN(x) Serial.println(x)
20+
#define DEBUG_PRINTF(x...) Serial.printf(x)
21+
#else
22+
#define DEBUG_PRINT(x)
23+
#define DEBUG_PRINTLN(x)
24+
#define DEBUG_PRINTF(x...)
25+
#endif
26+
1327
//temporary struct for passing bus configuration to bus
1428
struct BusConfig {
1529
uint8_t type = TYPE_WS2812_RGB;
@@ -23,7 +37,8 @@ struct BusConfig {
2337
type = busType; count = len; start = pstart;
2438
colorOrder = pcolorOrder; reversed = rev; skipAmount = skip;
2539
uint8_t nPins = 1;
26-
if (type > 47) nPins = 2;
40+
if (type >= 10 && type <= 15) nPins = 4;
41+
else if (type > 47) nPins = 2;
2742
else if (type > 40 && type < 46) nPins = NUM_PWM_PINS(type);
2843
for (uint8_t i = 0; i < nPins; i++) pins[i] = ppins[i];
2944
}
@@ -74,7 +89,7 @@ class Bus {
7489
}
7590

7691
virtual uint16_t getLength() {
77-
return 1;
92+
return 1; // is this ok? shouldn't it be 0 in virtual function?
7893
}
7994

8095
virtual void setColorOrder() {}
@@ -135,7 +150,7 @@ class BusDigital : public Bus {
135150
_busPtr = PolyBus::create(_iType, _pins, _len, nr);
136151
_valid = (_busPtr != nullptr);
137152
_colorOrder = bc.colorOrder;
138-
//Serial.printf("Successfully inited strip %u (len %u) with type %u and pins %u,%u (itype %u)\n",nr, len, type, pins[0],pins[1],_iType);
153+
DEBUG_PRINTF("Successfully inited strip %u (len %u) with type %u and pins %u,%u (itype %u)\n",nr, len, type, pins[0],pins[1],_iType);
139154
};
140155

141156
inline void show() {
@@ -201,7 +216,7 @@ class BusDigital : public Bus {
201216
}
202217

203218
void cleanup() {
204-
//Serial.println("Digital Cleanup");
219+
DEBUG_PRINTLN("Digital Cleanup");
205220
PolyBus::cleanup(_busPtr, _iType);
206221
_iType = I_NONE;
207222
_valid = false;
@@ -227,6 +242,7 @@ class BusDigital : public Bus {
227242
class BusPwm : public Bus {
228243
public:
229244
BusPwm(BusConfig &bc) : Bus(bc.type, bc.start) {
245+
_valid = false;
230246
if (!IS_PWM(bc.type)) return;
231247
uint8_t numPins = NUM_PWM_PINS(bc.type);
232248

@@ -280,10 +296,12 @@ class BusPwm : public Bus {
280296

281297
//does no index check
282298
uint32_t getPixelColor(uint16_t pix) {
299+
if (!_valid) return 0;
283300
return ((_data[3] << 24) | (_data[0] << 16) | (_data[1] << 8) | (_data[2]));
284301
}
285302

286303
void show() {
304+
if (!_valid) return;
287305
uint8_t numPins = NUM_PWM_PINS(_type);
288306
for (uint8_t i = 0; i < numPins; i++) {
289307
uint8_t scaled = (_data[i] * _bri) / 255;
@@ -328,20 +346,147 @@ class BusPwm : public Bus {
328346
void deallocatePins() {
329347
uint8_t numPins = NUM_PWM_PINS(_type);
330348
for (uint8_t i = 0; i < numPins; i++) {
349+
pinManager.deallocatePin(_pins[i], PinOwner::BusPwm);
331350
if (!pinManager.isPinOk(_pins[i])) continue;
332351
#ifdef ESP8266
333352
digitalWrite(_pins[i], LOW); //turn off PWM interrupt
334353
#else
335354
if (_ledcStart < 16) ledcDetachPin(_pins[i]);
336355
#endif
337-
pinManager.deallocatePin(_pins[i], PinOwner::BusPwm);
338356
}
339357
#ifdef ARDUINO_ARCH_ESP32
340358
pinManager.deallocateLedc(_ledcStart, numPins);
341359
#endif
342360
}
343361
};
344362

363+
364+
class BusNetwork : public Bus {
365+
public:
366+
BusNetwork(BusConfig &bc) : Bus(bc.type, bc.start) {
367+
_valid = false;
368+
// switch (bc.type) {
369+
// case TYPE_NET_ARTNET_RGB:
370+
// _rgbw = false;
371+
// _UDPtype = 2;
372+
// break;
373+
// case TYPE_NET_E131_RGB:
374+
// _rgbw = false;
375+
// _UDPtype = 1;
376+
// break;
377+
// case TYPE_NET_DDP_RGB:
378+
// _rgbw = false;
379+
// _UDPtype = 0;
380+
// break;
381+
// default:
382+
_rgbw = false;
383+
_UDPtype = bc.type - TYPE_NET_DDP_RGB;
384+
// break;
385+
// }
386+
_UDPchannels = _rgbw ? 4 : 3;
387+
//_rgbw |= bc.rgbwOverride; // RGBW override in bit 7 or can have a special type
388+
_data = (byte *)malloc(bc.count * _UDPchannels);
389+
if (_data == nullptr) return;
390+
memset(_data, 0, bc.count * _UDPchannels);
391+
_len = bc.count;
392+
_colorOrder = bc.colorOrder;
393+
_client = IPAddress(bc.pins[0],bc.pins[1],bc.pins[2],bc.pins[3]);
394+
_broadcastLock = false;
395+
_valid = true;
396+
_data2 = (byte *)malloc(_len * _UDPchannels);
397+
};
398+
399+
void setPixelColor(uint16_t pix, uint32_t c) {
400+
if (!_valid || pix >= _len) return;
401+
uint16_t offset = pix * _UDPchannels;
402+
_data[offset] = 0xFF & (c >> 16);
403+
_data[offset+1] = 0xFF & (c >> 8);
404+
_data[offset+2] = 0xFF & (c );
405+
if (_rgbw) _data[offset+3] = 0xFF & (c >> 24);
406+
}
407+
408+
uint32_t getPixelColor(uint16_t pix) {
409+
if (!_valid || pix >= _len) return 0;
410+
uint16_t offset = pix * _UDPchannels;
411+
// behave as NeoPixelBus
412+
return (
413+
(_rgbw ? (scale8(_data[offset+3], _bri) << 24) : 0)
414+
| (scale8(_data[offset] , _bri) << 16)
415+
| (scale8(_data[offset+1], _bri) << 8)
416+
| (scale8(_data[offset+2], _bri) )
417+
);
418+
}
419+
420+
void show() {
421+
if (!_valid || !canShow()) return;
422+
_broadcastLock = true;
423+
// apply brightness to second buffer
424+
if (_data2 == nullptr) {
425+
// but display original buffer if memory allocation failed
426+
realtimeBroadcast(_UDPtype, _client, _len, _data, _rgbw);
427+
} else {
428+
for (uint16_t pix=0; pix<_len; pix++) {
429+
uint16_t offset = pix * _UDPchannels;
430+
_data2[offset ] = scale8(_data[offset ], _bri);
431+
_data2[offset+1] = scale8(_data[offset+1], _bri);
432+
_data2[offset+2] = scale8(_data[offset+2], _bri);
433+
if (_rgbw) _data2[offset+3] = scale8(_data[offset+3], _bri);
434+
}
435+
realtimeBroadcast(_UDPtype, _client, _len, _data2, _rgbw);
436+
}
437+
_broadcastLock = false;
438+
}
439+
440+
inline bool canShow() {
441+
// this should be a return value from UDP routine if it is still sending data out
442+
return !_broadcastLock;
443+
}
444+
445+
inline void setBrightness(uint8_t b) {
446+
_bri = b;
447+
}
448+
449+
uint8_t getPins(uint8_t* pinArray) {
450+
for (uint8_t i = 0; i < 4; i++) {
451+
pinArray[i] = _client[i];
452+
}
453+
return 4;
454+
}
455+
456+
inline bool isRgbw() {
457+
return _rgbw;
458+
}
459+
460+
inline uint16_t getLength() {
461+
return _len;
462+
}
463+
464+
void cleanup() {
465+
_type = I_NONE;
466+
_valid = false;
467+
if (_data != nullptr) free(_data);
468+
_data = nullptr;
469+
if (_data2 != nullptr) free(_data2);
470+
_data2 = nullptr;
471+
}
472+
473+
~BusNetwork() {
474+
cleanup();
475+
}
476+
477+
private:
478+
IPAddress _client;
479+
uint16_t _len = 0;
480+
uint8_t _colorOrder;
481+
uint8_t _bri = 255;
482+
uint8_t _UDPtype;
483+
uint8_t _UDPchannels;
484+
bool _rgbw;
485+
bool _broadcastLock;
486+
byte *_data, *_data2;
487+
};
488+
489+
345490
class BusManager {
346491
public:
347492
BusManager() {
@@ -352,7 +497,7 @@ class BusManager {
352497
static uint32_t memUsage(BusConfig &bc) {
353498
uint8_t type = bc.type;
354499
uint16_t len = bc.count;
355-
if (type < 32) {
500+
if (type > 15 && type < 32) {
356501
#ifdef ESP8266
357502
if (bc.pins[0] == 3) { //8266 DMA uses 5x the mem
358503
if (type > 29) return len*20; //RGBW
@@ -365,15 +510,17 @@ class BusManager {
365510
return len*6;
366511
#endif
367512
}
368-
369-
if (type > 31 && type < 48) return 5;
513+
if (type >= 10 && type <= 15) return len*6; // double buffer for network
514+
if (type > 31 && type < 48) return 5;
370515
if (type == 44 || type == 45) return len*4; //RGBW
371516
return len*3;
372517
}
373518

374519
int add(BusConfig &bc) {
375520
if (numBusses >= WLED_MAX_BUSSES) return -1;
376-
if (IS_DIGITAL(bc.type)) {
521+
if (bc.type>=10 && bc.type<=15) {
522+
busses[numBusses] = new BusNetwork(bc);
523+
} else if (IS_DIGITAL(bc.type)) {
377524
busses[numBusses] = new BusDigital(bc, numBusses);
378525
} else {
379526
busses[numBusses] = new BusPwm(bc);
@@ -444,6 +591,7 @@ class BusManager {
444591
return len;
445592
}
446593

594+
// a workaround
447595
static inline bool isRgbw(uint8_t type) {
448596
return Bus::isRgbw(type);
449597
}

wled00/const.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,10 @@
122122

123123
#define TYPE_NONE 0 //light is not configured
124124
#define TYPE_RESERVED 1 //unused. Might indicate a "virtual" light
125+
//network types (master broadcast) (10-15)
126+
#define TYPE_NET_DDP_RGB 10 //network DDP RGB bus (master broadcast bus)
127+
#define TYPE_NET_E131_RGB 11 //network E131 RGB bus (master broadcast bus)
128+
#define TYPE_NET_ARTNET_RGB 12 //network ArtNet RGB bus (master broadcast bus)
125129
//Digital types (data pin only) (16-31)
126130
#define TYPE_WS2812_1CH 20 //white-only chips
127131
#define TYPE_WS2812_WWA 21 //amber + warm + cold white
@@ -241,7 +245,7 @@
241245

242246
#ifndef MAX_LED_MEMORY
243247
#ifdef ESP8266
244-
#define MAX_LED_MEMORY 5000
248+
#define MAX_LED_MEMORY 4000
245249
#else
246250
#define MAX_LED_MEMORY 64000
247251
#endif
@@ -282,7 +286,7 @@
282286

283287
// Maximum size of node map (list of other WLED instances)
284288
#ifdef ESP8266
285-
#define WLED_MAX_NODES 15
289+
#define WLED_MAX_NODES 24
286290
#else
287291
#define WLED_MAX_NODES 150
288292
#endif

0 commit comments

Comments
 (0)