Arduino Forum

Using Arduino => Programming Questions => Topic started by: renniejohnson on Aug 01, 2012, 04:17 pm

Title: Ethernet Simultaneous Cient and Server?
Post by: renniejohnson on Aug 01, 2012, 04:17 pm
Can you service both an ethernet client and server object concurrently in the main loop?  I'm only doing intranet networking with a single Windows host computer.

How about multiple clients and a server object?

Does the Arduino automatically know which objects to send the packet data to, or do you have to test for that.

Code examples?

Thanks.
Title: Re: Ethernet Simultaneous Cient and Server?
Post by: PaulS on Aug 01, 2012, 04:42 pm
Quote
Can you service both an ethernet client and server object concurrently in the main loop?  I'm only doing intranet networking with a single Windows host computer.

You can't do ANYTHING concurrently on an Arduino. It's a single processor system with no OS.

You can run as client and server, processing one part at a time.

Quote
How about multiple clients and a server object?

Up to 4 (on the W5100 based Ethernet shields/boards) clients can be connected at a time; only one client at a time can be serviced.

Quote
Does the Arduino automatically know which objects to send the packet data to

Whichever client instance you tell it to send data to gets the data.

Quote
or do you have to test for that.

What's to test?

Title: Re: Ethernet Simultaneous Cient and Server?
Post by: renniejohnson on Aug 01, 2012, 08:01 pm
Forgive my ignorance.  My curiosity was for incoming packet data.  If I have one server object and one or more client objects, each has their own IP address on the same subnet.  Each client object will communicate with a different server hardware device on the intranet.  The server object will receive client requests from the Windows host computer.

Currently, I only have only one ethernet server object and no clients.  In main sketch loop, I have this code:

Code: [Select]
led.WaitClient();   

  if(led.m_client.available())
  {
     commandReturn = led.GetCommand();
     commandReturn = led.ProcessCommand();
    delay(1);
  }


This is the code for GetCommand():

Code: [Select]
int LED_V3::GetCommand()
{
int tempChar;
m_commandReceivedComplete = 0;
m_commandLength = 0;
m_commandProcessedComplete = 0;
ClearCommand();

do{
if(m_client.available())
{
tempChar = m_client.read();

if(tempChar != 13)
{
m_command[m_commandLength] = tempChar;
m_commandLength += 1;
}
}
}while(tempChar!=13);

m_commandReceivedComplete = 1;
return RETURN_SUCCESS;
}


I guess my questions would be:

Will  I lose any incoming ethernet data for other ethernet objects by calling led.WaitClient();   

How does the sketch know how to distribute incoming packet data to the correct object?  Does the assignment of the IP address take care of that, or do I need to have special code to test?
Title: Re: Ethernet Simultaneous Cient and Server?
Post by: PaulS on Aug 01, 2012, 08:30 pm
Quote
If I have one server object and one or more client objects, each has their own IP address on the same subnet.

Whether the devices are all on the same subnet, or not, is irrelevant, from the point of view of the Arduino as server or the Arduino as client.

Quote
Each client object will communicate with a different server hardware device on the intranet.

So, each server will serve one client. How is there a risk, then, of sending data to the wrong client?

Quote
The server object will receive client requests from the Windows host computer.

I don't know what you mean by "the Windows host computer". The OS on the server or on the client is completely irrelevant.

Quote
Currently, I only have only one ethernet server object and no clients.  In main sketch loop, I have this code

How can you be calling the available() method for a client you don't have?

Code: [Select]
if(tempChar != 13)
{
m_command[m_commandLength] = tempChar;
m_commandLength += 1;
}

Is m_command{} going to magically grow to accommodate unlimited amounts of data?

Quote
Will  I lose any incoming ethernet data for other ethernet objects by calling led.WaitClient();   

Without knowing what led is, or what it's WaitClient() method does, that question can not be answered.

Quote
How does the sketch know how to distribute incoming packet data to the correct object?

There is only one active client object at a time. That is the one that the methods available(), read(), and write() are called on. The connection between that object and the incoming stream of data is maintained by the WizNet hardware.

Code: [Select]
Does the assignment of the IP address take care of that, or do I need to have special code to test?
I don't understand the question. Packets routed to the Arduino have both a source IP address (who issued the request, so the response goes back to the right place) and a destination IP address (that of the Arduino). The ethernet shield takes care of getting the incoming packets for the active client routed to the client object.
Title: Re: Ethernet Simultaneous Cient and Server?
Post by: renniejohnson on Aug 01, 2012, 09:48 pm
I'm sorry I am unable to articulate well on this matter.  I'm kind of a weekend warrior on these matters.  What I think I got from you is that I am free to operate multiple ethernet objects, client or server, and the Wiznet will handle the routing.  All I need to do is poll for incoming data for each object in my sketch loop and process accordingly.
Title: Re: Ethernet Simultaneous Cient and Server?
Post by: zoomkat on Aug 02, 2012, 12:44 am
Some combined server/client test code.

Code: [Select]
//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 pin 5 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 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.println(readString); //print to serial monitor for debuging

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

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

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

            client.println("<a href='/?on' target='inlineframe'>ON</a>");
            client.println("<a href='/?off' target='inlineframe'>OFF</a>");

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

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

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

          ///////////////////// control arduino pin
          if(readString.indexOf("on") >0)//checks for on
          {
            digitalWrite(5, HIGH);    // set pin 5 high
            Serial.println("Led On");
          }
          if(readString.indexOf("off") >0)//checks for off
          {
            digitalWrite(5, LOW);    // set pin 5 low
            Serial.println("Led Off");
          }
          //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();

}


Title: Re: Ethernet Simultaneous Cient and Server?
Post by: paulakg4 on Apr 08, 2013, 04:56 pm
So - Im working on something very similar but slightly different, hoping Paul S or Zoomcat might help me out.

Im wanting to do basically the same thing except I want to control two boards - both running the Firmata Library - using one Ethernet shield.

My setup is>

{A}ArduinoMega 2560 + Seeed Ethernet Shield (r1) + [sketch1]
|
pins[17,18][5v,grd] tied to
           X
pins[1,0][vin,grnd] on
|
{B}ArduinoUno R3 + Arduino Motor Shield(external power supply) + [sketch2]


Im able to connect board A no problem but can't seem to ping or connect to board B

(see next post for sketch[])
Title: Re: Ethernet Simultaneous Cient and Server?
Post by: PaulS on Apr 08, 2013, 05:14 pm
Quote
Im wanting to do basically the same thing except I want to control two boards - both running the Firmata Library - using one Ethernet shield.

Not going to happen. Firmata has no idea how to talk to the Ethernet shield.
Title: Re: Ethernet Simultaneous Cient and Server?
Post by: paulakg4 on Apr 08, 2013, 05:48 pm

I got really excited for a minute, I thought I was going to get to tell the great Paul S. that he was mistaken  ;)
but your not entirely wrong - nor entirely right. Check this out>

https://github.com/paulakg4/ArduinoCommander-ethernet/blob/master/Firmata/examples/StandardFirmataEthernet/StandardFirmataEthernet.ino

it requires you to overwrite the current Ethernet library (which is why technically your right) - but it works great with just one device.

I should mention on the client side I am connecting through the Pyfirmata library for Python.

Title: Re: Ethernet Simultaneous Cient and Server?
Post by: paulakg4 on Apr 08, 2013, 06:00 pm
well I cant get it to fit in here but all I did was insert this into the first line of setup()
Code: [Select]
void setup()
{
 Serial.begin(57600);
 Serial1.begin(57600);     <+++Added


Serial.println("setup()");

#ifdef DHCP
 // IP by DHCP
Serial. ....
 

and this at the beginning of loop()

Code: [Select]
void loop()
{
 
------------------------------------------<+++Added
   if (Serial1.available()) {
   int inByte = Serial1.read();
   ethernet.write(inByte);
 }
 
 // read from port 0, send to port 1:
 if (ethernet.available()) {
   int inByte = ethernet.read();
   Serial1.write(inByte);
 }
<+++Added -------------------------------------------------

 byte pin, analogPin;

 /* DIGITALREAD - as fast as possible, check for changes and output them to the
  * FTDI buffer using Serial.print()  */
 checkDigitalInputs();  

 /* SERIALREAD - processing incoming messagse as soon as possible, while still
  * checking digital inputs.  */
 while(firmata.available())
   firmata.processInput();

 /* SEND FTDI WRITE BUFFER - m....


Am I on the right the track?
Title: Re: Ethernet Simultaneous Cient and Server?
Post by: paulakg4 on Apr 08, 2013, 06:27 pm
If you dont mind coming along for the ride, I'd like to branch this out to a new thread>
Ive found very little information on ethernet + firmata, and Im pretty sure this could work, but Im really terrible with these conditional loops (if thats what theyre called).

>> http://arduino.cc/forum/index.php/topic,159228.0.html