├── ArtnetFastLED └── ArtnetFastLED.ino ├── ArtnetTest └── ArtnetTest.ino └── README.md /ArtnetFastLED/ArtnetFastLED.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Artnet DMX Control of many 12v SMD5050 RGB Strips with P9813 chip modules 3 | Arduino Mega 2560 4 | Hardware: Conceptinetics DMX Shield 5 | P9813 RGB LED Strip Driver Modules 6 | */ 7 | 8 | #include "FastLED.h" 9 | #include // needed for Arduino versions later than 0018 10 | #include 11 | #include // UDP library from: bjoern@cs.stanford.edu 12/30/2008 12 | #define short_get_high_byte(x) ((HIGH_BYTE & x) >> 8) 13 | #define short_get_low_byte(x) (LOW_BYTE & x) 14 | #define bytes_to_short(h,l) ( ((h << 8) & 0xff00) | (l & 0x00FF) ); 15 | 16 | // How many led strips are you driving 17 | #define NUM_LEDS 2 18 | 19 | // For led chips like Neopixels, which have a data line, ground, and power, you just 20 | // need to define DATA_PIN. For led chipsets that are SPI based (four wires - data, clock, 21 | // ground, and power), like the LPD8806 define both DATA_PIN and CLOCK_PIN 22 | #define DATA_PIN 3 23 | #define CLOCK_PIN 13 24 | 25 | //MAC and IP of the ethernet shield 26 | //MAC adress of the ethershield is stamped down the shield 27 | //to translate it from hexa decimal to decimal, use: http://www.frankdevelopper.com/outils/convertisseur.php 28 | //HARDWARE 29 | byte mac[] = {144, 162, 218, 00, 16, 96}; //the mac adress of ethernet shield or uno shield board 30 | byte ip[] = {192, 168, 0, 20}; // the IP adress of your device, that should be in same universe of the network you are using, here: 192.168.1.x 31 | 32 | // the next two variables are set when a packet is received 33 | byte remoteIp[4]; // holds received packet's originating IP 34 | unsigned int remotePort; // holds received packet's originating port 35 | 36 | //customisation: edit this if you want for example read and copy only 4 or 6 channels from channel 12 or 48 or whatever. 37 | const int number_of_channels=512; //512 for 512 channels 38 | const int channel_position=1; // 1 if you want to read from channel 1 39 | 40 | //buffers 41 | const int MAX_BUFFER_UDP=1024;//definition to do to make work UDP lib 42 | char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to store incoming data 43 | byte buffer_dmx[number_of_channels+channel_position]; //buffer to store filetered DMX data 44 | 45 | // art net parameters 46 | unsigned int localPort = 6454; // artnet UDP port is by default 6454 47 | const int art_net_header_size=17; 48 | const int max_packet_size=576; 49 | char ArtNetHead[8]="Art-Net"; 50 | char OpHbyteReceive=0; 51 | char OpLbyteReceive=0; 52 | short is_artnet_version_1=0; 53 | short is_artnet_version_2=0; 54 | short seq_artnet=0; 55 | short artnet_physical=0; 56 | short incoming_universe=0; 57 | boolean is_opcode_is_dmx=0; 58 | boolean is_opcode_is_artpoll=0; 59 | boolean match_artnet=1; 60 | short Opcode=0; 61 | EthernetUDP Udp; 62 | 63 | void setup() { 64 | // Uncomment/edit one of the following lines for your leds arrangement. 65 | // FastLED.addLeds(leds, NUM_LEDS); 66 | // FastLED.addLeds(leds, NUM_LEDS); 67 | // FastLED.addLeds(leds, NUM_LEDS); 68 | // FastLED.addLeds(leds, NUM_LEDS); 69 | // FastLED.addLeds(leds, NUM_LEDS); 70 | // FastLED.addLeds(leds, NUM_LEDS); 71 | // FastLED.addLeds(leds, NUM_LEDS); 72 | // FastLED.addLeds(leds, NUM_LEDS); 73 | // FastLED.addLeds(leds, NUM_LEDS); 74 | // FastLED.addLeds(leds, NUM_LEDS); 75 | // FastLED.addLeds(leds, NUM_LEDS); 76 | 77 | // FastLED.addLeds(leds, NUM_LEDS); 78 | // FastLED.addLeds(leds, NUM_LEDS); 79 | // FastLED.addLeds(leds, NUM_LEDS); 80 | 81 | // FastLED.addLeds(leds, NUM_LEDS); 82 | // FastLED.addLeds(leds, NUM_LEDS); 83 | // FastLED.addLeds(leds, NUM_LEDS); 84 | // FastLED.addLeds(leds, NUM_STRIPS); 85 | 86 | //setup ethernet and udp socket 87 | Ethernet.begin(mac,ip); 88 | Udp.begin(localPort); 89 | Serial.begin(9600); 90 | } 91 | 92 | void loop() { 93 | int packetSize = Udp.parsePacket(); 94 | 95 | //FIXME: test/debug check 96 | //if(packetSize>art_net_header_size && packetSize<=max_packet_size)//check size to avoid unneeded checks 97 | if(packetSize) { 98 | Serial.print("Packet received! (size: "); 99 | Serial.print(packetSize); 100 | Serial.print(") \n"); 101 | Serial.print(art_net_header_size); 102 | Serial.print("\n"); 103 | Serial.print(max_packet_size); 104 | Serial.print("\n"); 105 | 106 | IPAddress remote = Udp.remoteIP(); 107 | remotePort = Udp.remotePort(); 108 | Udp.read(packetBuffer,UDP_TX_PACKET_MAX_SIZE); 109 | 110 | //read header 111 | match_artnet=1; 112 | for (int i=0;i<7;i++) { 113 | //if not corresponding, this is not an artnet packet, so we stop reading 114 | if(char(packetBuffer[i])!=ArtNetHead[i]) { 115 | match_artnet=0;break; 116 | } 117 | } 118 | 119 | //if its an artnet header 120 | if(match_artnet==1) { 121 | //artnet protocole revision, not really needed 122 | //is_artnet_version_1=packetBuffer[10]; 123 | //is_artnet_version_2=packetBuffer[11];*/ 124 | 125 | //sequence of data, to avoid lost packets on routeurs 126 | //seq_artnet=packetBuffer[12];*/ 127 | 128 | //physical port of dmx N° 129 | //artnet_physical=packetBuffer[13];*/ 130 | 131 | //operator code enables to know wich type of message Art-Net it is 132 | Opcode=bytes_to_short(packetBuffer[9],packetBuffer[8]); 133 | 134 | //if opcode is DMX type 135 | if(Opcode==0x5000) { 136 | is_opcode_is_dmx=1;is_opcode_is_artpoll=0; 137 | } 138 | 139 | //if opcode is artpoll 140 | else if(Opcode==0x2000) { 141 | is_opcode_is_artpoll=1;is_opcode_is_dmx=0; 142 | //( we should normally reply to it, giving ip adress of the device) 143 | } 144 | 145 | //if its DMX data we will read it now 146 | if(is_opcode_is_dmx=1) { 147 | //if you need to filter DMX universes, uncomment next line to have the universe rceived 148 | //incoming_universe= bytes_to_short(packetBuffer[15],packetBuffer[14]) 149 | 150 | //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 151 | //channel position 152 | for(int i=channel_position-1;i< number_of_channels;i++) { 153 | buffer_dmx[i]= byte(packetBuffer[i+17]); 154 | } 155 | } 156 | }//end of sniffing 157 | 158 | for(int k=6; k<9; k++) { 159 | Serial.print(buffer_dmx[k]); 160 | Serial.print(", "); 161 | } 162 | Serial.println(""); 163 | 164 | //stuff to do on PWM or whatever 165 | //analogWrite(3,buffer_dmx[6]); 166 | //analogWrite(5,buffer_dmx[7]); 167 | //analogWrite(6,buffer_dmx[8]); 168 | } 169 | } 170 | 171 | 172 | -------------------------------------------------------------------------------- /ArtnetTest/ArtnetTest.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Artnet DMX Test 3 | Arduino Mega 2560 4 | Hardware: Conceptinetics DMX Shield 5 | P9813 RGB LED Strip Driver Modules 6 | */ 7 | 8 | #include // needed for Arduino versions later than 0018 9 | #include 10 | #include // UDP library from: bjoern@cs.stanford.edu 12/30/2008 11 | #define short_get_high_byte(x) ((HIGH_BYTE & x) >> 8) 12 | #define short_get_low_byte(x) (LOW_BYTE & x) 13 | #define bytes_to_short(h,l) ( ((h << 8) & 0xff00) | (l & 0x00FF) ); 14 | 15 | //MAC and IP of the ethernet shield 16 | //MAC adress of the ethershield is stamped down the shield 17 | //to translate it from hexa decimal to decimal, use: http://www.frankdevelopper.com/outils/convertisseur.php 18 | //HARDWARE 19 | byte mac[] = {144, 162, 218, 00, 16, 96}; //the mac adress of ethernet shield or uno shield board 20 | byte ip[] = {192, 168, 0, 20}; // the IP adress of your device, that should be in same universe of the network you are using, here: 192.168.1.x 21 | 22 | // the next two variables are set when a packet is received 23 | byte remoteIp[4]; // holds received packet's originating IP 24 | unsigned int remotePort; // holds received packet's originating port 25 | 26 | //customisation: edit this if you want for example read and copy only 4 or 6 channels from channel 12 or 48 or whatever. 27 | const int number_of_channels=512; //512 for 512 channels 28 | const int channel_position=1; // 1 if you want to read from channel 1 29 | 30 | //buffers 31 | const int MAX_BUFFER_UDP=1024;//definition to do to make work UDP lib 32 | char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to store incoming data 33 | byte buffer_dmx[number_of_channels+channel_position]; //buffer to store filetered DMX data 34 | 35 | // art net parameters 36 | unsigned int localPort = 6454; // artnet UDP port is by default 6454 37 | const int art_net_header_size=17; 38 | const int max_packet_size=576; 39 | char ArtNetHead[8]="Art-Net"; 40 | char OpHbyteReceive=0; 41 | char OpLbyteReceive=0; 42 | short is_artnet_version_1=0; 43 | short is_artnet_version_2=0; 44 | short seq_artnet=0; 45 | short artnet_physical=0; 46 | short incoming_universe=0; 47 | boolean is_opcode_is_dmx=0; 48 | boolean is_opcode_is_artpoll=0; 49 | boolean match_artnet=1; 50 | short Opcode=0; 51 | EthernetUDP Udp; 52 | 53 | int onboardLED = 13; 54 | 55 | void setup() { 56 | //setup ethernet and udp socket 57 | Ethernet.begin(mac,ip); 58 | Udp.begin(localPort); 59 | Serial.begin(9600); 60 | 61 | // set the onboard led pin to OUTPUT mode 62 | pinMode(onboardLED, OUTPUT); 63 | } 64 | 65 | void loop() { 66 | int packetSize = Udp.parsePacket(); 67 | 68 | //FIXME: test/debug check 69 | //if(packetSize>art_net_header_size && packetSize<=max_packet_size)//check size to avoid unneeded checks 70 | if(packetSize) { 71 | Serial.print("Packet received! (size: "); 72 | Serial.print(packetSize); 73 | Serial.print(") \n"); 74 | Serial.print(art_net_header_size); 75 | Serial.print("\n"); 76 | Serial.print(max_packet_size); 77 | Serial.print("\n"); 78 | 79 | IPAddress remote = Udp.remoteIP(); 80 | remotePort = Udp.remotePort(); 81 | Udp.read(packetBuffer,UDP_TX_PACKET_MAX_SIZE); 82 | 83 | //read header 84 | match_artnet=1; 85 | for (int i=0;i<7;i++) { 86 | //if not corresponding, this is not an artnet packet, so we stop reading 87 | if(char(packetBuffer[i])!=ArtNetHead[i]) { 88 | match_artnet=0;break; 89 | } 90 | } 91 | 92 | //if its an artnet header 93 | if(match_artnet==1) { 94 | //artnet protocole revision, not really needed 95 | //is_artnet_version_1=packetBuffer[10]; 96 | //is_artnet_version_2=packetBuffer[11];*/ 97 | 98 | //sequence of data, to avoid lost packets on routeurs 99 | //seq_artnet=packetBuffer[12];*/ 100 | 101 | //physical port of dmx N° 102 | //artnet_physical=packetBuffer[13];*/ 103 | 104 | //operator code enables to know wich type of message Art-Net it is 105 | Opcode=bytes_to_short(packetBuffer[9],packetBuffer[8]); 106 | 107 | //if opcode is DMX type 108 | if(Opcode==0x5000) { 109 | is_opcode_is_dmx=1;is_opcode_is_artpoll=0; 110 | } 111 | 112 | //if opcode is artpoll 113 | else if(Opcode==0x2000) { 114 | is_opcode_is_artpoll=1;is_opcode_is_dmx=0; 115 | //( we should normally reply to it, giving ip adress of the device) 116 | } 117 | 118 | //if its DMX data we will read it now 119 | if(is_opcode_is_dmx=1) { 120 | //if you need to filter DMX universes, uncomment next line to have the universe rceived 121 | //incoming_universe= bytes_to_short(packetBuffer[15],packetBuffer[14]) 122 | 123 | //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 124 | //channel position 125 | for(int i=channel_position-1;i< number_of_channels;i++) { 126 | buffer_dmx[i]= byte(packetBuffer[i+17]); 127 | } 128 | } 129 | }//end of sniffing 130 | 131 | for(int k=6; k<9; k++) { 132 | Serial.print(buffer_dmx[k]); 133 | Serial.print(", "); 134 | } 135 | Serial.println(""); 136 | 137 | //stuff to do on PWM or whatever 138 | //analogWrite(3,buffer_dmx[6]); 139 | //analogWrite(5,buffer_dmx[7]); 140 | //analogWrite(6,buffer_dmx[8]); 141 | 142 | } 143 | } 144 | 145 | 146 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Arduino-Artnet-DMX-Node 2 | ======================= 3 | 4 | Arduino Artnet DMX Node 5 | Arduino Mega 2560 6 | Ethernet Shield 7 | 8 | Modify the code to have the MAC address of the Ethernet Shield you're using, and a suitable IP Address. 9 | 10 | Connect the arduino to anything you want to control with DMX - Modify the code to suit. 11 | 12 | I will be publishing a relay module version, an addressable led controlling version and a PWM led driver version. 13 | --------------------------------------------------------------------------------