UDP

Greetings, greatest forum of the world.

I’ve learned so much here, thanks for all the interesting posts and answers!

Enough pleasantries.
I have a problem of my own. I have a couple of arduino’s that rely on a sort of telnet protocol to communicate between.
I have searched everywhere, but can’t seem to prevent two arduino’s connecting to one server at the same time. This is a problem because even though the reference says the ethernet library can have four simultaneous connections I can’t seem to find how to address them separately.

in all the examples written on the website (and even on this forum)
client.println
writes to ALL clients connected.
I have read that some have used other libraries like ethernet2 to overcome this, but I wanted to try a different approach.

I wanted to sent a UDP packages to see if an arduino is currently communicating with someone else…

I found this example somewhere on this forum but can’t get it to work.

I have two arduino’s (with an ethernet shield) connected to a router.
I can ping both of them. They can connect to each other via a little telnet program I wrote… But when I upload the following code, the lights flash, but nothing happens… Any ideas?

The code compiles without errors but I can’t figure out what is wrong. I have tried to change the ip addresses, ports… If anyone could tell me where to look next I’d be grateful…
Or post some simple code to sent one byte to another Duino over UDP…

Here’s the code for the sender :

#include <SPI.h>         // needed for Arduino versions later than 0018
#include <Ethernet.h>


// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 
  0x90, 0xA2, 0xDA, 0x00, 0x85, 0x46 };
IPAddress ip(192, 168, 2, 178);
IPAddress rem_ip(192, 168, 2, 177);
unsigned int localPort = 8887;      // local port to listen on
unsigned int remPort = 8888;      // remote port to send to


char rcv;            // Receive character (make this an Array for String Rx)
char snd;            // Transmit character (make this an Array for String Rx)


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


void setup() 
{
  // start the Ethernet and UDP:
  Serial.begin(9600);
  Ethernet.begin(mac,ip);
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
  Udp.begin(localPort);
}



void loop() 
{ 
   
    Udp.beginPacket(rem_ip, remPort);
    Udp.write('1');
    Udp.endPacket();
    delay(1000);
    Udp.beginPacket(rem_ip, remPort);
    Udp.write('0');
    Udp.endPacket();
    delay(1000);    
  
}

Here’s the code for the receiver

#include <SPI.h>         // needed for Arduino versions later than 0018
#include <Ethernet.h>


// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 
  0x90, 0xA2, 0xDA, 0x00, 0x85, 0x46 };
IPAddress ip(192, 168, 2, 177);
IPAddress rem_ip(192, 168, 2, 178);
unsigned int localPort = 8888;      // local port to listen on
unsigned int remPort = 8887;      // remote port to send to


char rcv;            // Receive character (make this an Array for String Rx)
char snd;            // Transmit character (make this an Array for String Rx)


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


void setup() 
{
  // start the Ethernet and UDP:
  Serial.begin(9600);
  Ethernet.begin(mac,ip);
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
  Udp.begin(localPort);
}



void loop() 
{ 
 
  if (RcvPkt()) 
  {
    // We just received a UDP packet so Act on that.
    if (rcv=='1') 
    {
      //digitalWrite(LEDPin,HIGH);
      Serial.println("on");
    }
    else if (rcv=='0') 
    {
      //digitalWrite(LEDPin,LOW);
      Serial.println("off");
    }
  }
}



int RcvPkt() 
{
    // 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(&rcv,1);
    Serial.println("Contents:");
    Serial.println(rcv);
  }
  return packetSize;
}

Thank you very much! Hope it is something simple I missed.

The major network problem I see which will certainly keep your code from working is the duplicate mac addresses on the sender and receiver. They must be unique on that localnet. Change the last octet by one, like this:

// on the sender
byte mac[] = {   0x90, 0xA2, 0xDA, 0x00, 0x85, 0x46 };
// on the receiver
byte mac[] = {   0x90, 0xA2, 0xDA, 0x00, 0x85, 0x47 };

It doesn't have to be those exactly, but no duplicates!

Thank you very much Surfer Tim,

Unfortunately that does not solve the problem… (changed it to 47 as you can see in the code)
I have modified the code slightly, cause I thought that I might have gotten something else than a “1” or a “0”… Still no luck.
I wonder what is wrong, since I can clearly see traffic both on the router and on the two Arduino Boards all lights are flashing disco like…

slightly modified code :

#include <SPI.h>         // needed for Arduino versions later than 0018
#include <Ethernet.h>


// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 
  0x90, 0xA2, 0xDA, 0x00, 0x85, 0x47 };
IPAddress ip(192, 168, 2, 177);
IPAddress rem_ip(192, 168, 2, 178);
unsigned int localPort = 8888;      // local port to listen on
unsigned int remPort = 8887;      // remote port to send to


char rcv;            // Receive character (make this an Array for String Rx)
char snd;            // Transmit character (make this an Array for String Rx)


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


void setup() 
{
  // start the Ethernet and UDP:
  Serial.begin(9600);
  Ethernet.begin(mac,ip);
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
  Udp.begin(localPort);
}



void loop() 
{ 
 
  if (RcvPkt()) 
  {
    Serial.print("Recevied : ");
    // We just received a UDP packet so Act on that.
    if (rcv=='1') 
    {
      //digitalWrite(LEDPin,HIGH);
      Serial.println("on");
    }
    else if (rcv=='0') 
    {
      //digitalWrite(LEDPin,LOW);
      Serial.println("off");
    }
  }  
}



int RcvPkt() 
{
    // 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(&rcv,1);
    Serial.println("Contents:");
    Serial.println(rcv);
  }
  return packetSize;
}

What are you seeing on the receiver's serial monitor? Any "Received packet of size " message?

On the sender, add this code. The reference does not show a return value, but endPacket() returns 1 on success and 0 on error. A return value of 1 in this case would indicate the receiver got the packet, but this applies only to localnet UDP traffic. If the receiver is not on that localnet, a return value of 1 indicates the gateway (router) took the packet, but does not indicate the destination received it.

    // replace this line
    Udp.endPacket();

    // with these
    if(Udp.endPacket() == 1) Serial.println("send ok");
    else Serial.println("send failed");

That is strange,

Just by adding that line, it sends AND receives...

Why would the difference be? I don't understand? Udp.endPacket(); should do the same as if(Udp.endPacket() == 1) Serial.println("send ok");

I don't understand, but thank you!

Sometimes it takes a while for the duplicate mac addresses to get straightened out. It shouldn't have been adding those lines that corrected anything.

I'm happy to hear it is working for you.

Thanks! It could be the mac address indeed although I noticed something else weird...

I was powering my second Arduino from a 5v supply. Adding and swapping those lines and by disconnecting and reconnecting the arduino's I noticed a little charge on the ground of the USB ports. I now unplugged the 5v power supply and all seems to be working fine... Could it be some grounding problem as well? Or a combination of both?

Anyways got it working! Thank you for your time...

kind regards.

Don't power the Arduinos on the 5v pin. It is not recommended.

5V.This pin outputs a regulated 5V from the regulator on the board. The board can be supplied with power either from the DC power jack (7 - 12V), the USB connector (5V), or the VIN pin of the board (7-12V). Supplying voltage via the 5V or 3.3V pins bypasses the regulator, and can damage your board. We don't advise it.

edit: I do occasionally power my Arduino Mega 2560 using a USB phone charger/power supply. That seems to work ok. Insure the charger supplies enough current and the correct voltage.

I had only a 5v power supply, I should get myself a 9v one.

I plugged it into the DC power jack. I always figured, to low a voltage would hurt no one :blush:
I guess now I know why it is not recommended. I power it via a usb power supply and everything works like a charm…

Thanks, Tim!