Discover IP using Broadcast

Hey,
I'm new to Networking and currently trying to figure out how I can connect the arduino to a PC (via Ethernet) without knowing it's IP in the first place. In the end this should allow to send input to the arduino aswell as to send data from the arduino to the pc.

My current Idea is to broadcast the IP of the arduino until the PC responds, then the PC transmits its own IP so communication can be established and the broadcast ends. I am thinking about using UDP, but I am not really sure how it works yet.
I found the following topic in the forum that looked promising ( Link) but I am not sure how to choose the correct port for UDP and also not sure if my Approach really makes sense..

Any advice is gladly appreciated (:

If you know the localnet broadcast address, you should be able to implement this.

The 192.168.0.0/24 network broadcast address is 192.168.0.255.

Thanks for the Response.

I already figured out the broadcast address, but I don't know how to figure out the UDP port to send to. Or doesn't it matter?

Do you know by any chance how I can let the PC return it's IP address to the arduino? I found something about a ping command to the broadcast address, but this wasn't in arduino..

I like UDP and ports 5005 or 5006.

With UDP, you can develop your own protocol. Send a packet to the broadcast address with your IP and "request". Have the other device send a packet to the Arduino's IP address with its IP.

What is the other device and OS?

So you mean I can tell the receiver of the broadcast in the request what to send back? I tried looking it up, but could not find any example with arduino.

The other device is a Windows Desktop.

I am NOT a Windows guy, but I will post the basic test code for you for a Ubuntu/Debian OS.

Here is my Arduino code. Change the network settings to yours.

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

// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};

IPAddress ip(192, 168, 1, 2);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);

unsigned int UDPport = 5005;// local port to listen for UDP packets

IPAddress UDPServer(192, 168, 1, 255); // destination device server

const int UDP_PACKET_SIZE = 64;

byte packetBuffer[ UDP_PACKET_SIZE] = "0";

unsigned int noChange = 0;

// A UDP instance to let us send and receive packets over UDP
EthernetUDP Udp;

unsigned long currentTime;
unsigned long secondTime;

unsigned long msPerSecond = 100UL;

int UDPCount = 0;
boolean packetOut = false;

void setup()
{
  Serial.begin(115200);
  
  pinMode(4, OUTPUT);
  digitalWrite(4, HIGH);

  Serial.print(F("Starting w5100..."));

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

/*
  while (!Ethernet.begin(mac)) {
    Serial.println(F("failed. Retrying in 5 seconds."));
    delay(5000);
    Serial.print(F("Starting w5100..."));
  }
*/

  Serial.println(Ethernet.localIP());

  Udp.begin(UDPport);

  delay(2000);

  currentTime = millis();
  secondTime = currentTime;

  Serial.println("Ready");
}



void loop()
{
  currentTime = millis();

  getUDPpacket();

/*
  if (currentTime - secondTime > msPerSecond) {
    byte rtnVal = Ethernet.maintain();
    switch (rtnVal) {
      case 1: Serial.println(F("\r\nDHCP renew fail"));
        break;
      case 2: Serial.println(F("\r\nDHCP renew ok"));
        break;
      case 3: Serial.println(F("\r\nDHCP rebind fail"));
        break;
      case 4: Serial.println(F("\r\nDHCP rebind ok"));
        break;

    }
*/

    Serial.println(F("\r\nUDP send"));
    sendUDPpacket(UDPServer); // send an NTP packet to a time server
    packetOut = true;
    secondTime += msPerSecond;
}

unsigned int udpCount = 0;

// send an NTP request to the time server at the given address
void sendUDPpacket(IPAddress& address)
{
  if(packetOut) Serial.println("Missed packet");
  
  udpCount++;

  // set all bytes in the buffer to 0
  memset(packetBuffer, 0, UDP_PACKET_SIZE);


  sprintf((char*)packetBuffer, "Arduino count %u", udpCount);

  if(Udp.beginPacket(address, UDPport) == 0)
  {
    Serial.println(F("BeginPacket fail"));
    return;
  }

  Udp.write(packetBuffer, UDP_PACKET_SIZE);

  if(Udp.endPacket() == 0)
  {
    Serial.println(F("endPacket fail"));
    return;
  }

  packetOut = true;
}


void getUDPpacket() {
  if ( Udp.parsePacket() ) {
    // We've received a packet, read the data from it

    
    if (Udp.remoteIP() == UDPServer) {
      Serial.print(F("UDP IP OK  "));
    }
    else {
      Serial.print(F("UDP IP Bad "));
      Serial.println(Udp.remoteIP());
//      return;
    }
    if (Udp.remotePort() == UDPport) {
      Serial.println(F("Port OK"));
    }
    else {
      Serial.println(F("Port Bad"));
      return;
    }


    Udp.read(packetBuffer, UDP_PACKET_SIZE); // read the packet into the buffer

    Serial.print(F("Received: "));
    Serial.println((char*)packetBuffer);

    packetOut = false;
  }
}

Here is my Linux code. Works on Ubuntu and RPi.

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <err.h>

int main(int argc, char *argv[]) {

	if(argc < 2) { 
//		if(daemon(0,0) == -1) err(1,NULL);
	}

	int sock, n, nr;
	socklen_t fromlen;
	struct sockaddr_in server;
	struct sockaddr_in from;

	sock = socket(AF_INET, SOCK_DGRAM, 0);
	if (sock < 0)
	printf("Can not create socket in server\n");

	memset(&server, 0, sizeof(struct sockaddr_in));
	server.sin_family = AF_INET;
	server.sin_port = htons(5005);
	server.sin_addr.s_addr = INADDR_ANY;

	if(bind(sock, (struct sockaddr *)&server, sizeof(server)) < 0)
	printf("Can not bind in server!\n");
	memset(&from, 0, sizeof(struct sockaddr_in));
	fromlen = sizeof(struct sockaddr_in);


	while(1) {
		int n, l1;
		unsigned char tBuf[300];
		unsigned char outBuf[300];
//		fflush(stdout);

		n = recvfrom(sock, tBuf, 300, 0, (struct sockaddr*) &from, &fromlen);
		if (n < 0) {
			printf("Can not receive in server!\n");
		}

		printf("%s from IP:%s, Port:%hu\r\n",&tBuf[0],inet_ntoa(from.sin_addr), ntohs(from.sin_port));

		strcpy(outBuf,"127 127 0 0\n\0");
		socklen_t length = sizeof(struct sockaddr_in);	
		n = sendto(sock, tBuf, 64, 0, (const struct sockaddr *)&from, fromlen);
		if(n < 0) {
			printf("Can not send from client");
		}

	}
}

Thank you very much, you've already been very helpful to me! (:

I'll try to implement it tomorrow. Thought I might have some further questions to understand the arduino code.

I wrote all that code, so if you have questions, ask away!