Pages: [1]   Go Down
Author Topic: Art-Net transmission via UDP ver 1.0 vs ver 22  (Read 1433 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Code:
/*
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
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Here is the v22 sketch

Code:
/*
artnet_Send for V22

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 <Udp.h>
#include <Stdint.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

//  ****  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:
  {
    int goodUdp = Udp.sendPacket(packetBuffer,MAX_BUFFER_UDP,sendIp, localPort);  //depreciated for Uno
    if (goodUdp > 0) 
    {
      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);
}


Any thoughts about what I am doing wrong?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have just discovered that Udp.endPacket() is returning an error(value of 0), and taking 1800millis to do so.

Am I not implementing the new protocols correctly?
Udp.beginPacket returns a 1, which is a sucessful execution,
Udp.write returns a 531, which would be the correct size of the buffer being written

anyone have thoughts?
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Typically, 0 means success. Why do you think that 0 means that an error occurred?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Well, I have it working, but I don't understand why.

I changed the IP to which I am sending, to be 255.255.255.255, instead of sending to ip[0].255.255.255.

my understanding is that I am now broadcasting to all IP's, where before I was only broadcasting to IP's in the same subnet.  am I misunderstanding this? 

Can someone explain why it would work in the old version, but not the current version?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@Paul
this is copied from EthernetUdp.h

Code:
// Finish off this packet and send it
  // Returns 1 if the packet was sent successfully, 0 if there was an error
  virtual int endPacket();
Logged

Pages: [1]   Go Up
Jump to: