I have a sketch for transmitting the Artnet UDP protocol that works properly when compiled and uploaded with Arduino V22. When I compile and upload with Arduino 1.0 (after changing what I think are the appropriate calls), it does not transmit properly.
When I run wire shark on the transmission, it is being transmitted as an ARP packet, instead of a UDP packet.
I am running a Duemilanove, with a w.5100 Ethernet Shield.
Attached you will find both the V22 and v1.0 sketches.
Here is the v1.0 sketch
/*
artnet_Send for V1.0
potentiometers attached to analog in 0 and 1
sends artnet packets every 3.5 seconds, or when Potentiometers change.
*/
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x87, 0xD5 };
byte ip[] = { 192, 168, 15,12}; // local network IP
//byte ip[] = { 2, 0, 0, 177 }; // proper Artnet protocol IP
byte gw[] = {ip[0], ip[1], ip[2], 1 };
byte sn[] = { 255, 0, 0, 0 };
byte sendIp[] = {ip[0], 255, 255, 255};
unsigned int localPort = 6454; // art-net communicates via UDP Port=6454
// **** Constants ****
const int Number_of_Channels=512;
const int MAX_BUFFER_UDP = 531;//18+512+1; //18bit UDP Header+512bit DMX Packet+1 stopbit
EthernetUDP Udp;
// **** buffers ****
//char
uint8_t packetBuffer[MAX_BUFFER_UDP]; //UDP packet, 0-17 header, 18 - 530 dmx buffer
unsigned char buffer_dmx[Number_of_Channels];
// **** Art-Net identification Variables ****
unsigned char ArtNetHead[8]="Art-Net"; //field 1, (0-7)
short Opcode=0x5000;
byte artnet_version_1= 0; //field 3 (10)
byte artnet_version_2=14; //field 4 (11)
byte seq_artnet=0; //filed 5 (12)
byte artnet_physical=0; //field 6 (13)
//int incoming_universe = 0; //field 7 (15, 14)
int dmx_chan_tx = 512; //field 8 & 9 (16-17)
int packetSize = 0;
int sendUniverse = 2;//universe of artnet to be sent
int sendDmxCh = 508; // Base channel of DMX to be sent on selected Universe
int sendDmxNum = 2; // Number of DMX Channels actually sent
long lastTxTime = 0; //time of last transmission
int maxTxTime = 3500; //3.5 seconds maximum between transmissions
boolean diffDmxVal = 0; // has the DMX changed?
// slider pot input it generate DMX Value
const int levelPin[] = {0,1};
void setup()
{
pinMode(4,OUTPUT);
digitalWrite(4,HIGH); //Disables SD card
Serial.begin(9600);
Ethernet.begin( mac, ip, gw, sn);
Udp.begin(localPort);
for (int i = 0; i<dmx_chan_tx; i++) // Set initial DMX Values to 0
{
buffer_dmx[i] = 0;
} //end set DMX values to 0
for (int i = 18; i<MAX_BUFFER_UDP; i++) //set packet buffer to all '0', except header
{
packetBuffer[i] = 0;
}
// Set PAcket Header into Buffer
for (int i = 0; i<8; i++)
{
packetBuffer[i] = ArtNetHead[i];
}
packetBuffer[8] = 0x00;//Opcode; // low byte
packetBuffer[9] = 0x50;//(Opcode >> 8); // high byte
packetBuffer[10] = artnet_version_1; //Protocol Version HIGH
packetBuffer[11] = artnet_version_2; // Prococol Version LOW
//packetBUffer[12] = seq_artnet: // sequence number(increment with each transmission)
packetBuffer[13] = artnet_physical; // physical input receiving DMX signal
packetBuffer[14] = sendUniverse; // universe being transmitted (LOW Byte)
packetBuffer[15] = (sendUniverse >> 8); // universe being transmitted (HIGH Byte)
packetBuffer[16] = (dmx_chan_tx >> 8); // # of transmitting DMX Chan (HIGH byte)
packetBuffer[17] = dmx_chan_tx; // # of transmitting DMX Chan (LOW byte)
}// end setup
void loop()
{
//read potentiometer, convert reading to scale (0-FF)
for (int i =0; i< sendDmxNum; i++)
{
buffer_dmx[sendDmxCh+i] = getLevel(i); //insert reading from potentiometer into DMX Buffer
if (buffer_dmx[sendDmxCh+i] == packetBuffer[sendDmxCh+17+i] && diffDmxVal == false)
{
diffDmxVal = false;//if no change of DMX value, do not send packet
} else
{
diffDmxVal = true; //if change of DMX value, write into UDP buffer, and send packet
}
// copy values from buffer_dmx into packetBuffer
packetBuffer[sendDmxCh+17+i] = buffer_dmx[sendDmxCh +i];
}
// ***** max time between transmissions
if (millis() - lastTxTime > maxTxTime)
{
diffDmxVal = true;
}
packetBuffer[12] = seq_artnet; //load seq# into UDP buffer
//Send Artnet packet if value change, or timeout
switch (diffDmxVal)
{
case false: //if no new DMX value, do not transmit
break;
case true:
{
Udp.beginPacket(sendIp, localPort);
Udp.write(packetBuffer,MAX_BUFFER_UDP); //
int goodUdp = Udp.endPacket(); //send the built packet
// int goodUdp = Udp.sendPacket(packetBuffer,MAX_BUFFER_UDP,sendIp, localPort); //depreciated for Uno
if (goodUdp == 1)
{
lastTxTime = millis(); //packet sent, reset timer,
seq_artnet ++; //increment Sequence Number in artnet header
}
diffDmxVal =false; //reset state change detection
}
break;
}
delay(10);
}//end loop
unsigned char getLevel(int i)
{
int levelPot = analogRead(levelPin[i]);
levelPot = map(levelPot,0,1023,0,255);
return(levelPot);
}
V22 will follow in next post