Are you using ws2801 or ws2803?
If so, you're in luck. It's all working. Though only working reliably with a Mega2560.
Think this is working code. Let me know if you have any questions.
Needs this lib -https://github.com/adafruit/Adafruit-WS2801-Library
//----WS2801
#include "Adafruit_WS2801.h"
int dataPin = 6; // WS2801 Data
int clockPin = 7; // WS2801 Clock
Adafruit_WS2801 strip = Adafruit_WS2801(16, dataPin, clockPin); //Configure WS2801 as follows: (number of ws2801, dataPin, clockPin)
//----Artnet
#include <SPI.h> // needed for Arduino versions later than 0018
#include <Ethernet.h>
#include <EthernetUdp.h> // UDP library from: bjoern@cs.stanford.edu 12/30/2008
#define short_get_high_byte(x) ((HIGH_BYTE & x) >> 8)
#define short_get_low_byte(x) (LOW_BYTE & x)
#define bytes_to_short(h,l) ( ((h << 8) & 0xff00) | (l & 0x00FF) );
#define UDP_PACKET_MAX_SIZE 2048
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0x03, 0x65 };
IPAddress ip(2,0,0,101);
unsigned int localPort = 6454; // local port to listen on
//customisation: edit this if you want for example read and copy only 4 or 6 channels from channel 12 or 48 or whatever.
const int number_of_channels=512; //512 for 512 channels
const int channel_position=1; // 1 if you want to read from channel 1
// buffers for receiving and sending data
char packetBuffer[UDP_PACKET_MAX_SIZE]; //buffer to hold incoming packet,
byte buffer_dmx[number_of_channels+channel_position]; //buffer to store filetered DMX data
// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
// art net parameters
const int art_net_header_size=17;
const int max_packet_size=576;
char ArtNetHead[8]="Art-Net";
char OpHbyteReceive=0;
char OpLbyteReceive=0;
short is_artnet_version_1=0;
short is_artnet_version_2=0;
short seq_artnet=0;
short artnet_physical=0;
short incoming_universe=0;
boolean is_opcode_is_dmx=0;
boolean is_opcode_is_artpoll=0;
boolean match_artnet=1;
short Opcode=0;
//SETUP
void setup() {
//----WS2801
strip.begin(); //Initialize WS2801 'strip' (WS2801 chips in a chain)
strip.show(); // Update LED contents, to start they are all 'off'
//----Artnet
// start the Ethernet and UDP:
Ethernet.begin(mac,ip);
Udp.begin(localPort);
Serial.begin(57600);
// pinMode(6, OUTPUT); // setup pin 6 as output to test an artnet channel with an led
}
//MAIN LOOP
//----Artnet
void loop() {
// if there's data available, read a packet
int packetSize = Udp.parsePacket();
if(packetSize)
{
//debug(packetSize); // uncomment this line to show packet info in serial monitor
Udp.read(packetBuffer,UDP_PACKET_MAX_SIZE);
//read header
match_artnet=1;//valeur de stockage
for (int i=0;i<7;i++)
{
if(char(packetBuffer[i])!=ArtNetHead[i])
{match_artnet=0;break;}//if not corresponding, this is not an artnet packet, so we stop reading
}
if (match_artnet==1)//if its an artnet header
{
/*artnet protocole revision, not really needed
is_artnet_version_1=packetBuffer[10];
is_artnet_version_2=packetBuffer[11];*/
/*sequence of data, to avoid lost packets on routeurs
seq_artnet=packetBuffer[12];*/
/*physical port of dmx N°
//artnet_physical=packetBuffer[13];*/
//operator code enables to know wich type of message Art-Net it is
Opcode=bytes_to_short(packetBuffer[9],packetBuffer[8]);
if(Opcode==0x5000)//if opcode is DMX type
{
is_opcode_is_dmx=1;is_opcode_is_artpoll=0;
}
else if(Opcode==0x2000)//if opcode is artpoll
{
is_opcode_is_artpoll=1;is_opcode_is_dmx=0;
//( we should normally reply to it, giving ip adress of the device)
}
if( is_opcode_is_dmx=1)//if its DMX data we will read it now
{
//if you need to filter DMX universes, uncomment next line to have the universe rceived
//incoming_universe= bytes_to_short(packetBuffer[15],packetBuffer[14])
//getting data from a channel position, on a precise amount of channels, this to avoid to much operation if you need only 4 channels for example
for(int i=channel_position-1;i< number_of_channels;i++)//channel position
{
buffer_dmx[i]= byte(packetBuffer[i+18]);
//note that channels are zero based, ie the first channel is buffer_dmx[0]
}
}
}
}
//----WS2801
for(int i=0;i<512;i++)//channel position
{
strip.setPixelColor(i,buffer_dmx[i*3],buffer_dmx[i*3+1],buffer_dmx[i*3+2]);
}
strip.show();
//analogWrite(6,buffer_dmx[0]); // test channel 0 with an led on pin 6
}//end MAIN LOOP
//debug method
int debug(int packetSize)
{
Serial.print("Received packet of size ");
Serial.println(packetSize);
Serial.print("From ");
IPAddress remote = Udp.remoteIP();
for (int i =0; i < 4; i++)
{
Serial.print(remote[i], DEC);
if (i < 3)
{
Serial.print(".");
}
}
Serial.print(", port ");
Serial.println(Udp.remotePort());
delay(10);
}