Two way TCP ethernet communication without a router

Hello, I have two Arduino UNOs that I am trying to get communicating with one another using TCP but without a router to handle DHCP. All the information I can find involves using a router to handle IP address allocation etc but since these do not need to be connected to the internet I do not wish to use a router and so will be connecting them directly via a cable. I plan on eventually using a switch as I have a third device on its way but I will still not be using a router as this LAN needs to be completely self contained. Can anyone help me find the information I need to get two arduinos talking to each other using the Ethernet shield and TCP without a router?

set static IP address. good values are IP 192.168.1.x use Ethernet.begin(mac, ip)

some Ethernet shields can do automatic 'crossing' but it is best to use cross cable for direct connection

I have two Arduino UNOs that I am trying to get communicating with one another using W5100 ethernet shields and a direct connection using a 568-B.2 patch cord. I have already confirmed that both of my ethernet shields are working by connecting to my router and using DHCP and python on my PC to communicate individually however whenever I try to assign static IPs to each UNO and have them communicate directly with each other they wont do it. I can get client.connect(server_ip, server_port) to return true however there doesn’t seem to be any actualy traffic between the two. Below is the code for the server UNO and client UNO.

Server:

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

// I2C LCD SETUP
LiquidCrystal_I2C LCD(0x27, 20, 4);

// Network configuration
const int server_port = 4080;
byte mac[] = {0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x01};
byte ip[] = {10,0,0,1};
EthernetServer server(server_port);

void setup() {
    Serial.begin(9600);
    Serial.println("Main Hub: Initializing");
    // Initialize Ethernet
    Ethernet.begin(mac, ip);
    server.begin();
    Serial.println("Main Hub: Server started");
    LCD.init();
    LCD.backlight();
    LCD.setCursor(0, 0);
    LCD.print("*      SERVER      *");
    LCD.setCursor(0, 1);
    LCD.print("IP: ");
    LCD.print(ip[0]);
    LCD.print(".");
    LCD.print(ip[1]);
    LCD.print(".");
    LCD.print(ip[2]);
    LCD.print(".");
    LCD.print(ip[3]);
    LCD.setCursor(0, 2);
    LCD.print("                    ");
    LCD.setCursor(0, 3);
    LCD.print("                    ");
}

void loop() {
    // check for clients
    EthernetClient client = server.available();
    if (client == true) {
        Serial.println("Main Hub: Client connected");
        server.write(client.read());
        Serial.println(client.read());
    }
}

Client:

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

// I2C LCD SETUP
LiquidCrystal_I2C LCD(0x27, 16, 2);

// Network configuration
const int server_port = 4080;
byte mac[] = {0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x01};
byte ip[] = {10,0,0,2};
byte server_ip[] = {10,0,0,1};
EthernetClient client;

void setup() {
    Serial.begin(9600);
    Serial.println("Client 1: Initializing");
    // Initialize Ethernet
    Ethernet.begin(mac, ip);
    LCD.init();
    LCD.backlight();
    LCD.setCursor(0, 0);
    LCD.print("*    CLIENT    *");
    LCD.setCursor(0, 1);
    LCD.print("IP: ");
    LCD.print(ip[0]);
    LCD.print(".");
    LCD.print(ip[1]);
    LCD.print(".");
    LCD.print(ip[2]);
    LCD.print(".");
    LCD.print(ip[3]);
    Serial.println("Client 1: Connecting to main hub");
    if (client.connect(server_ip, server_port)) {
        Serial.println("Client 1: Successfully connected to server");
        client.println("TEST");
    } else {
        Serial.println("Client 1: Failed to connect to server");
    }
}

void loop() {
    // do nothing for now
}

Thanks for the reply Juraj, I have opened another post in the more appropriate category and will link to it from here. I should have mentioned that I was already using a patch cord as well as assigning static IPs for both UNOs. New Post+

I believe this is due to the autonegotiation failing between two Ethernet shields as I recall having this problem posted by another user a short while back. The simplest solution is to use a switch between the two Unos.

EDIt: It appears that the problem was between 2 Ethernet 2 shields - don't know if that applies to you but either way testing with switch linking the two should be easy enough. Are you using a straight through or crossover cable when linking directly? You may need a crossover cable but testing witha switch first would be the first step.

Ya I was kind of figuring that was the problem, unfortunately the way in which I plan on implementing everything in this project will not allow me to use a switch or router. Eventually the server UNO will be replaced by a MEGA running as the server and managing a custom POE switch so the MEGA itself will need to handle negotiation. Since I'm not a network expert and have no clue how to get the server UNO to negotiate with the client I thought I'd post here.

byte mac[] = {0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x01};

Both boards have the same mac address. You should change them to match the sticker on the board or at least change one to not match the other Ethernet uses this address in arp

I can't believe I missed that :o I must have forgotten to change the MAC on the client lol I did the ol copy pasta from the server code after testing the server with python on my PC thanks a bunch for this! On the note of MAC addresses, the Ethernet shields I have are cheap SunFounder ones and don't have any sticker with a MAC address on them, is there a MAC assigned to the shield when it's manufactured that I can find or do I just make one up and hope that it isn't the same as another on the network?

skjodo: do I just make one up and hope that it isn't the same as another on the network?

Yes. If you pick a random 12-digit hexadecimal number, there is a very, very small chance that it will conflict with any other MAC address on your LAN. https://www.browserling.com/tools/random-mac {0xfb, 0x7d, 0x3c, 0xaa, 0x86, 0x79}; {0x9b, 0xd0, 0xbf, 0x47, 0x32, 0x9b};

Juraj: set static IP address. good values are IP 192.168.1.x use Ethernet.begin(mac, ip)

some Ethernet shields can do automatic 'crossing' but it is best to use cross cable for direct connection

It is a great answer. And additionally, I think It also need to set the gateway IP is the address of peer device. Some useful links:

You don't need to set a gateway IP if both are on the same subnet. If they are on different subnets, then you would need the router at that point.

What kind of sailboat?

-jim lee

IoT_hobbyist: And additionally, I think It also need to set the gateway IP is the address of peer device. Some useful links:

the Ethernet library sets the other values of static IP settings to good defaults for direct connection https://github.com/arduino-libraries/Ethernet/blob/master/src/Ethernet.cpp#L57

Topics moved and merged

Please do not start new topics on the same subject.

If you want a topic moved then ask a moderator

There is a DHCP server available for Arduino https://github.com/pkulchenko/DHCPLite never tried it, but may help you if you are going to have more than just the 2 or 3 nodes. I haven't checked to see if there are any alternative DHCP servers.

countrypaul: There is a DHCP server available for Arduino https://github.com/pkulchenko/DHCPLite never tried it, but may help you if you are going to have more than just the 2 or 3 nodes. I haven't checked to see if there are any alternative DHCP servers.

I considered using this library but was using UNOs and didn't really have room with the rest of the logic for the project. I just got a MEGA to use as the server though so I'll most likely be looking into this as I do plan on having this be scalable to a relatively large number of connected devices and intend the entire system to be essentially "Plug-and-Play". Currently reverse engineering an unmanaged switch to turn it into a PoE switch that is managed by the MEGA XD

countrypaul: There is a DHCP server available for Arduino https://github.com/pkulchenko/DHCPLite never tried it, but may help you if you are going to have more than just the 2 or 3 nodes. I haven't checked to see if there are any alternative DHCP servers.

I checked out the DHCP server you linked however I'm having trouble getting it implemented. I know I need it as the devices need to be plug-and-play and the server should be able to handle up to 32 of them but as I'm not a networking guy I'm a little out of my breadth here. To be honest I'm surprised that there isn't an official DHCP library for Arduino given how many projects end up utilizing internet or a private network in some way.

To be honest I'm surprised that there isn't an official DHCP library for Arduino given how many projects end up utilizing internet or a private network in some way.

What would you want/need an DHCP library to do ?

Using the Internet or a private network would normally use a router which will have a DHCP server to allocate IP addresses

You're right, normally you would be able to take advantage of the DHCP server in the router and be done with it however in my project the amount of hardware that can be deployed is limited so the main server, running on a MEGA2560, is connected to an unmanaged PoE switch and will have to do the DHCP management so that the connected devices can be "Plug-and-Play" in their design. A network communication interface has already been implemented for the connected devices and the server however the "Plug-and-Play" functionality basically requires DHCP since different connected devices will be added and removed on a regular basis.

I've been making some serious progress however in implementing DHCP on the server thanks to the DHCPLite library however it currently assigns the same IP to every connected device, which obviously causes issues, so I've started writing my own however the process of assigning a lease to a device is still confusing, namely how to structure the lease so that it conforms to the DHCP message format.