UDP writing to IP address- ESP32

Hi, I’m struggling to find out how to write a code that sends a message via UDP to a specific IP address on my home network.
I’m essentially looking to send UDP packet to a light fitting. I’ve proved it working through command prompts on Windows but failing with any code I try through the ESP32.
I’ve tried WIFIUDP library but this requires the IP address to message the ESP32 before it can send a packet back.
I think it might be AsyncUDP but can’t work out the code. Can anyone help?

I assume your light fitting is connected to your local WiFi network
set board to Tools>Board>ESP32 Dev Module
try File>Examples>WiFi>WiFiUDPclient
you need to enter your WiFi SSID and password then it can send UDP datagrams to the remote IP

have you looked at AsyncUdp.h

Hi Horace, thanks very much for your response. Yes, the fitting is on the local WiFi network. I've been doing as you mentioned and struggling to get it working. I believe the issue is that WiFiUDP can only UDP server or broadcast address - that's what's mentioned in the example text and consistent with what I'm seeing on Wireshark entries. Wireshark shows the chip doing an ARP request - "Who has 192.168.1.XXX? Tell 192.168.1.YYY" where XXX is the device I'm trying to send UDP packet to (the IP address I enter in the example code) and YYY is the ESP32 IP address.

Through reading I believe ASyncUDP allows a one way transmission which is what I'm looking for - but my issue is I don't know what that code would look like and don't know what the ASyncUDP commands are. Let me know if any ideas :slight_smile:

Hi gcjr - thanks very much for the link. I was thinking to use that but struggling to work out what it all means and how to translate into useable code? For my understanding, is that the library code itself - i.e. when you load in the library AsyncUdp.h, that is the code that gets loaded and the code you then enter in works with that library code to provide the desired effect?

The ASyncUDP library has examples showing how to use it. And, it's source code is available on your computer so you can look at it to see for yourself what its functions are.

the library has functions to send/received UDP messages

a grep of my usage

AsyncUDP udp;
// https://arduino.clanweb.eu/udp-control-esp32.php?lang=en
    if (udp.listen (port)) {
        udp.onPacket ([] (AsyncUDPPacket packet) {
    WiFi.mode (WIFI_STA);
    WiFi.mode (WIFI_OFF);
                WiFi.encryptionType (i) == WIFI_AUTH_OPEN ? "open" : "locked");
    udp.broadcast (msg);

Thanks gfvalvo - the issue for me is I don't know how to read the code in the library. For example - this is written which seems like it will send a message to a specific IP address and port (which is what I'm trying to do) but I can't work out the syntax
size_t sendTo(AsyncUDPMessage &message, const ip_addr_t *addr, uint16_t port, tcpip_adapter_if_t tcpip_if = TCPIP_ADAPTER_IF_MAX);

I'm trying the following for example.... udp.sendTo(AsyncUDPMessage hello, IPAddress("192.168.1.198"), 38899);

But can't get anywhere with it....

Thanks gcjr - in your example, where do I put the IP address and the text I'm trying to send as a packet to the specific device?

see the asyncUdp examples. I sent broadcast msgs

If you want to send unicast instead of broadcast messages, it's probably easiest to use:

size_t writeTo(const uint8_t *data, size_t len, const IPAddress addr, uint16_t port, tcpip_adapter_if_t tcpip_if = TCPIP_ADAPTER_IF_MAX);

You need to supply the arguments:

  • data - a pointer to your data
  • len - length of your data in bytes
  • addr - IP Address where data is to be sent, of type IPAddress
  • port - port where data is to be sent

You don't need to supply the last argument, just let the compiler use its default value.

Hi, sorry to be a pain on this but still no joy - here is my code - this still leads to an ARP call who has 192.168.1.XXX tell 192.168.1.YYY.

#include "WiFi.h"
#include "AsyncUDP.h"
#include "arduino.h"

const char *ssid = "XXXX";
const char *password = "XXXX";
IPAddress ipadd = IPAddress(192, 168, 1, 198);
uint16_t udpPort = 38899;
char *datatx1 = "HELLO 1";

AsyncUDP udp;

void setup() {
    // Setup serial port
  Serial.begin(115200);
  Serial.println();

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.print("Connecting to ");
  Serial.println(ssid);
  while (WiFi.status() != WL_CONNECTED) 
  {
    delay(500);
    Serial.print(".");
    }
}

void loop() {
  udp.writeTo((uint8_t *)datatx1, strlen(datatx1), ipadd, udpPort);
}

Do the UDP packets show up at the destination?

This code is very similar to yours and I see the UDP packets with Wireshark running on the target PC. It has the option of sending the packets two different ways. As is, it will use udp.sendTo(). If you comment out the line: #define USE_AsyncUDPMessage, then it will use udp.writeTo(). Both ways work for me. If the UDP packets aren't getting through for you, perhaps they're being blocked by your router / firewall. Also I'll bet your code is overrunning buffers or dropping some packets because you're trying to send them as fast as the loop() function will run. Add a little delay.

#include "Arduino.h"
#include "WiFi.h"
#include "AsyncUDP.h"

AsyncUDP udp;

void setup() {
	const char ssid[] {"xxxxxx"};
	const char password[] {"yyyyyy"};
	uint8_t retryTest {0};

	Serial.begin(115200);
	delay(2000);
	Serial.println("Starting");

	if (WiFi.status() != WL_CONNECTED) {
		while (WiFi.status() != WL_CONNECTED) {
			if (retryTest == 0) {
				WiFi.disconnect();
				WiFi.begin(ssid, password);
				retryTest = 5;
			} else {
				log_i("Waiting for WiFi Connection");
				retryTest--;
				delay(1000);
			}
		}
	}

	Serial.print("Got IP Address: ");
	Serial.println(WiFi.localIP());
}

void loop() {
#define USE_AsyncUDPMessage
	static const IPAddress destinationIp {192, 168, 10, 241};
	static const uint16_t port(1234);
	static uint32_t counter {0};

	Serial.printf("Sending: %lu\n", counter);

#ifdef USE_AsyncUDPMessage
	AsyncUDPMessage udpMessage;
	udpMessage.printf("Hello World: %lu", counter++);
	udp.sendTo(udpMessage, destinationIp, port);
#else
	char charMessage[22];
	sprintf(charMessage, "Hello World: %ul", counter++);
	udp.writeTo(reinterpret_cast<uint8_t*>(charMessage), strlen(charMessage), destinationIp, port);
#endif

	delay(2000);
}