We continue with the posts on the ESP8266 and ESP32 by seeing how to establish a connection using the UDP protocol as a speed-focused communication alternative.
We will refer to the ESP8266, but the same code is compatible for the ESP32, adjusting the library names. At the end, you have the code for both the ESP8266 and the ESP32.
We have seen several ways to communicate the ESP8266 with the client. We have seen web forms as a simple (and somewhat obsolete) solution, and the more modern Ajax connections, websockets, and asynchronous websockets.
All these solutions work via HTTP over TCP. But sometimes we forget that UDP communications also exist. Very briefly, let’s remember that UDP (Universal Datagram Protocol) communications do away with some of the packets needed to establish the connection and error verification.
In a UDP communication, the server sends packets without waiting for acknowledgment from the client. If a packet is lost, the client cannot request it to be resent. Therefore, TCP is useful for applications that require communication reliability. While UDP is useful for fast transmissions, even faster than a Websocket.
And in the case of a microprocessor like the ESP8266, a UDP communication fits many cases. Furthermore, UDP communications mean less load for the server as they avoid a good part of the required packets.
For example, if we are sending an animation to a series of LEDs, or controlling a robot’s position. In these cases of “almost continuous” communication, I don’t care as much about acknowledgment, but about speed. If a packet is lost, it will be immediately replaced by the next one.
Code Example
Fortunately, implementing UDP communication on the ESP8266 is very simple thanks to the ‘WiFiUDP.h’ library. Let’s see it with an example.
First, the main program loop looks like this.
We will see that the only relevant points are that we have included the necessary files, and the functions ‘ConnectUDP()’ and ‘GetUDP_Packet()’ that we will see next.
We also have the ‘SendUDP_Packet(“abcde”)’ function commented out, which would illustrate sending a String via UDP. We won’t use it in this example, but it’s there.
#include <ESP8266WiFi.h>
#include <WiFiUDP.h>
#include "config.h" // Replace with your network data
#include "UDP.hpp"
#include "ESP8266_Utils.hpp"
#include "ESP8266_Utils_UDP.hpp"
void setup()
{
Serial.begin(115200);
ConnectWiFi_STA();
ConnectUDP();
}
void loop()
{
GetUDP_Packet();
//SendUDP_Packet("abcde");
}
On the other hand, we have the ‘UDP.hpp’ file, where we have placed all the functions related to UDP in our program.
In this file, we have instantiated a ‘WiFiUDP’ object, the ports on which the connection will operate, and defined the ‘ProcessPacket(String response)’ function that handles the response we want to give to a UDP request.
// UDP variables
WiFiUDP UDP;
unsigned int localPort = 8888;
unsigned int remotePort = 8889;
char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet,
void ProcessPacket(String response)
{
Serial.println(response);
}
Finally, we have the ‘ESP8266_Utils_UDP.hpp’ file where, following the philosophy of this series of posts, we have defined a series of common functions that we can reuse between programs.
Here we have the ‘ConnectUDP()’ function that establishes the UDP connection, the functions ‘SendUDP_ACK()’ that sends an acknowledgment, ‘SendUDP_Packet(String content)’ that sends a String via UDP, and the function ‘GetUDP_Packet(bool sendACK = true)’ that receives a UDP packet and processes it with the function we defined in the previous file.
boolean ConnectUDP() {
Serial.println();
Serial.println("Starting UDP");
// in UDP error, block execution
if (UDP.begin(localPort) != 1)
{
Serial.println("Connection failed");
while (true) { delay(1000); }
}
Serial.println("UDP successful");
}
void SendUDP_ACK()
{
UDP.beginPacket(UDP.remoteIP(), remotePort);
UDP.write("ACK");
UDP.endPacket();
}
void SendUDP_Packet(String content)
{
UDP.beginPacket(UDP.remoteIP(), remotePort);
UDP.write(content.c_str());
UDP.endPacket();
}
void GetUDP_Packet(bool sendACK = true)
{
int packetSize = UDP.parsePacket();
if (packetSize)
{
// read the packet into packetBufffer
UDP.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
Serial.println();
Serial.print("Received packet of size ");
Serial.print(packetSize);
Serial.print(" from ");
Serial.print(UDP.remoteIP());
Serial.print(":");
Serial.println(UDP.remotePort());
Serial.print("Payload: ");
Serial.write((uint8_t*)packetBuffer, (size_t)packetSize);
Serial.println();
ProcessPacket(String(packetBuffer));
//// send a reply, to the IP address and port that sent us the packet we received
if(sendACK) SendUDP_ACK();
}
delay(10);
}
We upload everything to our ESP8266, and we are going to test our UDP communication. For this, we provide two small Python scripts.
The ‘recieveUDP.py’ script that receives a UDP packet and displays it on the screen.
import socket
UDP_PORT = 8889
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(('', UDP_PORT))
while True:
data, addr = sock.recvfrom(1024)
print("received message:")
print(data.decode('utf-8'))
The ‘sendUDP.py’ script file that sends an example packet via UDP.
import socket
UDP_IP = '192.168.43.237'
UDP_PORT = 8888
UDP_PAYLOAD = 'abcdef'
def yes_or_no(question):
reply = str(input(question)).lower().strip()
if reply[0] == 'y':
return 0
elif reply[0] == 'n':
return 1
else:
return yes_or_no("Please Enter (y/n) ")
while True:
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.sendto(bytes(UDP_PAYLOAD, "utf-8"), (UDP_IP, UDP_PORT))
sock.close()
print("UDP target IP:", UDP_IP)
print("UDP target port:", UDP_PORT)
print("message:", UDP_PAYLOAD)
if(yes_or_no('Send again (y/n): ')):
break
except:
pass
Result
We first run ‘recieveUDP.py’, which listens, and then ‘sendUDP.py’. We see in the console that the packet is sent correctly.

In the Arduino serial port, we can check that, indeed, the ESP8266 receives the packet.

Finally, since in the ESP8266 receive function we indicated that we want it to send an ACK signal, we see that the Python script receives the acknowledgment message.
![]()
Everything works correctly! Easy, very useful, and often forgotten, UDP connections are another way to communicate a client with the ESP8266.
Of course, instead of a simple String with “abced”, we will normally work with a JSON file containing the information we want, as we saw in this post.
Precisely, in the next post we will start using JSON files on the ESP8266 to consume a REST API. See you soon!
Download the Code
All the code from this post is available for download on Github.
Version for ESP8266: https://github.com/luisllamasbinaburo/ESP8266-Examples
Version for ESP32: https://github.com/luisllamasbinaburo/ESP32-Examples

