How do I get an Arduino to initiate a UDP session? SOLVED

I've been playing with UDP and all of the examples I have found "answer" a UDP session. That is, the remoteIP() info is obtained after some other computer has sent a UDP packet to my Arduino. The NTP sketch is the closest I have found to something where the Arduino starts the UDP. The trouble with that sketch is it makes a call using a NTP based command called "sendNTPpacket(timeServer);".

I need something similar where I can start a UDP send to an IP I specify. The "receive" examples use this line:

Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());

where remoteIP() and remotePort() are received from the other computer.

Is there an easy way for me to use the same command to start a UDP send where I specify remoteIP() and remotePort()?

mfriesen:
I've been playing with UDP and all of the examples I have found "answer" a UDP session. That is, the remoteIP() info is obtained after some other computer has sent a UDP packet to my Arduino. The NTP sketch is the closest I have found to something where the Arduino starts the UDP. The trouble with that sketch is it makes a call using a NTP based command called "sendNTPpacket(timeServer);".

I need something similar where I can start a UDP send to an IP I specify. The "receive" examples use this line:

Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());

where remoteIP() and remotePort() are received from the other computer.

Is there an easy way for me to use the same command to start a UDP send where I specify remoteIP() and remotePort()?

Have a look at the example code for the UDPSendReceive function - this is well commented and explains most of what you need to know - it also includes a processing sketch at the end of the code to let you test it

Craig

There is no such thing as a UDP “session”. UDP are just raw packets of data that get sent around. The whole concept of the “session” is purely down to the user and their application, and the protocol they encapsulate within the UDP packets.

Sending a UDP packet and replying to a UDP packet are one and the same. You just send a UDP packet. The only difference is the reason you send the packet. When replying you send a packet because you got a packet. When sending you send a packet because someone pressed a button (for example).

majenko:
There is no such thing as a UDP "session".

On the network side, that's true. But on the API side some of the semantics of a session do apply, for example in Posix you can bind a datagram socket to an address. While it doesn't establish a transport connection, it establishes a state within the client that has a similar effect at the API level.

I'm aware with UDP there isn't a connection that's why I used the word session. It's a session to me and my communication with the other end. I didn't know any other way of referring to the process. Anyway, I have experimented with the Send Receive example and pretty well anything else I can find including some looking at a Youtube from 2009 :

He posted 2 Arduinos connected together via Ethernet. This is basically what I want to do. His code is pre any official support from the Arduino libraries re UDP. He wrote his own called Library called ClientUDP_1.1, but I can't get the code to download from his blog link.

In the UDPSendReceiveString Arduino example, the initial SEND comes from the processing sketch, (which I can’t get to work either, but that’s another story..). I managed to send and receive UDP to my Arduino with my Linux box using SOCAT. I can confirm my Arduino code works with UDP.

What I want to do is start the “session” from one Arduino to another. The SendReceive example only sends a UDP packet after it has determined the RemoteIP() and RemotePort() from the Processing (or any other UDP initiated session).

How do I manually load the RemoteIP() bytes into these UDP send statements:

Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
Udp.write(ReplyBuffer);
Udp.endPacket();

Thanks

OK I figured it out myself.

I made an array called SendTo and populated it with my ‘receive’ Arduino’s ip:

byte SendTo = {10, 1, 0, 222};

And then used these lines in a void Send() routine:

Udp.beginPacket(SendTo, 8888);
Udp.write(“L1,23,45”);
Udp.endPacket();

Where 8888 is the receive Arduino’s Listen Port.

If anybody else is stuck on this I hope it helps.

Udp.write("L1,23,45");

In case anyone is wondering, the L1,23,45 is my data I wanted to send to the other Arduino. I should have pasted the lines in with a more generic field like "your data here".

Cheers

mfriesen:

Udp.write("L1,23,45");

In case anyone is wondering, the L1,23,45 is my data I wanted to send to the other Arduino. I should have pasted the lines in with a more generic field like "your data here".

Cheers

Please post your sketch up and change the title of the thread to SOLVED so that others can benefit in the future

Craig

Please post your sketch up and change the title of the thread to SOLVED so that others can benefit in the future

Craig. I changed the name, but as to posting my code it's still way too much of a work in progress.

What I'm working on is a network based countdown Timer. At first I worked with the display end where I used a network connected Uno to receive Telnet commands to generate RS422 like TimeCode. This timecode is then fed into a professionally made Time Display. The project then progressed to UDP and now to having a dedicated Uno based Controller that sends via UDP such things as time load, start, stop Up and DownCount commands. The 2 Unos work together to initiate the timer sequence, but once running each run independent. It's almost working.

mfriesen:

Please post your sketch up and change the title of the thread to SOLVED so that others can benefit in the future

Craig. I changed the name, but as to posting my code it's still way too much of a work in progress.

What I'm working on is a network based countdown Timer. At first I worked with the display end where I used a network connected Uno to receive Telnet commands to generate RS422 like TimeCode. This timecode is then fed into a professionally made Time Display. The project then progressed to UDP and now to having a dedicated Uno based Controller that sends via UDP such things as time load, start, stop Up and DownCount commands. The 2 Unos work together to initiate the timer sequence, but once running each run independent. It's almost working.

OK good one - sounds like a good project - when you get it happening post it up in the Exhibition area

Craig

Combined client/server code that might be of interest.

//zoomkat 7-03-12, combined client and server
//simple button GET with iframe code
//for use with IDE 1.0
//open serial monitor and send an g to test client and
//see what the arduino client/server receives
//web page buttons make pins high/low
//use the ' in html instead of " to prevent having to escape the "
//address will look like http://192.168.1.102:84 when submited
//for use with W5100 based ethernet shields
//note that the below bug fix may be required
// http://code.google.com/p/arduino/issues/detail?id=605

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

byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //assign arduino mac address
byte ip[] = {192, 168, 1, 102 }; // ip in lan assigned to arduino
byte gateway[] = {192, 168, 1, 1 }; // internet access via router
byte subnet[] = {255, 255, 255, 0 }; //subnet mask
EthernetServer server(84); //server port arduino server will use
EthernetClient client;
char serverName[] = "web.comporium.net"; // (DNS) zoomkat's test web page server
//byte serverName[] = { 208, 104, 2, 86 }; // (IP) zoomkat web page server IP address

String readString; //used by server to capture GET request 

//////////////////////

void setup(){

  pinMode(5, OUTPUT); //pin selected to control
  pinMode(6, OUTPUT); //pin selected to control
  pinMode(7, OUTPUT); //pin selected to control
  pinMode(8, OUTPUT); //pin selected to control

  //pinMode(5, OUTPUT); //pin 5 selected to control
  Ethernet.begin(mac,ip,gateway,gateway,subnet); 
  server.begin();
  Serial.begin(9600); 
  Serial.println("server/client 1.0 test 7/03/12"); // keep track of what is loaded
  Serial.println("Send an g in serial monitor to test client"); // what to do to test client
}

void loop(){
  // check for serial input
  if (Serial.available() > 0) 
  {
    byte inChar;
    inChar = Serial.read();
    if(inChar == 'g')
    {
      sendGET(); // call client sendGET function
    }
  }  

  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();

        //read char by char HTTP request
        if (readString.length() < 100) {

          //store characters to string 
          readString += c; 
          //Serial.print(c);
        } 

        //if HTTP request has ended
        if (c == '\n') {

          ///////////////
          Serial.print(readString); //print to serial monitor for debuging 

            //now output HTML data header
          if(readString.indexOf('?') >=0) { //don't send new page
            client.println(F("HTTP/1.1 204 Zoomkat"));
            client.println();
            client.println();  
          }
          else {   
            client.println(F("HTTP/1.1 200 OK")); //send new page on browser request
            client.println(F("Content-Type: text/html"));
            client.println();

            client.println(F("<HTML>"));
            client.println(F("<HEAD>"));
            client.println(F("<TITLE>Arduino GET test page</TITLE>"));
            client.println(F("</HEAD>"));
            client.println(F("<BODY>"));

            client.println(F("<H1>Zoomkat's simple Arduino 1.0 button</H1>"));

            // DIY buttons
            client.println(F("Pin5"));
            client.println(F("<a href=/?on2 target=inlineframe>ON</a>")); 
            client.println(F("<a href=/?off3 target=inlineframe>OFF</a>

")); 

            client.println(F("Pin6"));
            client.println(F("<a href=/?on4 target=inlineframe>ON</a>")); 
            client.println(F("<a href=/?off5 target=inlineframe>OFF</a>

")); 

            client.println(F("Pin7"));
            client.println(F("<a href=/?on6 target=inlineframe>ON</a>")); 
            client.println(F("<a href=/?off7 target=inlineframe>OFF</a>

")); 

            client.println(F("Pin8"));
            client.println(F("<a href=/?on8 target=inlineframe>ON</a>")); 
            client.println(F("<a href=/?off9 target=inlineframe>OFF</a>

")); 

            client.println(F("Pins"));
            client.println(F("&nbsp;<a href=/?off2468 target=inlineframe>ALL ON</a>")); 
            client.println(F("&nbsp;<a href=/?off3579 target=inlineframe>ALL OFF</a>")); 

            client.println(F("<IFRAME name=inlineframe style='display:none'>"));          
            client.println(F("</IFRAME>"));

            client.println(F("</BODY>"));
            client.println(F("</HTML>"));
          }

          delay(1);
          //stopping client
          client.stop();

          ///////////////////// control arduino pin
          if(readString.indexOf('2') >0)//checks for 2
          {
            digitalWrite(5, HIGH);    // set pin 5 high
            Serial.println("Led 5 On");
            Serial.println();
          }
          if(readString.indexOf('3') >0)//checks for 3
          {
            digitalWrite(5, LOW);    // set pin 5 low
            Serial.println("Led 5 Off");
            Serial.println();
          }
          if(readString.indexOf('4') >0)//checks for 4
          {
            digitalWrite(6, HIGH);    // set pin 6 high
            Serial.println("Led 6 On");
            Serial.println();
          }
          if(readString.indexOf('5') >0)//checks for 5
          {
            digitalWrite(6, LOW);    // set pin 6 low
            Serial.println("Led 6 Off");
            Serial.println();
          }
          if(readString.indexOf('6') >0)//checks for 6
          {
            digitalWrite(7, HIGH);    // set pin 7 high
            Serial.println("Led 7 On");
            Serial.println();
          }
          if(readString.indexOf('7') >0)//checks for 7
          {
            digitalWrite(7, LOW);    // set pin 7 low
            Serial.println("Led 7 Off");
            Serial.println();
          }     
          if(readString.indexOf('8') >0)//checks for 8
          {
            digitalWrite(8, HIGH);    // set pin 8 high
            Serial.println("Led 8 On");
            Serial.println();
          }
          if(readString.indexOf('9') >0)//checks for 9
          {
            digitalWrite(8, LOW);    // set pin 8 low
            Serial.println("Led 8 Off");
            Serial.println();
          }         

          //clearing string for next read
          readString="";

        }
      }
    }
  }
} 

//////////////////////////
void sendGET() //client function to send and receive GET data from external server.
{
  if (client.connect(serverName, 80)) {
    Serial.println("connected");
    client.println("GET /~shb/arduino.txt HTTP/1.0");
    client.println();
  } 
  else {
    Serial.println("connection failed");
    Serial.println();
  }

  while(client.connected() && !client.available()) delay(1); //waits for data
  while (client.connected() || client.available()) { //connected or data available
    char c = client.read();
    Serial.print(c);
  }

  Serial.println();
  Serial.println("disconnecting.");
  Serial.println("==================");
  Serial.println();
  client.stop();

}