Arduino ethernet shield connected directly to PC gives problems [SOLVED]

Hi All,

I have a TCP arduino server and a client program on the pc. When i connect the server and pc to a router then there is no problem. But when i connect the Arduino en PC direcly to each other via a cable then the client can't connect (the server does not see the connection client). The PC has a static ip adres (192,168,100,1) and the server has a adres of 192.168.100.105). When i use ping on my pc and i ping to the server then everything is fine. I set the gate way adress on the server to 192.168.100.1 and the subnet mask to 255.255.255.0.

My question is if it is possible to directly connect the arduino server to a pc client? Below is the server code that set up the server:

IsServer = true;
		Serial.begin(9600);
		delay(1000);
		char Buffer[10];

		 Serial.println("Setting up server");

                                       IPAddress serverIP(192,168,100,105); // IP Adress to our Server

		 // the router's gateway address:
		byte gateway[] = { 192, 168, 100, 1 };

		// the subnet:
		byte subnet[] = { 255, 255, 255, 0 };
		   

		Mac = byte[] { 0x90, 0xA2, 0xDA, 0x0D, 0xA4, 0x13 };   //physical mac address
		for(int Index=0; Index < 6; Index++){
			Mac[Index] = MacAdress[Index];
		};

		ServerIP = ServerIPAdress; // IP Adress to our Server
		ServerPort = ServPort;

		// initialize the ethernet device
		Ethernet.begin(Mac, ServerIP, gateway, subnet);

		// start listening for clients
		ServerObject.begin();

		Serial.println("Server setup");

Any feedback is welcome!

I think you need a crossover ethernet cable to connect directly the shield and the PC

edit : is this really a "programming question" ? :wink:

Your Ethernet.begin() call is not correct. You did not include the dns server. I used the gateway ip below.

// change this
Ethernet.begin(Mac, ServerIP, gateway, subnet);
// to this
Ethernet.begin(Mac, ServerIP, gateway, gateway,subnet);

Hi all,
Thanks for your reply's! I have included the dns server (by using my gateway adress) and that works! I also forgot to to add my gatway and dns in my pc networkadapter. When i added them (192.168.100.1) as both my gateway and dns then the client can connect. im using a standard utp cable (straight trough).

Once again thanks for your reply's!

you can add [solved] to the thread title :slight_smile:

Hi all,

I have the same problem when i use my PC as a server and the Arduino as a client. If i connect them both to a router then evertying works fine, but when i connect them directly to each other then the server doesn't see the client. My PC networkadapter is still state 192.168.100.101.
Gateway 196.168.100.1.
DNS same as gateway
Subnetmask 255.255.255.0

Using the suggestion of SuferTim i did the following when setting up the client:

	Mac = byte[] { 0x90, 0xA2, 0xDA, 0x0D, 0xA4, 0x13 }; 

	ServerPort = 5000;

	// start the serial for debugging
	Serial.begin(9600);
	// start the Ethernet connection:

	
	byte gateway[] = { 192, 168, 100, 1 };
	byte subnet[] = { 255, 255, 255, 0 };
	IPAddress ip(192,168,100,105);

	Ethernet.begin(Mac, ip, gateway, gateway, subnet);

And then i have a connect function that connects to the server:

// give the Ethernet shield a second to initialize:
  delay(1000);
  Serial.println("connecting to Server ...");

  // if you get a connection to the Server
  IPAddress serverIp(192,168,100,101); 
  if (Client.connect(serverIp, 5000)) {
    Serial.println("connected");//report it to the Serial

		return 0;
  }
  else {
    // if you didn't get a connection to the server:
    Serial.println("connection failed");

		return -1;
  }

It Always returns with connection failed, does anybody have an idea? All suggestions are welkom!

Is your server on the PC listening to port 5000? Or port 80?

@SuferTim

Thanks for your reply, the server port is 5000.

No firewall problem? Have you tried the connection with a PC instead of the Arduino? Do not use the server as the test. It doesn't check the firewall.

You may have a crossover problem. Modern computers can detect a crossed connection when two Ethernet slave devices are connected together and adapt the interface accordingly. Older computers don't have this capability.

It's best to always use a crossover cable when connecting two Ethernet slaves together.

The Wiznet W5100 supports MDIX. No need for a crossover cable.
Page 5 here:

Thanks for your reactions!

My firewall is off and the PC that im using is a macbook pro with windows 8 form last year i think. With a server on the arduino and client on the pc there is no problem (thanks to TimSurfer suggestion).

Below are my PC networkadapter settings (the wireless adapter is off):
IP 192.168.100.101
SubnetMask: 255.255.255.0
Gateway: 192.168.100.1
DNS 192.168.100.1

All values are staticly.

Bellow is the PC server code, written with the ASIO boost library

cout << "Setting up server" << endl;
		// Protocol and port
		 boost::asio::ip::tcp::endpoint Endpoint(boost::asio::ip::tcp::v4(), 5000);

		// Create acceptor
		boost::asio::ip::tcp::acceptor Acceptor(IOService, Endpoint);

		// Create socket
		SmartSocket Sock(new boost::asio::ip::tcp::socket(IOService));

		cout << "Before accept..." << endl;

		 // Waiting for client
	     Acceptor.accept(*Sock);

		cout << "Server set up" << endl;

		for(unsigned int i=0; i < sizeof(SendBuffer); i++){
			SendBuffer[i] = 'a';
		}

		for(unsigned int i=0; i < sizeof(RecvBuffer); i++){
			RecvBuffer[i] = 'b';
		}

		cout << "inhoud after filling InputBuffer: ";
		for (unsigned int i = 0 ; i < sizeof(SendBuffer) ; i++) cout << SendBuffer[i] << " ";
		cout << endl;

		cout << "inhoud after filling RecvBuffer: ";
				for (unsigned int i = 0 ; i < sizeof(RecvBuffer) ; i++) cout << RecvBuffer[i] << " ";
		cout << endl;

		while(1){

			SendData(Sock);
			Sleep(1000);
			RecieveData(Sock);

			cout << "inhoud after filling InputBuffer: ";
			for (unsigned int i = 0 ; i < sizeof(SendBuffer) ; i++) cout << SendBuffer[i] << " ";
			cout << endl;

			cout << "inhoud after filling RecvBuffer: ";
					for (unsigned int i = 0 ; i < sizeof(RecvBuffer) ; i++) cout << RecvBuffer[i] << " ";
			cout << endl;
		}

And on the Arduino client class constructor:

		IsServer = false;
		byte Mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0xA4, 0x13 };   //physical mac address
		//for(int Index=0; Index < 6; Index++){
		//	Mac[Index] = MacAdress[Index];
		//};
	
		ServerIP = ServerIPAdress; // IP Adress to our Server
		ServerPort = ServPort;

		// start the serial for debugging
		Serial.begin(9600);
		// start the Ethernet connection:

		// the router's gateway address:
		byte gateway[] = { 192, 168, 100, 1 };

		// the subnet:
		byte subnet[] = { 255, 255, 255, 0 };

		IPAddress ip(192,168,100,105);

		// For direct connection
		Ethernet.begin(Mac, ip, gateway, gateway, subnet);

and connect function

  // give the Ethernet shield a second to initialize:
  delay(1000);
  Serial.println("connecting to Server ...");

  // if you get a connection to the Server
  //IPAddress serverIp(192,168,100,101); 
  if (Client.connect(ServerIP , 5000)) {
    Serial.println("connected");//report it to the Serial

		return 0;
  }
  else {
    // if you didn't get a connection to the server:
    Serial.println("connection failed");

		return -1;
  }

In the serail monitor i get connection failed and in the console of the server i get waiting before accept.

Any suggestions are welcome! :slight_smile:

It would be best if you posted the entire Arduino sketch. I would like to see it all in one post.

@SurferTim

My communicator class in seperate cpp an h files and these are used in my sketch files:

My sketch file:

#include <CommunicationModule.h>
#include <CommunicationModuleTCPIP.h>


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

byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0xA4, 0x13 };   //physical mac address
IPAddress serverIP(192,168,100,101); // IP Adress to our Server
int serverPort=5000;

char Buffer[10];

// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to
EthernetClient client;

CommunicationModuleTCPIP CMIP;

void setup() {
  
   CMIP =   CommunicationModuleTCPIP(mac, serverIP, 5000, false);
   
   CMIP.Connect();
}

void loop()
{
  // if there are incoming bytes available
  // from the server, read them and print them:
  if (CMIP.Client.available() == 10) {
    CMIP.RecieveBuffer(Buffer, 10);
    Serial.print(Buffer);
    
    CMIP.SendBuffer(Buffer, 10);
  }

  // if the server's disconnected, stop the client:
  if (!CMIP.Client.connected()) {
    Serial.println();//report it to the serial
    Serial.println("disconnected");
    CMIP.Client.stop();

    // do nothing forevermore:
    for(;;)
      ;
  }
}

My class headerfile:

#ifndef COMMUNICATIONMODULETCPIP_H_
#define COMMUNICATIONMODULETCPIP_H_


#include "CommunicationModule.h"
#include "Arduino.h"
#include <SPI.h>
#include <Ethernet.h>

//extern EthernetServer ServerObject;

class CommunicationModuleTCPIP : public CommunicationModule
{
   public:

	CommunicationModuleTCPIP(byte MacAdress[], IPAddress ServerIPServerIPAdress, int ServPort, bool Server);
	CommunicationModuleTCPIP();

	int Connect();
	void SendBuffer(char Buffer[], int Size);
	void RecieveBuffer(char Buffer[], int Size);
	void ClearBuffer(char Buffer[]);

	
	bool IsServer;
	byte Mac[];
	IPAddress ServerIP;
	int ServerPort;

	EthernetClient Client;
	EthernetServer ServerObject;

	bool DataRecieved;

   private:
};




#endif /* COMMUNICATIONMODULE_H_ */

And the cpp file of the class:

#include "CommunicationModuleTCPIP.h"

CommunicationModuleTCPIP::	CommunicationModuleTCPIP()
	:ServerObject(5000){

}


CommunicationModuleTCPIP::	CommunicationModuleTCPIP(byte MacAdress[], IPAddress ServerIPAdress, int ServPort, bool Server)
	:ServerObject(5000)
{


	if(!Server){

		IsServer = false;
		byte Mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0xA4, 0x13 };   //physical mac address
		//for(int Index=0; Index < 6; Index++){
		//	Mac[Index] = MacAdress[Index];
		//};
	
		ServerIP = ServerIPAdress; // IP Adress to our Server
		ServerPort = ServPort;

		// start the serial for debugging
		Serial.begin(9600);
		// start the Ethernet connection:

		// the router's gateway address:
		byte gateway[] = { 192, 168, 100, 1 };

		// the subnet:
		byte subnet[] = { 255, 255, 255, 0 };

		IPAddress ip(192,168,100,105);

		// For direct connection
		Ethernet.begin(Mac, ip, gateway, gateway, subnet); 
   
		// For DHCP connection
		//if (Ethernet.begin(Mac) == 0) {
		//	Serial.println("Failed to configure Ethernet using DHCP");
		//	// no point in carrying on, so do nothing forevermore:
		//	for(;;){
		//		;
		//	}
		//}	
	}
	else{
		IsServer = true;
		Serial.begin(9600);
		delay(1000);
		char Buffer[10];

		 Serial.println("Setting up server");

		 // the router's gateway address:
		byte gateway[] = { 192, 168, 100, 1 };

		// the subnet:
		byte subnet[] = { 255, 255, 255, 0 };

		//Mac = byte[] { 0x90, 0xA2, 0xDA, 0x0D, 0xA4, 0x13 };   //physical mac address
		for(int Index=0; Index < 6; Index++){
			Mac[Index] = MacAdress[Index];
		};

		ServerIP = ServerIPAdress; // IP Adress to our Server
		ServerPort = ServPort;

		// initialize the ethernet device
		Ethernet.begin(Mac, ServerIP, gateway, gateway, subnet);

		// start listening for clients
		ServerObject.begin();

		Serial.println("Server setup");

	}
}

int CommunicationModuleTCPIP::Connect(){

  // give the Ethernet shield a second to initialize:
  delay(1000);
  Serial.println("connecting to Server ...");

  // if you get a connection to the Server
  //IPAddress serverIp(192,168,100,101); 
  if (Client.connect(ServerIP , 5000)) {
    Serial.println("connected");//report it to the Serial

		return 0;
  }
  else {
    // if you didn't get a connection to the server:
    Serial.println("connection failed");

		return -1;
  }

};


void CommunicationModuleTCPIP::SendBuffer(char Buffer[], int Size){

	//Serial.println("Before");
	//Client = ServerObject.available();
    //Client.write((uint8_t*)Buffer, Size);
	//Serial.println("After");



	if(IsServer){
		if(DataRecieved){
				// Serial.println("client connected send");
				Client.write((uint8_t*)Buffer, Size);

				DataRecieved = false;
		}
	}
	else{
	     Client.write((uint8_t*)Buffer, Size);
	}
}

void CommunicationModuleTCPIP::RecieveBuffer(char Buffer[], int Size){

	if(IsServer){
		Client = ServerObject.available();
		if (Client.connected()) {
			if(!DataRecieved){
			// Serial.println("client connected recieve");

			for(int i=0;i < Size; i++){
				Buffer[i] = Client.read();
			}

			for (unsigned int i = 0; i < 10; i++) {
				Serial.print(Buffer[i]);
			}
			Serial.println();   

			DataRecieved = true;
			}
		}

	}
	else{
	  for(int i=0;i < Size; i++){
		Buffer[i] = Client.read();
      };
	}
}


void CommunicationModuleTCPIP::ClearBuffer(char Buffer[]){
	Buffer[0] = '\0';
}

Hope this gives more insight, i have to go to an appointment so i will not be able to respond back until to night/ tommorrow. Hope that you (and others) can help me.

Many thanks!

Does anybody have an idea why the connecting Arduino client can't been seen by the PC server? :~

Try connecting with a simple sketch. This just connects and disconnects every 10 seconds. Does it work?

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

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,100,105);

IPAddress remoteIP(192,168,100,101);
unsigned int remotePort = 5000;

EthernetClient client;

void setup() {
  Serial.begin(9600);

  // disable SD SPI
  pinMode(4,OUTPUT);
  digitalWrite(4,HIGH);

  Serial.print(F("Starting ethernet..."));
  Ethernet.begin(mac,ip);
  Serial.println(Ethernet.localIP());

  delay(2000);
  Serial.println(F("Ready"));
}

void loop() {
  Serial.print(F("Connecting..."));
  if(client.connect(remoteIP,remotePort))  {
    Serial.println(F("connected"));
   client.stop();
  }
  else Serial.println(F("failed"));

  delay(10000);
}

@TimSurfer:

Thanks again for your reaction. I used your program (changed the mac to my mac adress and checked the ip of the server).
And at first it didn't work, but the i started thinking that maby the pc server also uses DHCP to get its IP adres. Then i bounded my IP adress to my network adapter like this:

I replaced the following code line:

/boost::asio::ip::tcp::endpoint Endpoint(boost::asio::ip::tcp::v4(), 5000);

With:

 ip::tcp::endpoint Endpoint(ip::address::from_string( "192.168.100.101" ), 5000 );

And it worked! Then i runned my client sketch and it works to!

Many thanks TimSurfer for all your time and effort (and others to :wink: ).