AdafruitUDP makes it easy to work with raw UDP sockets. It includes a convenient callback for incoming data, and a number of helper functions to read and write data over a UDP socket.

You're free to 'poll' for incoming data and connection status, but the 'data received' callback fires whenever incoming data is available,  which can then be read via the .read() and related commands. Callbacks aren't mandatory, but help keep your code easy to understand and more maintainable as your project grows in complexity.

UDP Socket API

The AdafruitUDP class includes the following functions:

// UDP API
virtual uint8_t   begin       (uint16_t port);
virtual void      stop        (void);
virtual int       beginPacket (IPAddress ip, uint16_t port);
virtual int       beginPacket (const char *host, uint16_t port);
virtual int       endPacket   (void);
virtual int       parsePacket (void);
virtual IPAddress remoteIP    (void);
virtual uint16_t  remotePort  (void);

// Stream API
virtual int       read        (void);
virtual int       read        (unsigned char* buffer, size_t len);
virtual int       read        (char* buffer, size_t len);
virtual int       peek        (void);
virtual int       available   (void);
virtual void      flush       (void);
virtual size_t    write       (uint8_t byte);
virtual size_t    write       (const uint8_t *buffer, size_t size);

// Callback
void setReceivedCallback (udpcallback_t fp);

UDP API

The following functions are primarilly based on the Arduino EthernetUDP class and enable you to work with UDP connections and packets.

uint8_t begin (uint16_t port)

Initialises the AdafruitUDP class for the specified local port.

Parameters:

  • port: The local port number to listen on (0..65535)

Returns: 1 if successful, 0 if there are no sockets available to be used.

void stop (void)

Disconnects from the UDP server, and releases any resources used during the UDP session.

Parameters: None

Returns: Nothing

int beginPacket (IPAddress ip, uint16_t port)

Starts a UDP connection to write data to the specified remote IP address and port.

Parameters:

  • ip: The remote IPAddress where the UDP server is located
  • port: The remote port number to connect to (0..65535)

Returns: '1' if successful, '0' if there was a problem connecting to the specified IP address or port.

int beginPacket (const char *host, uint16_t port)

Starts a UDP connection to write data to the specified domain name and remote port.

Parameters:

  • host: A string containing the domain name to connect to
  • port: The port number to connect to (0..65536)

Returns: '1' if the connection was successfully established, otherwise '0'.

int endPacket (void)

This function must be called after writing UDP data to the remote server.

Parameters: None

Returns: '1' if the packet was sent successfully, otherwise '0'.

int parsePacket (void)

Checks whether a UDP packet is available, and returns the size of the UDP packet as a return value.

You must call this function BEFORE reading any data from the buffer via AdafruitUDP.read()!

Parameters: None

Returns: The number of bytes available in the buffered UDP packet.

IPAddress remoteIP (void)

Returns the IP address of the remote UDP server.

AdafruitUDP.parsePacket() must be called BEFORE this function.

Parameters: None

Returns: The IPAddress of the remote UDP server/connection.

uint16_t remotePort (void)

Returns the port for the remote UDP server.

AdafruitUDP.parsePacket() must be called BEFORE this function.

Parameters: None

Returns: The port of the remote UDP server/connection.

Stream API

The following functions are based on the Stream class that Arduino EthernetUDP implements.

int read (void)

Reads the first available byte in the UDP buffer.

This function must be called AFTER AdafruitUDP.parsePacket()!

Parameters: None

Returns: The first character available in the UDP buffer, or 'EOF' if no data is available.

int read (unsigned char* buffer, size_t len)
int read (char* buffer, size_t len)

These two identical functions (other than the type used for the 'buffer') will read up to 'len' bytes from the UDP response data, copying them into the buffer provided in the first argument of this function.

This function must be called AFTER AdafruitUDP.parsePacket()!

Parameters:

  • buffer: A pointer to the buffer where the UDP data will be copied
  • len: The maximum number of bytes to read

Returns:

  • The actual number of bytes read from the UDP data and copied into 'buffer'
  • '0' if no data was read or available
  • '-1' if an error occured

int peek (void)

Reads a single byte from the UDP response buffer without advancing to the next position in the buffer.

This function must be called AFTER AdafruitUDP.parsePacket()!

Parameters: None

Returns: The first byte available in the UDP buffer, or '-1' if no data is available.

int available (void)

Returns the number of bytes available to be read in the UDP buffer.

This function must be called AFTER AdafruitUDP.parsePacket()!

Parameters: None

Returns: The number of bytes available to be read in the UDP buffer, otherwise '0' if the read buffer is empty.

void flush (void)

This function will flush the buffer of any outgoing data, and return when the buffered data has been sent and the buffer is empty.

Parameters: None

Returns: Nothing

size_t write (uint8_t byte)

Writes a single byte to the remote UDP server.  This function must be placed after AdafruitUDP.beginPacket() and before AdafruitUDP.endPacket().  The packet will not be sent until .endPacket is called!

Parameters:

  • byte: The single byte to write to the transmit buffer

Returns: The number of bytes written.

size_t write (const uint8_t *buffer, size_t size)

Writes the specified 'buffer' to the remote UDP server.  This function must be placed after AdafruitUDP.beginPacket() and before AdafruitUDP.endPacket().  The packet will not be sent until .endPacket is called!

Parameters:

  • buffer: The buffer where the data to transmit is stored
  • size: The number of bytes contained in 'buffer'

Returns: The number of bytes written.

Callback Handlers

AdafruitUDP supports a 'read' callback that will fire every time incoming UDP data is recieved over the open socket connection.

The callback function has the following signature (although you are free to choose a different name if you wish to):

void received_callback(void);

Before you can use the callback function, you need to register your callback handler (using the function signature in the paragraph above).

You register the callback with the following function:

void setReceivedCallback (udpcallback_t fp)

Registers the function used to process 'data received' callbacks.

Parameters:

  • fp: The name of the function where callback events should be redirected to

Returns: Nothing

See the example section at the bottom of this page for details on using the data received callback in the real world.

Examples

The examples below illustration some basic UDP concepts to help you understand the class described above.

UDP Echo Server

The following example will listen on port 8888 for any incoming UDP requests, and then echo them back to the requesting device via the 'received' callback handler:

#include <adafruit_feather.h>

#define WLAN_SSID            "yourSSID"
#define WLAN_PASS            "yourPass"

#define LOCAL_PORT           8888

AdafruitUDP udp;

char packetBuffer[255];

bool connectAP(void)
{
  // Attempt to connect to an AP
  Serial.print("Attempting to connect to: ");
  Serial.println(WLAN_SSID);

  if ( Feather.connect(WLAN_SSID, WLAN_PASS) )
  {
    Serial.println("Connected!");
  }
  else
  {
    Serial.printf("Failed! %s (%d)", Feather.errstr(), Feather.errno());
    Serial.println();
  }
  Serial.println();

  return Feather.connected();
}

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

  // wait for Serial port to connect. Needed for native USB port only
  while (!Serial) delay(1);

  Serial.println("UDP Echo Callback Example");
  Serial.println();

  while( !connectAP() )
  {
    delay(500);
  }

  // Tell the UDP client to auto print error codes and halt on errors
  udp.err_actions(true, true);
  udp.setReceivedCallback(received_callback);

  Serial.printf("Openning UDP at port %d ... ", LOCAL_PORT);
  udp.begin(LOCAL_PORT);
  Serial.println("OK");

  Serial.println("Please use your PC/mobile and send any text to ");
  Serial.print( IPAddress(Feather.localIP()) );
  Serial.print(" UDP port ");
  Serial.println(LOCAL_PORT);
}

void loop()
{

}

/**************************************************************************/
/*!
    @brief  Received something from the UDP port
*/
/**************************************************************************/
void received_callback(void)
{
  int packetSize = udp.parsePacket();

  if ( packetSize )
  {
    // Print out the contents with remote information
    Serial.printf("Received %d bytes from ", packetSize);
    Serial.print( IPAddress(udp.remoteIP()) );
    Serial.print( " : ");
    Serial.println( udp.remotePort() );

    udp.read(packetBuffer, sizeof(packetBuffer));
    Serial.print("Contents: ");
    Serial.write(packetBuffer, packetSize);
    Serial.println();

    // Echo back contents
    udp.beginPacket(udp.remoteIP(), udp.remotePort());
    udp.write(packetBuffer, packetSize);
    udp.endPacket();
  }
}

This guide was first published on Mar 23, 2016. It was last updated on Mar 23, 2016.

This page (AdafruitUDP) was last updated on Feb 11, 2016.

Text editor powered by tinymce.