Art-Net Color Order Maps, RGBW

This commit is contained in:
Troy
2024-11-07 13:26:14 -05:00
parent 3012272ed3
commit 3f02ba73df
4 changed files with 74 additions and 31 deletions

View File

@@ -448,7 +448,7 @@ uint8_t BusOnOff::getPins(uint8_t* pinArray) const {
}
BusNetwork::BusNetwork(BusConfig &bc) : Bus(bc.type, bc.start, bc.autoWhite) {
BusNetwork::BusNetwork(BusConfig &bc, const ColorOrderMap &com) : Bus(bc.type, bc.start, bc.autoWhite), _colorOrderMap(com) {
_valid = false;
USER_PRINT("[");
switch (bc.type) {
@@ -457,6 +457,11 @@ BusNetwork::BusNetwork(BusConfig &bc) : Bus(bc.type, bc.start, bc.autoWhite) {
_UDPtype = 2;
USER_PRINT("NET_ARTNET_RGB");
break;
case TYPE_NET_ARTNET_RGBW:
_rgbw = true;
_UDPtype = 2;
USER_PRINT("NET_ARTNET_RGBW");
break;
case TYPE_NET_E131_RGB:
_rgbw = false;
_UDPtype = 1;
@@ -469,10 +474,11 @@ BusNetwork::BusNetwork(BusConfig &bc) : Bus(bc.type, bc.start, bc.autoWhite) {
break;
}
_UDPchannels = _rgbw ? 4 : 3;
_data = (byte *)malloc(bc.count * _UDPchannels);
_data = (byte*) heap_caps_calloc_prefer((bc.count * _UDPchannels)+15, sizeof(byte), 3, MALLOC_CAP_DEFAULT, MALLOC_CAP_SPIRAM);
if (_data == nullptr) return;
memset(_data, 0, bc.count * _UDPchannels);
_len = bc.count;
_colorOrder = bc.colorOrder;
_client = IPAddress(bc.pins[0],bc.pins[1],bc.pins[2],bc.pins[3]);
_broadcastLock = false;
_valid = true;
@@ -482,21 +488,61 @@ BusNetwork::BusNetwork(BusConfig &bc) : Bus(bc.type, bc.start, bc.autoWhite) {
USER_PRINTF(" %u.%u.%u.%u]\n", bc.pins[0],bc.pins[1],bc.pins[2],bc.pins[3]);
}
void BusNetwork::setPixelColor(uint16_t pix, uint32_t c) {
if (!_valid || pix >= _len) return;
if (hasWhite()) c = autoWhiteCalc(c);
if (_cct >= 1900) c = colorBalanceFromKelvin(_cct, c); //color correction from CCT
uint16_t offset = pix * _UDPchannels;
_data[offset] = R(c);
_data[offset+1] = G(c);
_data[offset+2] = B(c);
if (_rgbw) _data[offset+3] = W(c);
void IRAM_ATTR BusNetwork::setPixelColor(uint16_t pix, uint32_t c) {
if (!_valid || pix >= _len) return;
if (_rgbw) c = autoWhiteCalc(c);
if (_cct >= 1900) c = colorBalanceFromKelvin(_cct, c); // color correction from CCT
uint16_t offset = pix * _UDPchannels;
uint8_t co = _colorOrderMap.getPixelColorOrder(pix + _start, _colorOrder);
if (_colorOrder != co || _colorOrder != COL_ORDER_RGB) {
switch (co) {
case COL_ORDER_GRB:
_data[offset] = G(c); _data[offset+1] = R(c); _data[offset+2] = B(c);
break;
case COL_ORDER_RGB:
_data[offset] = R(c); _data[offset+1] = G(c); _data[offset+2] = B(c);
break;
case COL_ORDER_BRG:
_data[offset] = B(c); _data[offset+1] = R(c); _data[offset+2] = G(c);
break;
case COL_ORDER_RBG:
_data[offset] = R(c); _data[offset+1] = B(c); _data[offset+2] = G(c);
break;
case COL_ORDER_GBR:
_data[offset] = G(c); _data[offset+1] = B(c); _data[offset+2] = R(c);
break;
case COL_ORDER_BGR:
_data[offset] = B(c); _data[offset+1] = G(c); _data[offset+2] = R(c);
break;
}
if (_rgbw) _data[offset+3] = W(c);
} else {
_data[offset] = R(c); _data[offset+1] = G(c); _data[offset+2] = B(c);
if (_rgbw) _data[offset+3] = W(c);
}
}
uint32_t BusNetwork::getPixelColor(uint16_t pix) const {
if (!_valid || pix >= _len) return 0;
uint16_t offset = pix * _UDPchannels;
return RGBW32(_data[offset], _data[offset+1], _data[offset+2], _rgbw ? (_data[offset+3] << 24) : 0);
uint32_t IRAM_ATTR BusNetwork::getPixelColor(uint16_t pix) const {
if (!_valid || pix >= _len) return 0;
uint16_t offset = pix * _UDPchannels;
uint8_t co = _colorOrderMap.getPixelColorOrder(pix + _start, _colorOrder);
uint8_t r = _data[offset + 0];
uint8_t g = _data[offset + 1];
uint8_t b = _data[offset + 2];
uint8_t w = _rgbw ? _data[offset + 3] : 0;
switch (co) {
case COL_ORDER_GRB: return RGBW32(g, r, b, w);
case COL_ORDER_RGB: return RGBW32(r, g, b, w);
case COL_ORDER_BRG: return RGBW32(b, r, g, w);
case COL_ORDER_RBG: return RGBW32(r, b, g, w);
case COL_ORDER_GBR: return RGBW32(g, b, r, w);
case COL_ORDER_BGR: return RGBW32(b, g, r, w);
default: return RGBW32(r, g, b, w); // default to RGB order
}
}
void BusNetwork::show() {
@@ -516,8 +562,8 @@ uint8_t BusNetwork::getPins(uint8_t* pinArray) const {
void BusNetwork::cleanup() {
_type = I_NONE;
_valid = false;
if (_data != nullptr) free(_data);
_data = nullptr;
// if (_data != nullptr) free(_data);
// _data = nullptr;
}
// ***************************************************************************
@@ -1181,7 +1227,7 @@ int BusManager::add(BusConfig &bc) {
if (getNumBusses() - getNumVirtualBusses() >= WLED_MAX_BUSSES) return -1;
DEBUG_PRINTF("BusManager::add(bc.type=%u)\n", bc.type);
if (bc.type >= TYPE_NET_DDP_RGB && bc.type < 96) {
busses[numBusses] = new BusNetwork(bc);
busses[numBusses] = new BusNetwork(bc, colorOrderMap);
} else if (bc.type >= TYPE_HUB75MATRIX && bc.type <= (TYPE_HUB75MATRIX + 10)) {
#ifdef WLED_ENABLE_HUB75MATRIX
DEBUG_PRINTLN("BusManager::add - Adding BusHub75Matrix");

View File

@@ -337,7 +337,7 @@ class BusOnOff : public Bus {
class BusNetwork : public Bus {
public:
BusNetwork(BusConfig &bc);
BusNetwork(BusConfig &bc, const ColorOrderMap &com);
uint16_t getMaxPixels() const override { return 4096; };
bool hasRGB() const { return true; }

View File

@@ -252,7 +252,8 @@
//Network types (master broadcast) (80-95)
#define TYPE_NET_DDP_RGB 80 //network DDP RGB bus (master broadcast bus)
#define TYPE_NET_E131_RGB 81 //network E131 RGB bus (master broadcast bus, unused)
#define TYPE_NET_ARTNET_RGB 82 //network ArtNet RGB bus (master broadcast bus, unused)
#define TYPE_NET_ARTNET_RGB 82 //network ArtNet RGB bus (master broadcast bus)
#define TYPE_NET_ARTNET_RGBW 83 //network ArtNet RGB bus (master broadcast bus)
#define TYPE_NET_DDP_RGBW 88 //network DDP RGBW bus (master broadcast bus)
#define IS_DIGITAL(t) (((t) & 0x10) || ((t)==TYPE_HUB75MATRIX)) //digital are 16-31 and 48-63 // WLEDMM added HUB75

View File

@@ -774,7 +774,7 @@ uint8_t IRAM_ATTR realtimeBroadcast(uint8_t type, IPAddress client, uint16_t len
// For some reason, this is faster outside of the case block...
//
static byte *packet_buffer = (byte *) heap_caps_calloc_prefer(530, sizeof(byte), 3, MALLOC_CAP_IRAM_8BIT, MALLOC_CAP_DEFAULT, MALLOC_CAP_SPIRAM); // MALLOC_CAP_TCM seems to have alignment issues.
static byte *packet_buffer = (byte *) heap_caps_calloc_prefer(530, sizeof(byte), 2, MALLOC_CAP_DEFAULT, MALLOC_CAP_SPIRAM); // MALLOC_CAP_TCM seems to have alignment issues.
if (packet_buffer[0] != 0x41) memcpy(packet_buffer, ART_NET_HEADER, 12); // copy in the Art-Net header if it isn't there already
// Volumetric test code
@@ -792,6 +792,8 @@ uint8_t IRAM_ATTR realtimeBroadcast(uint8_t type, IPAddress client, uint16_t len
switch (type) {
case 0: // DDP
{
WiFiUDP ddpUdp;
// calculate the number of UDP packets we need to send
size_t channelCount = length * (isRGBW? 4:3); // 1 channel for every R,G,B value
size_t packetCount = ((channelCount-1) / DDP_CHANNELS_PER_PACKET) +1;
@@ -857,16 +859,11 @@ uint8_t IRAM_ATTR realtimeBroadcast(uint8_t type, IPAddress client, uint16_t len
case 1: //E1.31
{
} break;
case 2: //ArtNet
case 2: //Art-Net
{
static uint_fast16_t artnetlimiter = millis()+(1000/fps_limit);
while (artnetlimiter > micros()) {
if (ArtNetSkipFrame) {
return 0; // Let WLED keep generating effect frames and we output an Art-Net frame when fps_limit is reached.
} else {
delayMicroseconds(10); // Make WLED obey fps_limit and just delay here until we're ready to send a frame.
}
delayMicroseconds(10); // Make WLED obey fps_limit and just delay here until we're ready to send a frame.
}
/*
@@ -904,8 +901,6 @@ uint8_t IRAM_ATTR realtimeBroadcast(uint8_t type, IPAddress client, uint16_t len
return 1; // stop when we hit end of LEDs
}
// hardware_output_universe = hardware_outputs_universe_start[hardware_output];
uint_fast16_t channels_remaining = leds_per_output * (isRGBW?4:3);
while (channels_remaining > 0) {
@@ -1004,6 +999,7 @@ uint8_t IRAM_ATTR realtimeBroadcast(uint8_t type, IPAddress client, uint16_t len
return 1; // borked
}
#endif
packet_buffer[9] = ART_NET_HEADER[9]; // reset ArtSync opcode high byte
#ifdef ARTNET_TIMER
packetstotal++;