Merge pull request #3121 from troyhacks/2023-03-10-Art-Net_Transmit
Art-Net transmit support for network LEDs
This commit is contained in:
commit
e96053e268
@ -383,24 +383,20 @@ uint8_t BusOnOff::getPins(uint8_t* pinArray) {
|
||||
|
||||
BusNetwork::BusNetwork(BusConfig &bc) : Bus(bc.type, bc.start, bc.autoWhite) {
|
||||
_valid = false;
|
||||
// switch (bc.type) {
|
||||
// case TYPE_NET_ARTNET_RGB:
|
||||
// _rgbw = false;
|
||||
// _UDPtype = 2;
|
||||
// break;
|
||||
// case TYPE_NET_E131_RGB:
|
||||
// _rgbw = false;
|
||||
// _UDPtype = 1;
|
||||
// break;
|
||||
// case TYPE_NET_DDP_RGB:
|
||||
// _rgbw = false;
|
||||
// _UDPtype = 0;
|
||||
// break;
|
||||
// default: // TYPE_NET_DDP_RGB / TYPE_NET_DDP_RGBW
|
||||
switch (bc.type) {
|
||||
case TYPE_NET_ARTNET_RGB:
|
||||
_rgbw = false;
|
||||
_UDPtype = 2;
|
||||
break;
|
||||
case TYPE_NET_E131_RGB:
|
||||
_rgbw = false;
|
||||
_UDPtype = 1;
|
||||
break;
|
||||
default: // TYPE_NET_DDP_RGB / TYPE_NET_DDP_RGBW
|
||||
_rgbw = bc.type == TYPE_NET_DDP_RGBW;
|
||||
_UDPtype = 0;
|
||||
// break;
|
||||
// }
|
||||
break;
|
||||
}
|
||||
_UDPchannels = _rgbw ? 4 : 3;
|
||||
_data = (byte *)malloc(bc.count * _UDPchannels);
|
||||
if (_data == nullptr) return;
|
||||
|
@ -345,7 +345,7 @@ ${i+1}:
|
||||
<!--option value="46">PWM RGB+DCCT</option-->'}
|
||||
<option value="80">DDP RGB (network)</option>
|
||||
<!--option value="81">E1.31 RGB (network)</option-->
|
||||
<!--option value="82">ArtNet RGB (network)</option-->
|
||||
<option value="82">Art-Net RGB (network)</option>
|
||||
<option value="88">DDP RGBW (network)</option>
|
||||
</select><br>
|
||||
<div id="co${i}" style="display:inline">Color Order:
|
||||
|
@ -713,7 +713,9 @@ void sendSysInfoUDP()
|
||||
// buffer - a buffer of at least length*4 bytes long
|
||||
// isRGBW - true if the buffer contains 4 components per pixel
|
||||
|
||||
uint8_t sequenceNumber = 0; // this needs to be shared across all outputs
|
||||
static size_t sequenceNumber = 0; // this needs to be shared across all outputs
|
||||
static const size_t ART_NET_HEADER_SIZE = 12;
|
||||
static const byte ART_NET_HEADER[] PROGMEM = {0x41,0x72,0x74,0x2d,0x4e,0x65,0x74,0x00,0x00,0x50,0x00,0x0e};
|
||||
|
||||
uint8_t realtimeBroadcast(uint8_t type, IPAddress client, uint16_t length, uint8_t *buffer, uint8_t bri, bool isRGBW) {
|
||||
if (!(apActive || interfacesInited) || !client[0] || !length) return 1; // network not initialised or dummy/unset IP address 031522 ajn added check for ap
|
||||
@ -791,6 +793,57 @@ uint8_t realtimeBroadcast(uint8_t type, IPAddress client, uint16_t length, uint8
|
||||
|
||||
case 2: //ArtNet
|
||||
{
|
||||
// calculate the number of UDP packets we need to send
|
||||
const size_t channelCount = length * (isRGBW?4:3); // 1 channel for every R,G,B,(W?) value
|
||||
const size_t ARTNET_CHANNELS_PER_PACKET = isRGBW?512:510; // 512/4=128 RGBW LEDs, 510/3=170 RGB LEDs
|
||||
const size_t packetCount = ((channelCount-1)/ARTNET_CHANNELS_PER_PACKET)+1;
|
||||
|
||||
uint32_t channel = 0;
|
||||
size_t bufferOffset = 0;
|
||||
|
||||
sequenceNumber++;
|
||||
|
||||
for (size_t currentPacket = 0; currentPacket < packetCount; currentPacket++) {
|
||||
|
||||
if (sequenceNumber > 255) sequenceNumber = 0;
|
||||
|
||||
if (!ddpUdp.beginPacket(client, ARTNET_DEFAULT_PORT)) {
|
||||
DEBUG_PRINTLN(F("Art-Net WiFiUDP.beginPacket returned an error"));
|
||||
return 1; // borked
|
||||
}
|
||||
|
||||
size_t packetSize = ARTNET_CHANNELS_PER_PACKET;
|
||||
|
||||
if (currentPacket == (packetCount - 1U)) {
|
||||
// last packet
|
||||
if (channelCount % ARTNET_CHANNELS_PER_PACKET) {
|
||||
packetSize = channelCount % ARTNET_CHANNELS_PER_PACKET;
|
||||
}
|
||||
}
|
||||
|
||||
byte buffer[ART_NET_HEADER_SIZE];
|
||||
memcpy_P(buffer, ART_NET_HEADER, ART_NET_HEADER_SIZE);
|
||||
ddpUdp.write(buffer, ART_NET_HEADER_SIZE); // This doesn't change. Hard coded ID, OpCode, and protocol version.
|
||||
ddpUdp.write(sequenceNumber & 0xFF); // sequence number. 1..255
|
||||
ddpUdp.write(0x00); // physical - more an FYI, not really used for anything. 0..3
|
||||
ddpUdp.write((currentPacket) & 0xFF); // Universe LSB. 1 full packet == 1 full universe, so just use current packet number.
|
||||
ddpUdp.write(0x00); // Universe MSB, unused.
|
||||
ddpUdp.write(0xFF & (packetSize >> 8)); // 16-bit length of channel data, MSB
|
||||
ddpUdp.write(0xFF & (packetSize )); // 16-bit length of channel data, LSB
|
||||
|
||||
for (size_t i = 0; i < packetSize; i += (isRGBW?4:3)) {
|
||||
ddpUdp.write(scale8(buffer[bufferOffset++], bri)); // R
|
||||
ddpUdp.write(scale8(buffer[bufferOffset++], bri)); // G
|
||||
ddpUdp.write(scale8(buffer[bufferOffset++], bri)); // B
|
||||
if (isRGBW) ddpUdp.write(scale8(buffer[bufferOffset++], bri)); // W
|
||||
}
|
||||
|
||||
if (!ddpUdp.endPacket()) {
|
||||
DEBUG_PRINTLN(F("Art-Net WiFiUDP.endPacket returned an error"));
|
||||
return 1; // borked
|
||||
}
|
||||
channel += packetSize;
|
||||
}
|
||||
} break;
|
||||
}
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user