WiFi UDP Send and Receive String Library Bug (need guidance)

Are you certain your processing program is sending the packet?

I have two arduino's. The first "A1" (arduino1) is connected to the Ethernet shield, and the other is connected to the Wi-Fi Shield. At all times the processing app is up. When you clicked on the processing box and hit enter it sends the packets.

When I upload the Ethernet code to the A1 and click on the processing box and hit enter A1 prints "Hello World".

When I upload the WiFi code into A2 The Serial monitor goes through the Connection process and connects successfully to the Internet. The last thing that happens is it prints

Serial.println("\nStarting connection to server...");

After that, nothing else happens, Even when I click on the processing app box and hit buttons. To my understanding, there is no reason the processing app wouldn't send the packets.

Then to make sure, I switched back to A1 and pressed enter and A1 worked. I just can't figure out why it isn't working.

I have the wifi shields send and receive like the WifiUdpNtpClient code. The processing is the "server".

That is actually what I am trying to do. I don't want to use the processing app, but it seemed like the only way to get a feel for how the communication process works. The WiFiUdpNtp program is only half of the code. They don't provide the code from the Ntp side, and Youtube doesn't have any examples using Wi-Fi, (plenty using Xbee but none using WiFi).

I was able to mimic the Server example code, but it requires to click on the app buttons for changes to be made. I was able to make it so when buttons are pressed on the A1 or A2 the Server will see the changes, and the app will adjust, but I couldn't figure out how to make that send a signal to the other Arduino without clicking a button on the app. The (Get / ) only changes when a button is pressed. I couldn't figure out how to by-pass that.

Is it possible to make a change in state do something like = (currentLine.endsWith("GET /H") so that the http://192.168.1.176/H changes automatically? I found this link, http://www.htmlcodetutorial.com/linking/_A_HREF.html which is very handy, but have not yet found a way to do this without physically clicking on a reference to hyperlink.

Are you certain the wifi card is at 192.168.1.177? I don't see where you call WiFi.config(ip) before you connect to the wireless router. If you don't, the dhcp server sets the ip on the wifi shield. http://arduino.cc/en/Reference/WiFiConfig

I don’t see where you call WiFi.config(ip) before you connect to the wireless router.

Out of every WiFi library example that I have successfully used and attempted to modify, (SimpleWebServerWiFi, WiFiUdpNepClient, WiFiWebCliet, WiFiWebServer, and a few other examples that I found on YouTube) not one used this

WiFi.config(ip);

function.

I was under the impression IPAddress ip(192, 168, 1, 177); told it which ip address to use, otherwise it would use the default IPAddress ip = WiFi.localIP();

By typing in WiFi.config(ip); into the void setup() section that fixed the immediate issue that had me stuck in stalemate. I will now continue to try to reverse engineer this processing to arduino communication, and will hopefully have the two arduinos talking to each other wirelessly through WiFi within the next few days. I will post the final code when I figure it out.

Tim, I’m a man of my word. Send me a private message and let me know where to mail the check, or a ebay/amazon account and I will get that to you (sorry I don’t know anything about bitcoins…yet)

If anyone knows how to get a server to communicate and control an arduino without requiring a user to physically click on a reference to hyperlink (one arduinos actions control another arduino) please share.

If anyone knows how to get a server to communicate and control an arduino without requiring a user to physically click on a reference to hyperlink (one arduinos actions control another arduino) please share.

Generally servers do not initiate communication to other servers. Clients usually initiate communication to servers. That being said, an arduino with an ethernet shield can run combined client/server code where the server waits for incoming request, while the client will make a client request to another server upon some event.

I was under the impression IPAddress ip(192, 168, 1, 177); told it which ip address to use, otherwise it would use the default IPAddress ip = WiFi.localIP();

No. If you do not call WiFi.config(ip), the wifi shield uses the IP received from the dhcp server. The WiFi.localIP() function will return the IP the wifi shield is using, no matter how it gets the IP.

edit: Donate the money to a local charity to feed the less fortunate during the upcoming holidays. That would be good with me. :)

Clients usually initiate communication to servers.

As suggest i attempted to modify the client code that came in the library to make the two arduinos talk to each other over WiFi. I ran into a few problems. I don’t understand why it keeps saying “connection failed” when I press the button. I know this means it can’t connect to the host, but I have the host up and running using the Aurdion2. I even have the webpage pulled up that shows it is working (the code for the webserver is the exact code from the SimpleWebServerWiFi example with the needed modifications to get it to connect to my network, and the WiFi.config(ip); function added into the setup loop.), but the client isn’t connecting to it for some reason. There might be other issues that I don’t yet comprehend enough understanding about to ask.

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

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

IPAddress server(192,168,1,177);  

IPAddress ip(192,168,1,177);

EthernetClient client;
// EthernetServer server(80); // ------------  comment 1
/*--------------------if I enabled this, it says--------------------------------
"conflicting declaration "EthernetServer server'
'server' has a previous declaration as 'IPAddress server'                                          
*/
void setup() {

  pinMode(2,INPUT);   // button 1 (led on)
  pinMode(3,INPUT);   // button 2 (led off)
  pinMode(4,OUTPUT);  // led
  Serial.begin(9600);

  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");

    Ethernet.begin(mac, ip);
  }

  delay(1000);
  Serial.println("connecting...");

}
// server.begin(); // needs to enable server in comment 1
 
void loop()
{
  /*========================= Button 1 Pressed =================== 
    ============================ Led comes on ==================== 
    =========================== GET ends with H ==================
    ======== without pressing a reference to hyperlink =========== 
  */
  if (digitalRead(2) == HIGH)
  {  digitalWrite(4,HIGH);
     Serial.println("led should be on");
     if ( client.connect(server, 80) ) 
     { Serial.println("connected");
        // Make a HTTP request:
        client.println("GET /H");
        client.println("Host: (ip)"); // -----------experiment 1---------------- unsure about this
        client.println("Connection: close");
        client.println();
     } else { // if you didn't get a connection to the server:
              Serial.println("connection failed");
            }
            
  }
   /*========================= Button 1 Pressed =================== 
    ============================ Led comes on ==================== 
    =========================== GET ends with H ==================
    ======== without pressing a reference to hyperlink =========== 
  */      
   if (digitalRead(3) == HIGH)
    {  digitalWrite(4,LOW);
    Serial.println("led off");
       if ( client.connect(server, 80) ) 
       { Serial.println("connected");
          // Make a HTTP request:
          client.println("GET /H");
          client.println("Host: 192,168,1,177"); // ------experiment 2------------------ unsure about this
          client.println("Connection: close");
          client.println();
       } else { // if you didn't get a connection to the server:
                Serial.println("connection failed");
              }  
             
    }
    
      /*========================= If below is enabled =================== 
    ======================== it gets caught in a loop ==================== 
    =================== resulting in led never coming on =================
    ============= and serial never prints (led should be on ============== 
  /*  
  // if there are incoming bytes available 
  // from the server, read them and print them:
  if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }

  // if the server's disconnected, stop the client:
  if (!client.connected()) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();

    // do nothing forevermore:
    while(true);
  }
  */
}

Donate the money to a local charity to feed the less fortunate during the upcoming holidays. That would be good with me.

My sister Lane Riley, actually started this mission a year ago. http://www.deltahandsforhope.org/blog/ In a small town in Mississippi (known as the poorest city in America, which before she told me this I thought was Detroit) to provide food and educational resources to the children. I found it interesting that you specifically asked to give it to an organization to help feed children. I will give her the money in an envelope labeled “from Tim for the underprivileged children”. Or if you prefer I will give it to a local church. Let me know which you would prefer.

This is what I prefer:

I will give her the money in an envelope labeled "from Tim for the underprivileged children".

The Arduino cannot be both the client and the server in this scenario. It can handle only one of these tasks at a time.

IPAddress server(192,168,1,177);  

IPAddress ip(192,168,1,177);

This is what I prefer:

She comes home today for Thanksgiving. It will be done.

The Arduino cannot be both the client and the server in this scenario. It can handle only one of these tasks at a time.

I’m very confused now.

ethernet shield can run combined client/server

So what is the difference in

IPAddress server(192,168,1,177);

IPAddress ip(192,168,1,177);

and how the Ethernet version of WebClient code is written (which I have successfully tested)

IPAddress server(74,125,232,128); // numeric IP for Google (no DNS)
//char server = “www.google.com”; // name address for Google (using DNS)

// Set the static IP address to use if the DHCP fails to assign
IPAddress ip(192,168,1,177);

Experiment 1: I eliminated

IPAddress ip(192,168,1,177);

and made the following changes to account for the changes:

Ethernet.begin(mac, ip); change to Ethernet.begin(mac, server);
client.println(“Host: (ip)”); // ------------ to client.println(“Host: (server)”); // ------------
===========================results==================================
No apparent difference.

Experiment 2: I eliminated

IPAddress server(192,168,1,177);

and made the following changes to account for the changes:

if (client.connect(server, 80)) changed to if (client.connect(ip, 80))
client.println(“Host: (ip)”); // ---------- changed to client.println(“Host: (server)”); // ----------
===========================results==================================
No apparent difference.

Experiment 3: I think this is closer to the right track so i posted the updated code below for easier understanding. I changed IPAddress ip(192,168,1,177); to IPAddress ip(192,168,1,174); so it they would have two separate addressed. The arduino2 with WiFi shield is still running the SimpleWiFiWebServer code and I have the address up on my screen to confirm. However, the client still isn’t connecting to it.

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

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

IPAddress server(192,168,1,177);  

IPAddress ip(192,168,1,174);

EthernetClient client;
// EthernetServer server(80); // ------------  comment 1
/*--------------------if I enabled this, it says--------------------------------
"conflicting declaration "EthernetServer server'
'server' has a previous declaration as 'IPAddress server'                                          
*/
void setup() {

  pinMode(2,INPUT);   // button 1 (led on)
  pinMode(3,INPUT);   // button 2 (led off)
  pinMode(4,OUTPUT);  // led
  Serial.begin(9600);

  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");

    Ethernet.begin(mac, ip);
  }

  delay(1000);
  Serial.println("connecting...");

}
// server.begin(); // needs to enable server in comment 1
 
void loop()
{
  /*========================= Button 1 Pressed =================== 
    ============================ Led comes on ==================== 
    =========================== GET ends with H ==================
    ======== without pressing a reference to hyperlink =========== 
  */
  if (digitalRead(2) == HIGH)
  {  digitalWrite(4,HIGH);
     Serial.println("led should be on");
     if ( client.connect(server, 80) ) 
     { Serial.println("connected");
        // Make a HTTP request:
        client.println("GET /H");
        client.println("Host: (ip)"); // -----------experiment 1---------------- unsure about this
        client.println("Connection: close");
        client.println();
     } else { // if you didn't get a connection to the server:
              Serial.println("connection failed");
            }
            
  }
   /*========================= Button 1 Pressed =================== 
    ============================ Led comes on ==================== 
    =========================== GET ends with H ==================
    ======== without pressing a reference to hyperlink =========== 
  */      
   if (digitalRead(3) == HIGH)
    {  digitalWrite(4,LOW);
    Serial.println("led off");
       if ( client.connect(server, 80) ) 
       { Serial.println("connected");
          // Make a HTTP request:
          client.println("GET /H");
          client.println("Host: 192,168,1,177"); // ------experiment 2------------------ unsure about this
          client.println("Connection: close");
          client.println();
       } else { // if you didn't get a connection to the server:
                Serial.println("connection failed");
              }  
             
    }
    
      /*========================= If below is enabled =================== 
    ======================== it gets caught in a loop ==================== 
    =================== resulting in led never coming on =================
    ============= and serial never prints (led should be on ============== 
  /*  
  // if there are incoming bytes available 
  // from the server, read them and print them:
  if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }

  // if the server's disconnected, stop the client:
  if (!client.connected()) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();

    // do nothing forevermore:
    while(true);
  }
  */
}

The ethernet shield can run combined client/server, just not a connection to itself as both the client and server in one connection. I'm not sure that even a bit of "socket trickery" can handle that. I've never tried it.

The difference is the example you posted are identical IP addresses. The WebClient example (not WebServer) is not the same IP. The IPs are different for the client (192.168.1.177) and the Google server (74.125.232.128).

If you have two devices on a localnet with the same IP, you have a routing problem. All IPs and mac addresses must be unique on a localnet.

The IPs are different for the client (192.168.1.177) and the Google server (74.125.232.128).

Yes, but didn’t I address that in experiment 3?

Experiment 3: I think this is closer to the right track so i posted the updated code below for easier understanding. I changed IPAddress ip(192,168,1,177); to IPAddress ip(192,168,1,174); so it they would have two separate addressed. The arduino2 with WiFi shield is still running the SimpleWiFiWebServer code and I have the address up on my screen to confirm. However, the client still isn’t connecting to it.

I changed the addresses so they wouldn’t match in that experiment.

IPAddress server(192,168,1,177);

IPAddress ip(192,168,1,174);

The server address is still the same address as the server (WiFi arduino1 running on the SimpleWiFiWebServer program)… don’t they need to be if they are to talk to each other?

Wait… are you saying that I can’t have a client talk to a server if they are both on the same router (localnet)?, If so, do I need to create a static Ip address to get around that?

If you have two devices on a localnet with the same IP, you have a routing problem.

No, what I am saying is you can't have two identical IPs on the same localnet. I have client and server devices on my localnet, and they do fine, but I know the limits of the protocols.

As long as one device is assigned 192.168.1.177 and the other device is assigned 192.168.1.174, you are ok. Those are different IP addresses.

Something still isn’t quite right. I added a 1 second delay to slow things down

if (digitalRead(2) == HIGH)
{ digitalWrite(4,HIGH);
delay(1000);

anyway, What I got from the serial printer of the client is

connecting...
led should be on 
connected
led should be on
connection failed
HTTP/1.1 200 OK
Content-type:text/html
Click <a href=\"/H\">here</a> turn the LED on pin 9 on
led should be on
connection failed
led off
confection failed

and then I continued to press buttons and kept getting the same results “connection failed”. The good news is

HTTP/1.1 200 OK
Content-type:text/html
Click <a href="/H">here turn the LED on pin 9 on

was not code in the client program. It came from the Server program, so for a second they talked to each other. But the Server never changed, and it didn’t happen again after that.

I did notice if i click the reference to hyperlink in the webpage that displays the Server program while I’m pressing a button on Arduino2 (Client program) it freezes Arduino1 (Server) and I have to restart it for it to respond. I think I successfully just executed my first (and hopefully last) denial of service attack on myself when I did that.

But still… why is the client program not commanding the Server program? Why did the client program only receive connection to the Server program for a second? I am missing something… But I don’t know what to look for.

Updated debugging notes:

I’ve been doing all kinds of reverse engineering. I have the following notes written that may be of help figuring out where the problem is.

I updated the code a little. Now the light will come on when the client calls it. But then everything shuts down.

When looking at the serial monitor of the Server it will go through the connection process. Then if I pull up the ip address it will pull it up and I can click on the two hyperlinks to make the light come on or off. If I click on the button on the Server it will say either GET /H or GET /H depending on which button I press. The it will say Host:192.168.1.177 then it will say Connection: close then a blank line then client disonnected

After this happens the Sever freezes and if you click on one of the hyperlinks the circle thing that shows it’s refreshing just keeps going around and around. Like it’s loading, but never gets there.

Looking from the client serial monitor it will say connecting… and nothing else until I press a button. When i press button one it will say
led should be on
connected
HTTP/1.1 200 OK
Content-type:text/html
Connection:close

Click <href="/H">hereturn the led on pin 9 on
Click <href="/L">hereturn the led on pin 4 off

Then if i press another button it will say

led off
connection failed

The only way to get the Server to respond is to restart the Arduino1 (Server)
But the really interesting this is, if I leave the Serial Monitor up for the Client and restart only the Server, the Server will work fine as far as controling it through the hyperlink options, but pressing a button on the Client won’t make it do anything. The client will just Serial Print connection failed, but the Server is never effected, until I restart the Client as well.

I feel like i need to put a client stop, or restart in somewhere in the client code to tell it to stop once the mission is complete. But Everything I try, nothing seems to work. Will someone please help?
This is the code for the Client program. The Server program is from the SimpleWebServerWiFi library with the added WiFi.config(ip); function in setup.

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

// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };


IPAddress server(192,168,1,177);


// Set the static IP address to use if the DHCP fails to assign
IPAddress ip(192,168,1,174);

// Initialize the Ethernet client library
// with the IP address and port of the server 
// that you want to connect to (port 80 is default for HTTP):
EthernetClient client;

void setup() {
    pinMode(2,INPUT);   // button 1 (led on)
  pinMode(3,INPUT);   // button 2 (led off)
  pinMode(4,OUTPUT);  // led
  Serial.begin(9600);
  
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

  // start the Ethernet connection:
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    // try to congifure using IP address instead of DHCP:
    //Ethernet.begin(mac, ip);
  }
  // give the Ethernet shield a second to initialize:
  delay(1000);
  Serial.println("connecting...");

  // if you get a connection, report back via serial:
  
}

void loop()
{
  /*========================= Button 1 Pressed =================== 
    ============================ Led comes on ==================== 
    =========================== GET ends with H ==================
    ======== without pressing a reference to hyperlink =========== 
  */
  if (digitalRead(2) == HIGH)
  {  digitalWrite(4,HIGH);
  delay(1000);
     Serial.println("led should be on");
     if ( client.connect(server, 80) ) 
     { Serial.println("connected");
        // Make a HTTP request:
        client.println("GET /H");
        client.println("Host: 192.168.1.177"); 
        client.println("Connection: close");
        client.println();
     } else { // if you didn't get a connection to the server:
              Serial.println("connection failed");
            }
            
  }
   /*========================= Button 1 Pressed =================== 
    ============================ Led comes on ==================== 
    =========================== GET ends with H ==================
    ======== without pressing a reference to hyperlink =========== 
  */      
   if (digitalRead(3) == HIGH)
    {  digitalWrite(4,LOW);
    delay(1000);
    Serial.println("led off");
       if ( client.connect(server, 80) ) 
       { Serial.println("connected");
          // Make a HTTP request:
          client.println("GET /L");
          client.println("Host: 192.168.1.177");
          client.println("Connection: close");
          client.println();
       } else { // if you didn't get a connection to the server:
                Serial.println("connection failed");
              }  
             
    }





  // if there are incoming bytes available 
  // from the server, read them and print them:
  if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }


   /*========================= if below is active =================== 
    =========================== freezes everything ==================== 
  */ 

/*
  // if the server's disconnected, stop the client:
  if (!client.connected()) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();

    // do nothing forevermore:
    while(true);
  }
  */
}

I figured out where to put the client.stop(); This was a little tricky. I posted the offical working client code below.

include <SPI.h>
#include <Ethernet.h>
boolean RunForTheHills = 0;
boolean OnlyOnce = 0;
boolean Internet = 0;
// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
// if you don't want to use DNS (and reduce your sketch size)
// use the numeric IP instead of the name for the server:
IPAddress server(192,168,1,177);  

// Set the static IP address to use if the DHCP fails to assign
IPAddress ip(192,168,1,174);

// Initialize the Ethernet client library
// with the IP address and port of the server 
// that you want to connect to (port 80 is default for HTTP):
EthernetClient client;

void setup() {
    pinMode(2,INPUT);   // button 1 (led on)
  pinMode(3,INPUT);   // button 2 (led off)
  pinMode(4,OUTPUT);  // led
  Serial.begin(9600);
  
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

  // start the Ethernet connection:
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    // try to congifure using IP address instead of DHCP:
    //Ethernet.begin(mac, ip);
  }
  // give the Ethernet shield a second to initialize:
  delay(1000);
  Serial.println("connecting...");

  // if you get a connection, report back via serial:
  
}

void loop()
{
  /*========================= Button 1 Pressed =================== 
    ============================ Led comes on ==================== 
    =========================== GET ends with H ==================
    ======== without pressing a reference to hyperlink =========== 
  */
  if (digitalRead(2) == HIGH)
  { RunForTheHills = HIGH; }
 

   /*========================= Button 1 Pressed =================== 
    ============================ Led comes on ==================== 
    =========================== GET ends with H ==================
    ======== without pressing a reference to hyperlink =========== 
  */      
   if (digitalRead(3) == HIGH)
   {  RunForTheHills = LOW; }
   
//---------------------------------------------------------------------

  if (RunForTheHills == HIGH)
  { if (OnlyOnce == LOW)
    { digitalWrite(4,HIGH);
      //delay(1000);
      Serial.println("");
      Serial.println("led should be on");
      Serial.println("--------------------------------");
      if ( client.connect(server, 80) ) 
      { Serial.println("connected");
        // Make a HTTP request:
        client.println("GET /H");
        client.println("Host: 192.168.1.177");
        client.println("Connection: close");
        client.println();
      } else { // if you didn't get a connection to the server:
               Serial.println("connection failed");
             }
          Internet = HIGH;
          OnlyOnce = HIGH;
    }      
  }
  
  
    if (RunForTheHills == LOW)
    { if (OnlyOnce == HIGH)
      { digitalWrite(4,LOW);
        Serial.println("");
        //delay(1000);
        Serial.println("led off");
        Serial.println("---------------------------");
       if ( client.connect(server, 80) ) 
       { Serial.println("");
         Serial.println("connected");
          // Make a HTTP request:
          client.println("GET /L");
          delay(1);
          client.println("Host: 192.168.1.177"); 
          client.println("Connection: close");
          client.println();
         // client.stop();
       } else { // if you didn't get a connection to the server:
                Serial.println("connection failed");
              }  
             Internet = HIGH;
             OnlyOnce = LOW;
    }
    }
    
      while (client.available()) 
      { char c = client.read();
        Serial.write(c);
       // if (c == '\r') 
        //{ client.stop(); }
      }

  if (Internet == HIGH)
  {
  // if the server's disconnected, stop the client:
  if (!client.connected()) {
    Internet = LOW;
    //Serial.println();
    Serial.println("disconnecting.");
    client.stop();
  }
  }
  }

Now I need to figure out how to combine this with the server code. That way Arduino1 can be the server, and the client, and arduino2 can be the client as well… Do I have that right? The results I want are if button 1 is pressed on arduino1 led on arduino1 and arduino 2 come on. and vise verse so if the button on arduino 2 is pressed, the led on arduino 1 and arduino is turned on/off using a WiFi connection.

I’m confused about how to do this though.

in the SimpleWebServerWiFi code would I change

WiFiClient client = server.available();

to WiFiClient client = (server.available(); || 192,168,1,174)? That way it can talk to itself, or know if a change in hyperlink is made? This is blowing my mind right now.

Or would I need both arduinos to be servers, and clients of each other for that?

The below is for the w5100 ethernet shield and not wifi, but you might be able to modify the code for wifi. Note that an IP address is only assigned to the server function.

//zoomkat 10-02-14, combined client and server
//simple button GET with iframe code
//for use with IDE 1.0
//open serial monitor and send a g to test client GET 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

#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[] = "checkip.dyndns.com"; // (DNS) dyndns 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(F("server/client 1.0 test 9/02/14")); // keep track of what is loaded
  Serial.println(F("Send a 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(F("Led 5 On"));
            Serial.println();
          }
          if(readString.indexOf('3') >0)//checks for 3
          {
            digitalWrite(5, LOW);    // set pin 5 low
            Serial.println(F("Led 5 Off"));
            Serial.println();
          }
          if(readString.indexOf('4') >0)//checks for 4
          {
            digitalWrite(6, HIGH);    // set pin 6 high
            Serial.println(F("Led 6 On"));
            Serial.println();
          }
          if(readString.indexOf('5') >0)//checks for 5
          {
            digitalWrite(6, LOW);    // set pin 6 low
            Serial.println(F("Led 6 Off"));
            Serial.println();
          }
          if(readString.indexOf('6') >0)//checks for 6
          {
            digitalWrite(7, HIGH);    // set pin 7 high
            Serial.println(F("Led 7 On"));
            Serial.println();
          }
          if(readString.indexOf('7') >0)//checks for 7
          {
            digitalWrite(7, LOW);    // set pin 7 low
            Serial.println(F("Led 7 Off"));
            Serial.println();
          }     
          if(readString.indexOf('8') >0)//checks for 8
          {
            digitalWrite(8, HIGH);    // set pin 8 high
            Serial.println(F("Led 8 On"));
            Serial.println();
          }
          if(readString.indexOf('9') >0)//checks for 9
          {
            digitalWrite(8, LOW);    // set pin 8 low
            Serial.println(F("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(F("connected"));
    client.println(F("GET / HTTP/1.1"));
    client.println(F("Host: checkip.dyndns.com"));
    client.println(F("Connection: close"));
    client.println();
  } 
  else {
    Serial.println(F("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(); //gets byte from ethernet buffer
    readString += c; //places captured byte in readString
  }

  //Serial.println();
  client.stop(); //stop client
  Serial.println(F("client disconnected."));
  Serial.println(F("Data from server captured in readString:"));
  Serial.println();
  Serial.print(readString); //prints readString to serial monitor 
  Serial.println();
  Serial.println(F("End of readString"));
  Serial.println(F("=================="));
  Serial.println();
  readString=""; //clear readString variable

}

This is working perfectly, and surprisingly it seems to be alot faster than (loading/refresh wise) its almost instantly which is awesome! I’m trying to understand it.

if(readString.indexOf(’?’) >=0) { //don’t send new page
client.println(F(“HTTP/1.1 204 Zoomkat”));

I don’t understand the 204 Zoomkat - I understand the standard 200 OK but this is throwing me off. It would probably be clearer if I understood readString.indexOf(’’)

///////////////////// control arduino pin
if(readString.indexOf(‘2’) >0)//checks for 2

Where does indexOf come from? In the previous code I have experimented with this was always if (currentLine.endsWith(“GET / whatever”

I see the 2 matches client.println(F(“ON”));

But why would it automatically skip the (?on or ?off) that comes before the number?

I don't understand the 204 Zoomkat - I understand the standard 200 OK but this is throwing me off.

status: 204 is the "no content" http code that tells the browser a new page will not be sent, so the original page does not change.

Where does indexOf come from?

It comes from the below String functions.

http://arduino.cc/en/Reference/StringObject

But why would it automatically skip the (?on or ?off) that comes before the number?

As I understand the operation, indexOf does not skip those characters, but compares those characters to the desired number to see if there is a match. If there is not a match, a counter is incremented and the next character is checked. If there is a match, the position in the character string is returned, and if the position is >0, then the condition is true and the following code is executed.

I've been playing around with the code zoomkat was generous enough to provide as a reference. I modified it making it so that instead of

if(inChar == 'g') { sendGET(); // call client sendGET function

the client of arduino 1 will talk to the server of arduino2 when a button is pressed.

The problem that I've run into is that if button1 on arduino1 is pressed, it activates client mode and talks to server of arduino2. But as it continues the loop, it runs into the server section, and arduino2 is now talking to the server.... so the server section, and the client section cause chaos. I've tried using delays, which worked at first, but every time I add or change anything the delay duck tape fix falls apart and it becomes an unpredictable slow mess.

Basically what I think I need but don't know how to word to ask, is to write in the program, once client program starts, the server program is ignored, until the client is finished. and if the server program is started, the client program needs to just hold its horses until the server is completed.

What would be the ideal way of tackling this? Would it be like a loop until client is not available type of format?

Basically what I think I need but don't know how to word to ask, is to write in the program, once client program starts, the server program is ignored, until the client is finished. and if the server program is started, the client program needs to just hold its horses until the server is completed.

That is actually how the code works. Your probable issue is with the button push (you haven't provided your code). You probably need to set a flag for your button push such that the client loop is not reenterd until the button is released and then pushed again. Your current code is probably creating a spew of client request upon the button press.