Still struggling to send data over UDP

Okay, first of all I am trying to communicate between two arduinos (uno and 2560) over ethernet shields using UDP. My UNO code (transmitting side) is such:

#include <SPI.h>        
#include <Ethernet.h>
#include <EthernetUdp.h>

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {0xDE, 0xAB, 0x64, 0xEF, 0xFA, 0xED };
IPAddress ip(192, 168, 1, 100);
IPAddress subnet(255,255,255,0);
unsigned int localPort = 8888;      // local port to listen on

// testing stuff
char axisBufferOut[10];
char directionBufferOut[10];
char valueBufferOut[10];
char checksumBufferOut[10];

// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;

char packetBufferIn[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet,


//////////////////////////////////////////////////////////////////////////////////
// CONSTANTS
//////////////////////////////////////////////////////////////////////////////////
const byte totalAxes = 3;          // Count from zero
const byte deadband = 20;          // Create a deadband in the center of each pot


//////////////////////////////////////////////////////////////////////////////////
// VARIABLES
//////////////////////////////////////////////////////////////////////////////////
byte activeAxis = 0;    // set this to start at zero, or the first axis
int axisZero = A0;
int axisOne = A1;
int axisTwo = A2;
int axisThree = A3;
int checksum;    // checksum for packet

//testing
int analogIn;
char outBuffer[4];
byte index=0;


//////////////////////////////////////////////////////////////////////////////////
// ARRAYS
//////////////////////////////////////////////////////////////////////////////////
byte axesArray[] = {axisZero,axisOne,axisTwo,axisThree};  // Array of analog pins, one for each axis
int axesNewArray[4];    // an array to hold analog values until they can be compared to existing value
int axesOldArray[4];    // an array to hold the final analog raw value
int axesFinalArray[4];    // an array to hold the filtered and centered value
byte axesFlagArray[4];    // an array to hold the axes direction flags


//////////////////////////////////////////////////////////////////////////////////
// SETUP
//////////////////////////////////////////////////////////////////////////////////
void setup() {
  // start the Ethernet and UDP:
  Ethernet.begin(mac,ip,subnet);
  Udp.begin(localPort);

  // zero the arrays
  byte a;
  for (a = 0; a <= 3; a = a + 1) {
  axesOldArray[a] = 0;
}
  for (a = 0; a <= 3; a = a + 1) {
  axesNewArray[a] = 0;
}
  for (a = 0; a <= 3; a = a + 1) {
  axesFinalArray[a] = 0;
  }
  
  Serial.begin(9600);
}

//////////////////////////////////////////////////////////////////////////////////
// MAIN PROGRAM
//////////////////////////////////////////////////////////////////////////////////
void loop(){
          
  axesNewArray[activeAxis] = analogRead(axesArray[activeAxis]);    // ...read the active pin
  Serial.println(axesFinalArray[0]);

  if(axesNewArray[activeAxis] >= axesOldArray[activeAxis] +2 || axesNewArray[activeAxis] <= axesOldArray[activeAxis] -2)
  {
    axesOldArray[activeAxis] = axesNewArray[activeAxis];    // copy new value into old value
    axesFinalArray[activeAxis] = axesOldArray[activeAxis];    // make final value the same
    axesFinalArray[activeAxis] /= 2;    // make the range 0-511
    axesFinalArray[activeAxis] -= 255;    // make the center of the pot zero
        
    // set zero value if in deadband
    if(axesFinalArray[activeAxis] > -deadband && axesFinalArray[activeAxis] < deadband)    // check to see if value is in deadband
    {
      axesFinalArray[activeAxis] = 0;    // make the result equal zero in the center if it is in deadband
    }
      
    // set axis to go from 0 at center to 255 at extreme
    if(axesFinalArray[activeAxis] < 0)
    {
      axesFinalArray[activeAxis] = map(axesFinalArray[activeAxis], -deadband, -255, 0, 255);
      axesFlagArray[activeAxis] = 0;    // need direction flag set here
    }
    else if(axesFinalArray[activeAxis] > 0)
    {
      axesFinalArray[activeAxis] = map(axesFinalArray[activeAxis], deadband, 256, 0, 255);
      axesFlagArray[activeAxis] = 1;      // need direction flag set here
    }
    else
    {
      axesFinalArray[activeAxis] = 0;    // set value to zero if in deadband
    }
  } 
   
  
  // index the pointer down to the next axis
  if(activeAxis < totalAxes)    // check if the active axis is the last one or not
  {
    ++activeAxis;    // increment it otherwise
  }
  else
  {
    activeAxis = 0;    // set it back to zero
  }
 
  //transmit();
    Serial.print("  before-->");
    Serial.println(axesFinalArray[0]);
  //  analogIn = axesFinalArray[0];
  //  itoa(analogIn,outBuffer,10); // last number is radix
  //  outBuffer[0] = analogIn;    // Contents of packet
    outBuffer[0] = axesFinalArray[0];
    //outBuffer[0] = '\0';
    Serial.print("  after-->");
    Serial.println(outBuffer[0]);    
    

    // Trying to poke the other board into replying
    Udp.beginPacket(IPAddress (192, 168, 1, 200), 8888);
    Udp.write(outBuffer[0]);
    Udp.endPacket();
    
    Serial.print("outBuffer--");
    Serial.println(outBuffer[0]);

  
  
  
  //delay(250);
}

//////////////////////////////////////////////////////////////////////////////////
// FUNCTIONS
//////////////////////////////////////////////////////////////////////////////////
int transmit() {
  //checksum = axesArray[activeAxis] + axesFlagArray[activeAxis] + axesFinalArray[activeAxis];
  
  //itoa(axesArray[activeAxis],axisBufferOut,10);
  //itoa(axesFlagArray[activeAxis],directionBufferOut,10);
  //itoa(axesFinalArray[activeAxis],valueBufferOut,10);
  //itoa(checksum,checksumBufferOut,10);
  
  Serial.println(valueBufferOut);
  
    // build and send packet
    Udp.beginPacket(IPAddress (192, 168, 1, 200), 8888);
    Udp.write(axisBufferOut);
    //Udp.write(directionBufferOut);
    //Udp.write(valueBufferOut);
    //Udp.write(checksumBufferOut);
    Udp.endPacket();
    
    //Serial.println(axisBufferOut);
}

The Mega 2560 (receiving side) is:

#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


// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {  
  0xDE, 0xAD, 0xBE, 0xFF, 0xFE, 0xBB };
IPAddress ip(192, 168, 1, 200);

unsigned int localPort = 8888;      // local port to listen on

// buffers for receiving and sending data
char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet,
char  ReplyBuffer[] = "acknowledged";       // a string to send back

// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;

void setup() {
  // start the Ethernet and UDP:
  Ethernet.begin(mac,ip);
  Udp.begin(localPort);

  Serial.begin(9600);
}

void loop() {
  // if there's data available, read a packet
  int packetSize = Udp.parsePacket();
  if(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());

    // read the packet into packetBufffer
    Udp.read(packetBuffer,UDP_TX_PACKET_MAX_SIZE);
    int a = atoi(packetBuffer); // am I using this wrong?!!!
    Serial.print("a-");
    Serial.println(a);
    Serial.println("Contents:");
    Serial.println(packetBuffer);

    // send a reply, to the IP address and port that sent us the packet we received
    Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
    Udp.write(ReplyBuffer);
    Udp.endPacket();
  }
  delay(10);
}

All I'm trying to do is read an analog in, convert it to 0-255 and send it to the 2560 which is supposed to unscramble it back to 0-255. I can see the ASCII character that I'm sending on both sides but some extra garbage is added on the receiving side. I think I need to null terminate it but am not sure of the syntax for that. Also, how to I get it back to a byte?

Any tips are greatly appreciated.

spugnoid

If you are using Arduino 1.0 and want to specify the IP address you also have to specify the Default Gateway and DNS Server addresses before you specify the Subnet Mask.

I think you are passing the subnet mask as the DNS Server address.

    int a = atoi(packetBuffer); // am I using this wrong?!!!

Yes - you are sending one byte, you don't need to convert it. You sent one byte so the first byte of packetBuffer would be it, right?

Okay, thanks for your help I have it running. Seems to be delicate though and depends on a reply from the receiving board in order for the transmission to continue past the first packet. I though UDP didn't look for a reply?

Anyways, here is the state of things now (it's full of test edits and workarounds and such but this is what is running successfully)

Transmission side:

#include <SPI.h>        
#include <Ethernet.h>
#include <EthernetUdp.h>

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {0xDE, 0xAB, 0x64, 0xEF, 0xFA, 0xED };
IPAddress ip(192, 168, 1, 100);
unsigned int localPort = 8888;      // local port to listen on

// testing stuff
char axisBufferOut[10];
char directionBufferOut[10];
char valueBufferOut[10];
char checksumBufferOut[10];

// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;

char packetBufferIn[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet,


//////////////////////////////////////////////////////////////////////////////////
// CONSTANTS
//////////////////////////////////////////////////////////////////////////////////
const byte totalAxes = 3;          // Count from zero
const byte deadband = 20;          // Create a deadband in the center of each pot


//////////////////////////////////////////////////////////////////////////////////
// VARIABLES
//////////////////////////////////////////////////////////////////////////////////
byte activeAxis = 0;    // set this to start at zero, or the first axis
int axisZero = A0;
int axisOne = A1;
int axisTwo = A2;
int axisThree = A3;
int checksum;    // checksum for packet

//testing
int analogIn;
byte outBuffer[4];
byte index=0;


//////////////////////////////////////////////////////////////////////////////////
// ARRAYS
//////////////////////////////////////////////////////////////////////////////////
byte axesArray[] = {axisZero,axisOne,axisTwo,axisThree};  // Array of analog pins, one for each axis
int axesNewArray[4];    // an array to hold analog values until they can be compared to existing value
int axesOldArray[4];    // an array to hold the final analog raw value
int axesFinalArray[4];    // an array to hold the filtered and centered value
byte axesFlagArray[4];    // an array to hold the axes direction flags


//////////////////////////////////////////////////////////////////////////////////
// SETUP
//////////////////////////////////////////////////////////////////////////////////
void setup() {
  // start the Ethernet and UDP:
  Ethernet.begin(mac,ip);
  Udp.begin(localPort);

  // zero the arrays
  byte a;
  for (a = 0; a <= 3; a = a + 1) {
  axesOldArray[a] = 0;
}
  for (a = 0; a <= 3; a = a + 1) {
  axesNewArray[a] = 0;
}
  for (a = 0; a <= 3; a = a + 1) {
  axesFinalArray[a] = 0;
  }
  
  //Serial.begin(9600);
}

//////////////////////////////////////////////////////////////////////////////////
// MAIN PROGRAM
//////////////////////////////////////////////////////////////////////////////////
void loop(){
          
  axesNewArray[activeAxis] = analogRead(axesArray[activeAxis]);    // ...read the active pin

  if(axesNewArray[activeAxis] >= axesOldArray[activeAxis] +2 || axesNewArray[activeAxis] <= axesOldArray[activeAxis] -2)
  {
    axesOldArray[activeAxis] = axesNewArray[activeAxis];    // copy new value into old value
    axesFinalArray[activeAxis] = axesOldArray[activeAxis];    // make final value the same
    axesFinalArray[activeAxis] /= 2;    // make the range 0-511
    axesFinalArray[activeAxis] -= 255;    // make the center of the pot zero
        
    // set zero value if in deadband
    if(axesFinalArray[activeAxis] > -deadband && axesFinalArray[activeAxis] < deadband)    // check to see if value is in deadband
    {
      axesFinalArray[activeAxis] = 0;    // make the result equal zero in the center if it is in deadband
    }
      
    // set axis to go from 0 at center to 255 at extreme
    if(axesFinalArray[activeAxis] < 0)
    {
      axesFinalArray[activeAxis] = map(axesFinalArray[activeAxis], -deadband, -255, 0, 255);
      axesFlagArray[activeAxis] = 0;    // need direction flag set here
    }
    else if(axesFinalArray[activeAxis] > 0)
    {
      axesFinalArray[activeAxis] = map(axesFinalArray[activeAxis], deadband, 256, 0, 255);
      axesFlagArray[activeAxis] = 1;      // need direction flag set here
    }
    else
    {
      axesFinalArray[activeAxis] = 0;    // set value to zero if in deadband
    }
  } 
   
  
  // index the pointer down to the next axis
  if(activeAxis < totalAxes)    // check if the active axis is the last one or not
  {
    ++activeAxis;    // increment it otherwise
  }
  else
  {
    activeAxis = 0;    // set it back to zero
  }
 
  //transmit();
    Serial.print("  before-->");
    Serial.println(axesFinalArray[0]);
  //  analogIn = axesFinalArray[0];
  //  itoa(analogIn,outBuffer,10); // last number is radix
  //  outBuffer[0] = analogIn;    // Contents of packet
    outBuffer[0] = axesFinalArray[0];
    //outBuffer[0] = '\0';
    Serial.print("  after-->");
    Serial.println(outBuffer[0]);    
    

    // Trying to poke the other board into replying
    Udp.beginPacket(IPAddress (192, 168, 1, 200), 8888);
    Udp.write(outBuffer[0]);
    Udp.endPacket();
    
    Serial.print("outBuffer--");
    Serial.println(outBuffer[0]);
  
  //delay(20);
}

//////////////////////////////////////////////////////////////////////////////////
// FUNCTIONS  --not used currently
//////////////////////////////////////////////////////////////////////////////////
/*
int transmit() {
  //checksum = axesArray[activeAxis] + axesFlagArray[activeAxis] + axesFinalArray[activeAxis];
  
  //itoa(axesArray[activeAxis],axisBufferOut,10);
  //itoa(axesFlagArray[activeAxis],directionBufferOut,10);
  //itoa(axesFinalArray[activeAxis],valueBufferOut,10);
  //itoa(checksum,checksumBufferOut,10);
  
  Serial.println(valueBufferOut);
  
    // build and send packet
    Udp.beginPacket(IPAddress (192, 168, 1, 200), 8888);
    Udp.write(axisBufferOut);
    //Udp.write(directionBufferOut);
    //Udp.write(valueBufferOut);
    //Udp.write(checksumBufferOut);
    Udp.endPacket();
    
    //Serial.println(axisBufferOut);
}
*/

And the receiving side:

#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

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {  
  0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF };
IPAddress ip(192, 168, 1, 200);

unsigned int localPort = 8888;      // local port to listen on

int incomingBuffer; // int to hold converted incoming ascii
int analogOut;
int bufferOut;
int analogOld;
byte received;

// buffers for receiving and sending data
byte packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet,
char  ReplyBuffer[] = "acknowledged";       // a string to send back

// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;

void setup() {
  // start the Ethernet and UDP:
  Ethernet.begin(mac,ip);
  Udp.begin(localPort);

  //Serial.begin(9600);
}

void loop() {
  // if there's data available, read a packet
  int packetSize = Udp.parsePacket();
  if(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());
    
    // read the packet into packetBufffer
    Udp.read(packetBuffer,UDP_TX_PACKET_MAX_SIZE);
    //Serial.print("Contents--");
    received = packetBuffer[0];
    //Serial.println(received);
           
    if(received != analogOld) 
    {
      analogOld = received;
      analogWrite(5,analogOld);
    }
    //Serial.print("analogOut--");
    //Serial.println(analogOut);

    // send a reply, to the IP address and port that sent us the packet we received
    Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
    Udp.write(ReplyBuffer);
    Udp.endPacket();
  } 
}

Now so far I can dim an led across the ethernet cable but what I really need is to send a packet consisting of 4 bytes. [axis][direction][value][checksum].

What is required to put 4 bytes together?
Something like this?

Udp.beginPacket(IPAddress (192, 168, 1, 200), 8888);
    Udp.write(outBuffer[0]);
    Udp.write(outBuffer[1]);
    Udp.write(outBuffer[2]);
    Udp.write(outBuffer[3]);
    Udp.endPacket();

If that works, then how to I slice it back into meaningful bytes again? I'm sorry if I'm asking a lot, I don't want someone to write this for me, just a few nudges/shoves in the right direction would be nice. I just can't seem to find any examples of anything similar anywhere.

Thanks again,

Spugnoid

1 Like

Well, I seem to have it figured out now. Even simpler than I thought.

Thanks a lot!

Spugnoid

1 Like