Go Down

Topic: Ethernet Simultaneous Cient and Server? (Read 7008 times) previous topic - next topic

renniejohnson

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.

PaulS

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?

The art of getting good answers lies in asking good questions.

renniejohnson

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?

PaulS

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.
The art of getting good answers lies in asking good questions.

renniejohnson

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.

zoomkat

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();

}


Google forum search: Use Google Search box in upper right side of this page.
Why I like my 2005 Rio Yellow Honda S2000  https://www.youtube.com/watch?v=pWjMvrkUqX0

paulakg4

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[])

PaulS

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.
The art of getting good answers lies in asking good questions.

paulakg4


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.


paulakg4

#9
Apr 08, 2013, 06:00 pm Last Edit: Apr 08, 2013, 06:17 pm by paulakg4 Reason: 1
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?

paulakg4

#10
Apr 08, 2013, 06:27 pm Last Edit: Apr 08, 2013, 07:01 pm by paulakg4 Reason: 1
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

Go Up