Looking for a little help with UDP between two Arduinos

I am running Arduino 1.0 with both an Uno and a Mega 2560. Both are wearing DFRobot ethernet shields v.2 (Mega-compatible). I can make all of the ethernet examples work on my local network and the internet but only if I manually configure them as DHCP doesn't want to work. I think it's my gateway IP or something.

Anyways, I am trying to use one Arduino (the Uno) to control the other (The Mega 2560) through UDP, straight through, no switches or anything. I can make the UDP example run and the processing sketch does its thing and the Arduino spits out the response through serial. So that part all works. However, I cannot find any examples that don't require an incoming packet first. I mean, all of the examples involve iPods, processing, etc to initiate and the Arduino responds and captures the IP and port from the incoming packet in order to send its reply. How can I code it so that I know all of that ahead of time? The addresses for both boards are going to be fixed so I would like to just configure that right into the program.

I did find this thread:

but I am using the latest IDE so it refuses to compile. I have figured out the first few errors and supplied updated code but it just keeps finding more. Also, am I correct in believing that UDP can only send 'char' values or can I send other data types?

For the record, I spent many hours Googling every possible avenue I can think of but have seen no code examples that work for me. And yes, I did search the forum pretty hard as well, that's how I found the above thread. Also, this is my first post so take it easy on me. I only have about 10 hours experience with the Arduino and have already figured out quite a bit but this is just not sinking in for me. My only other programming experience is PLCs and HTML/CSS if you want to count those. I don't.

Thanks,

Spugnoid

How close are they? You can't use serial, I2C or SPI can you?

Assuming you can't, I haven't played much with UDP on Arduino, but since it is a connectionless protocol you should just be able to fire off a UDP packet when you feel like it.

For now they are connected with a patch cable but eventually they will be about 200ft apart. I have been able to hack together a sketch that makes the rx tx lights blink like mad but despite the Serial.print command, nothing shows up.

Right then. Better post your code.

Please put it between [code] ... [/code] tags.

You can do that by hitting the # button above the posting area.

Okay, the 2560 is running this:

#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, 0xAD, 0x6E, 0xEF, 0xFA, 0xED };
IPAddress ip(192, 168, 1, 157);

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

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

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

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

}

void loop() {

  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.println("Contents:");
    Serial.println(packetBuffer);
}
    // Ok, this is just tacked on straight from the ethernet reference.
    // TX RX flash like mad but neither board gives anything from serial mon.
    // If I understand correctly, this will just repeatedly broadcast 'hello'
    // Which should be received by the other board which will then reply with
    // The canned 'acknowledged' from the UDPSendReceiveString example code.
    // But obviously I'm wrong because my code doesn't work. :)
    Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
    Udp.write("hello");
    Udp.endPacket();
    
    delay(13);
}

Which is obviously just two bits of code stolen right from the ethernet library reference.

The Uno is running this code:

#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, 0xEF, 0xAE, 0xED };
IPAddress ip(192, 168, 1, 107);

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);
    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();
  }
  // 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(17);
}

Which is just the UDPSendReceive example from the IDE.

I (wrongly) assumed that if I just broadcasted a packet, the other one would pick it up and reply with its own. But, both serial monitors are blank.

I hope my total lack of understanding of the Ethernet/UDP library isn't showing too badly. :blush:

Here:

    Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
    Udp.write("hello");
    Udp.endPacket();

I assume what you are trying to do is listen for a packet, and then (whether or not you get one) send one of your own. But to what port?

Exactly, I can't figure out how to correctly put the 'To' port and/or IP in my code. All the examples assume a reply to a known IP on the Arduino which then replies to the address that sent the packet. None of them show the correct way of setting the address in the code without receiving a packet to begin with. I've tried a few things but it doesn't compile.

I see. Well you have two options here. First, you are designing the system, right? So you know the address. So you can hard-code it.

Alternatively (and this is done a bit on local networks) you broadcast to within the subnet:

For example, this is how DHCP works. How can a PC request an IP address, when it doesn't know who to ask? It broadcasts a special request.

A big part of the problem is I'm unsure of the syntax to hardcode it. :frowning:

This compiles, I'll let you have the fun of testing it:

    Udp.beginPacket(IPAddress (255, 255, 255, 255), 8888);

This is what I've got now,

#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, 0xAD, 0x6E, 0xEF, 0xFA, 0xED };
IPAddress ip(192, 168, 1, 157);
IPAddress subnet(255,255,255,0);

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


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

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

void setup() {
  // start the Ethernet and UDP:
  Ethernet.begin(mac,ip,subnet);
  Udp.begin(localPort);
  
  Serial.begin(9600);  // Forgot this before. Oops.
}

void loop() {

  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.println("Contents:");
    Serial.println(packetBuffer);
}
    // Trying to poke the other board into replying
    Udp.beginPacket(IPAddress (192, 168, 1, 107), 8888);
    Udp.write("Hello World");
    Udp.endPacket();
    Serial.println("test");  // prove serial mon is working
    
    delay(100);
}

TX on fairly solid, RX on solid on the other board. No reply triggered and nothing on serial mon. I'm still trying stuff but even if it compiles it doesn't seem to work.

Okay, for whatever reason, this morning it works. I made no code changes from last night but I did power down both boards overnight.

I appreciate your help, now I just have to figure out what I did.

Spugnoid