Arduino Ethernet Shield Client and Server

I want to share a project that uses two Arduinos to communicate over LAN as a client and server.  These two sketches were made for a pan/tilt controller, but you can modify the code to send other data.

Client:

/*
*
* This program controls the Bescor MP−101 Pan/Tilt system via Ethernet
*
* Copyright (c) 2012 Matt Alford, http://www.protechy.com
* Date: Sep 15, 2012    
*
*  This program is free software: you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation, either version 3 of the License, or
*  (at your option) any later version.

*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.

*  You should have received a copy of the GNU General Public License
*  along with this program.  If not, see <http://www.gnu.org/licenses></http:>.
*/

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

byte mac[] = {   0x90, 0xA2, 0xDA, 0x0D, 0xXX, 0xXX }; //assign arduino mac address
byte ip[] = { xxx, xxx, x, xx}; // ip in lan assigned to the arduino

//byte gateway[] = { xxx, xxx, x, x }; // internet access via router
//byte subnet[] = { xxx, xxx, xxx, x }; //subnet mask

EthernetServer server(8888); //server port of the arduino
EthernetClient client;

byte serverName[] = { xxx, xxx, x, xx }; // (IP) Arduino server IP address 

#define up 9  
#define down 3  
#define left 6    
#define right 5   

int absx = 0; 
int absy = 0;   
int posx = 0;
int posy = 0;
int valueX = 0;
int valueY = 0;

void setup()
{

  Ethernet.begin(mac,ip); 
  server.begin();
  Serial.begin(115200);   

}

boolean packetEndedX = false;
boolean negativeX = false;

boolean packetEndedY = false;
boolean negativeY = false;

void recieve() //client function to send and receive data from the Arduino server.
{
  if (client.connect(serverName, 8888)) 
  {

    Serial.println("connected");
    client.println("G");
    client.println();

  } 
  else 
  {

    client.println("x");
    client.println();
    Serial.println("connection failed");
    Serial.println();
    resetEthernetShield();

  }

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

    if(c == '<')
    {
     posx = 0;
      do {
        while(client.available() <1); // wait for a character
    c = client.read();
        if(c == '-')
        negativeX = true;
    if(c >= '0' && c <= '9' )
        posx = posx * 10 + c - '0';
      } 
        while(c != ',');    
        packetEndedX = true;
      do {
        while(client.available() <1); // wait for a character
        c = client.read();
        if(c == '-')
        negativeY = true;
    if(c >= '0' && c <= '9')
    posy = posy * 10 + c - '0';
       } 
      while(c != '>');
      packetEndedY = true;            
    }    

   if(packetEndedY)
   {
     if(negativeY)
     posy *= -1;
     valueY = posy;
     posy = 0;
     negativeY = false;
     packetEndedY = false;

   } 

  if(packetEndedX)
   {
     if(negativeX)
     posx *= -1;
     valueX = posx;
     posx = 0;
     negativeX = false;
     packetEndedX = false;     
   } 

    Serial.print("X value: ");
    Serial.println(valueX);
    Serial.print("Y value: ");
    Serial.println(valueY);
    Serial.println();

  }

    Serial.println();
    Serial.println("disconnecting.");
    client.stop();
    delay(15);
}

//////////////Main Loop////////////

void loop()
{
  recieve(); //client function to send and receive data from the Arduino server.

  absx = valueX;
  absx = abs(valueX);  // Convert to an absolute value
  absy = valueY;
  absy = abs(valueY); 

  if (valueX > 10)
  {
    analogWrite(right, absx * 2.5);
    digitalWrite(left, LOW);
  }
  else if (valueX < -10)
  {
    analogWrite(left, absx * 2.5);
    digitalWrite(right, LOW);
  }
  // Stop pan
  else
  {
    analogWrite(right, LOW);
    analogWrite(left, LOW);
  }  
  if (valueY > 10)
  {
    analogWrite(up, absy * 2.5);
    digitalWrite(down, LOW);
  }
  else if (valueY < -10)
  {
    analogWrite(down, absy * 2.5);
    digitalWrite(up, LOW);
  }
  // Stop tilt
  else
  {
    analogWrite(up, LOW);
    analogWrite(down, LOW);
  }

}
void resetEthernetShield() //reset when disconnected from the server
{  
  delay(100);
  Serial.println("reset ethernet");
  client.stop();
  Ethernet.begin(mac, ip);
  delay(100);
}

 

Server:

/*
*
* Controller
* This program controls the Bescor MP-101 Pan/Tilt system via Ethernet
*
* Copyright (c) 2012 Matt Alford, http://www.protechy.com
* Date: Sep 15, 2012    
*
*  This program is free software: you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation, either version 3 of the License, or
*  (at your option) any later version.

*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.

*  You should have received a copy of the GNU General Public License
*  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

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

WiiChuck chuck = WiiChuck();

byte mac[] = {   0x90, 0xA2, 0xDA, 0x0D, 0xXX, 0xXX }; //assign arduino mac address
byte ip[] = { 192, 168, 1, 41}; // ip in lan assigned the to arduino

//byte gateway[] = { 192, 168, 1, 1 }; // internet access via router
//byte subnet[] = { 255, 255, 255, 0 }; //subnet mask

EthernetServer server(8888); //server port arduino server will use
EthernetClient client;

void setup()
{
  Ethernet.begin(mac,ip); 
  server.begin();
  chuck.begin();
  chuck.update();
  Serial.begin(115200); 
}

void loop()
{
  chuck.update();
  EthernetClient client = server.available();
  if (client) 
  {
    while (client.connected()) 
    {
      if (client.available()) 
      {
        char c = client.read();     
       if(c == 'G') //Client's response
      {
          client.print("<");
          client.print(chuck.readJoyX());             
          client.print(",");
          client.print(chuck.readJoyY());
          client.println(">");

          Serial.print("X value: ");
          Serial.println(chuck.readJoyX());          
          Serial.print("Y value: ");
          Serial.println(chuck.readJoyY());  
          Serial.println();
          client.stop();
          break;   
       }   
      if (c == 'x') //If dissconected from client, it might not be necessary to reset server
      { 
        delay(100);
        Serial.println("reset ethernet");
        Ethernet.begin(mac, ip);
        delay(100);   
        client.flush();
        client.stop();          
      }
    }
   }
  }
  delay(5);
}

 

5 Comments

  1. Matt, I notice in your client/server version of the code that you are using different pins to the Bescor and not setting the PWM freqs as you did with v2.4. Are the freqs handled differently with the client/server version? What is optimal?

    With my setup is using the v2.4 connection and I am seeing up/down working very close to what I need as far as smoothness, but the right/left is a little too jerky.

    v2.4:
    UP – 10 (timer 1)
    DN – 9 (timer 1)
    LF – 11 (timer 2)
    RT – 3 (timer 2)

    Client:
    UP – 9 (timer 1)
    DN – 3 (timer 2)
    LF – 6 (timer 0)
    RT – 5 (timer 0)

    BTW, you’ve done a great job with this. It has been interesting to follow your efforts.

    –Jvk
    Joe Key

    Reply
    • The Ethernet Shield stopped working when I tried to use the same pins on v2.4. Also, the timer was messing up the connection. Yes, it seems the up and down is a little smoother. I remember having trouble getting the left and right to be as smooth.

      Reply
  2. I went ahead and used the PWM pins as you did on your Ethernet setup, but I am using MIDI shields for my interconnect and adjusted their pins to avoid conflict. FWIW, instead of using the Wii Nunchuck, I am using an old school analog joystick. Hoping to find the right tweak to be able to use in a live performance setting. The choice to use/experiment with MIDI will allow me to have servo pan/tilt cameras that I can store multiple positions, though with the MP-101, that is not possible. Thanks again your efforts.

    Reply
  3. Why do you have written server.begin() in void setup() in the client version of arduino program?

    Reply
    • You’re correct. Its not necessary to use server.begin() for the client side of things, but I’ll have to look back to see why I did that.

      Reply

Submit a Comment

Your email address will not be published.