Project Help: Multiple Ethernet Shields

Hello all,

I am working on a project connecting multiple Arduinos in different locations across the world. The way I have it set up right now, one Arduino (attached to a ship bell) acts as a server that loads a webpage. The other Arduino is attached to a push button switch, and when pushed will send a get request to the webpage, activating the first Arduino and ringing the bell via a servo motor. This all works fine together so far.

The issue with this system is that I need to have several “bell” Arduinos. I was planning to just have each “bell” Arduino be a different server, and have the “button” Arduino send out multiple get requests at once, but I can’t figure out how to get the “button” Arduino to connect to more than one server at a time.

Is there an easier way to do what I’m doing? Does anyone know how to connect a single EthernetClient to multiple EthernetServers?

I’ve attached the code I’m using below. Note that some of the code I’m using isn’t mine, it’s compiled from projects i’ve seen around the internet. I don’t know specifically who wrote them, but I’m not claiming any of it as my own.

“Button” Arduino Code:

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

int buttonInput = 7;
int buttonState = 0;

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 10, 250, 1, 80 };
byte gateway[] = { 10, 250, 0, 1 };
byte server[] = { 10, 250, 4, 80 }; // server id

EthernetClient client;

bool connected = false;

void setup()
{
  Ethernet.begin(mac, ip, gateway);
  Serial.begin(9600);
 
  pinMode(buttonInput, INPUT);
  //digitalWrite(buttonInput, HIGH);

  delay(1000);

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

}

void loop() {
 


   if (client.connect(server,80)) {
 
    buttonState = digitalRead(buttonInput);
    
    Serial.println("connected");  }
   if (buttonState == LOW) {
               }
   if (buttonState == HIGH) { 
       client.print("GET /?button2off");
       Serial.print("GET /?button2off");
       client.println(" HTTP/1.1");
       Serial.println(" HTTP/1.1");
       client.println("Host: http://localhost/PhpProject1/");
       Serial.println("Host: http://localhost/PhpProject1/");
       client.println("User-Agent: Arduino");
       Serial.println("User-Agent: Arduino");
       client.println();
       client.stop(); 
  
     }
    //else {
      delay(900);
    if (client.available()) {
        char c = client.read();
        Serial.print("fine");
        }
        Serial.println();                                         
      //client.stop();                                            
      connected = false;
    }

“Bell” Arduino Code:

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

Servo microservo; 
int pos = 0; 
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEF };   //physical mac address
byte ip[] = { 10, 250, 1, 80};                      // ip in lan (that's what you need to use in your browser. ("192.168.1.178")
byte gateway[] = { 10, 250, 0, 1 };                 //internet access via router
//byte subnet[] = { 255, 255, 255, 0 };                  //subnet mask
EthernetServer server(80);                          //server port     
String readString;

void setup() {
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
  
 //  pinMode(led, OUTPUT);
  microservo.attach(7);
  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip, gateway);
  server.begin();

}


void loop() {
  // Create a client connection
  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
     
           client.println("HTTP/1.1 200 OK"); //send new page
           client.println("Content-Type: text/html");
           client.println();     
           client.println("<HTML>");
           client.println("<HEAD>");
           client.println("<meta name='apple-mobile-web-app-capable' content='yes' />");
           client.println("<meta name='apple-mobile-web-app-status-bar-style' content='black-translucent' />");
           client.println();
           client.println("<TITLE>Arduino Control Room</TITLE>");
           client.println("</HEAD>");
           client.println("<BODY>");
           client.println("<H1>Arduino Control Room</H1>");
           client.println("<hr />");
           client.println("
");  
           client.println("<H2>Arduino with Ethernet Shield</H2>");    
           client.println("
"); 
           client.println("<a href=\"/?button2off\"\">Rotate</a>
"); 
           client.println("<p>Created by Mike O'Dell.</p>");  
           client.println("
"); 
           client.println("</BODY>");
           client.println("</HTML>");
     
           delay(5);
           //stopping client
           client.stop();
           //controls the Arduino if you press the buttons

           if (readString.indexOf("?button2off") >0){
                //for(pos = 180; pos>=1; pos-=3)     // goes from 180 degrees to 0 degrees 
                { 
                  microservo.attach(7,544,2400);//Pulse Values for a HiTec Servo
                  //microservo.write(9);  // set servo to 0

                  microservo.write(180);

                  delay(600);
                  microservo.detach();
                } 
           }
            //clearing string for next read
            readString="";  
            
         }
       }
    }
}
}

Thank you for the help!

You can connect to as many servers as you want. Take a look at this example code.
http://playground.arduino.cc/Code/WebClient
You can call the getPage function with different server IPs.

If these devices are all localnet, you might do better with UDP. Just a thought...

edit: Even if they are not localnet, you can use UDP. The "client" sends a packet and the "server" returns a response packet.

Hello SurferTim,

Thank you for the help. I got the “bell” arduino to work, but the “button” arduino wouldn’t connect to it over a different subnet (I have to make it work across subnets, I should have mentioned that. It’s staying inside the local network but across different subnets across the globe).

If the UDP method would work, can you give me an example to work off of? I haven’t ever used UDP with Arduino before… Do you think they will still communicate across subnets?

Thank you again for the help.

If you want to access the "bell" (server) with the "button" (client), you must learn a bit about networking and port forwarding. The "server" router that connects to the internet will need an additional setting forwarding the public IP and port to the server's localnet IP and port.

Do a Google search for "router port forward", or look in the router's manual to determine how to accomplish this.

Thank you for the fast reply.

I have used port forwarding before, the issue is that this project is on a corporate network with firewalls and protocols that I cannot touch. I can get the devices to communicate across subnets once in a while, but it is intermittent and not reliable (the system has to work after I've left it for a while, on an external power source). I guess all I need is a reliable way for the "button" code to set off the "bell"... if that is even possible with such a finnicky connection.

Another question: is there a way I can use UDP for the "button" and the server set up I already have for the "bells"? I am semi-crunched for time, I have to get this all to work by the end of next week. The "bell" Arduino set up and code that I posted above works perfectly all the time, with a built in reset for power outages and such. The "button" code is the only one that is giving me trouble.

In other words, with a basic UDP code setup for the “button” like this:

 #include <Ethernet.h>

#include <EthernetUdp.h>



// Enter a MAC address and IP address for your controller below.

// The IP address will be dependent on your local network:

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

IPAddress ip(10, 250, 1, 81);



unsigned int localPort = 8888;      // local port to listen on

EthernetUDP Udp;

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




void setup() {

  // start the Ethernet and UDP:

  Ethernet.begin(mac,ip);

  Udp.begin(localPort);

  Serial.begin(9600);

}



void loop() {
  
    Udp.beginPacket(IPAddress (10, 250, 1, 80), 8888);
    Udp.write("Hello");
    Udp.endPacket();
    Serial.println("test");  // prove serial mon is working
    
    delay(100);
}
[\code]

Can I just add the UDP format and two lines of code to the “bell” code to receive the message, then ‘if packet says ‘hello’, do action’? Can you think of a simple action code like that?

That should be a "Perfect World" version, but it should work as long as nothing goes wrong.

I would have the UDP "server" return a packet so You will know the packet got to the server.

If the "server" is behind a router that does a NAT, you need to do a port forward.