ESP32 AsyncUDP Library – broadcast()

Home / References / ESP32 Library / AsyncUDP Library

Description

The broadcast() method is used to send UDP packets to all devices on the local network using the broadcast address. This method transmits data to the special broadcast IP address (255.255.255.255), which allows all devices on the same network segment to receive the packet simultaneously. The method requires that the AsyncUDP object has been previously bound to a local port using the listen() method, as it uses the local port number as the destination port for the broadcast transmission.

This is particularly useful for network discovery protocols, service announcements, device enumeration, and group messaging applications where you need to communicate with all devices on the network without knowing their specific IP addresses. The broadcast packets are automatically handled by the network infrastructure and delivered to all devices within the broadcast domain, making it an efficient way to disseminate information across the entire local network.

This page is part of the Comprehensive Guide to the ESP32 Arduino Core Library, accessible on AvantMaker.com.

Syntax and Usage

The broadcast() method has two overloaded versions:

Broadcast raw data: 

size_t sentBytes = udp.broadcast(data, length)

Broadcasts raw byte data to all devices on the network.

Broadcast string data: 

size_t sentBytes = udp.broadcast(message)

Broadcasts a null-terminated string to all devices on the network.

Arguments

  • data (uint8_t*) – Pointer to the raw byte data to be broadcast. Must be valid memory containing the data to send.
  • length (size_t) – The number of bytes to broadcast from the data buffer. Maximum size is limited by CONFIG_TCP_MSS.
  • message (const char*) – Null-terminated string to broadcast. The method automatically calculates the string length using strlen().

For more ESP32 development resources and tutorials, visit the All About ESP32 Resources Hub on  AvantMaker.com

Return Value

The broadcast() method returns a size_t value indicating the number of bytes actually sent in the broadcast transmission. It returns the exact number of bytes transmitted if the broadcast was successful, allowing you to verify that all intended data was sent. It returns 0 if the broadcast failed due to various reasons such as the UDP object not being bound to a local port, network interface errors, insufficient memory for packet buffers, or network connectivity issues. Note that the method requires the AsyncUDP object to have been previously bound to a local port using the listen() method, as it uses the local port number as the destination port for the broadcast. You can use the lastErr() method to get more detailed error information if the broadcast fails.

Example Code

Network Discovery and Service Announcement System

This example demonstrates how to use the broadcast() method to create a comprehensive network discovery and service announcement system. The device periodically broadcasts its presence and services to all devices on the network, listens for discovery requests from other devices, and maintains a registry of discovered devices. This creates a dynamic network where devices can automatically find and communicate with each other without manual configuration.

How to use this example: Upload this code to your ESP32 and replace the WiFi credentials. The device will automatically start broadcasting its presence and services to the network every 30 seconds. Other devices running the same code will discover each other and display information about available services. The system responds to discovery requests and maintains a list of active devices on the network. Monitor the Serial output to see broadcast transmissions, device discoveries, and network statistics.

Testing with Multiple Devices: This broadcast example works best with multiple ESP32 devices on the same network. Each device will announce its presence and discover other devices automatically. You can modify the services and data each device broadcasts to create a distributed IoT system where devices can find and communicate with specific services they need.

Setup Instructions for Multi-Device Testing:

  1. Multiple Device Setup: Upload this code to multiple ESP32 devices on the same WiFi network. Each device will get a unique device ID based on its MAC address.
  2. Network Discovery: All devices will automatically discover each other through periodic broadcast announcements and maintain a registry of available devices and services.
  3. Service Communication: Devices can request specific services from other devices by sending targeted broadcast messages, creating a self-organizing IoT network.
/*
 * Author: Avant Maker
 * Date: June 18, 2025
 * Version: 1.0
 * License: MIT 
 * 
 * Description: 
 * This example demonstrates how to use the broadcast() method to create a
 * comprehensive network discovery and service announcement system. The device
 * periodically broadcasts its presence and services to all devices on the
 * network, listens for discovery requests from other devices, and maintains
 * a registry of discovered devices. This creates a dynamic network where
 * devices can automatically find and communicate with each other.
 *
 * How to use this example:
 * Upload this code to your ESP32 and replace the WiFi credentials. The device
 * will automatically start broadcasting its presence and services to the
 * network. Other devices running the same code will discover each other and
 * display information about available services. The system responds to
 * discovery requests and maintains a list of active devices on the network.
 *
 * Code Source:
 * This example code is sourced from the Comprehensive Guide
 * to the ESP32 Arduino Core Library, accessible on AvantMaker.com.
 * For additional code examples and in-depth documentation related to
 * the ESP32 Arduino Core Library, please visit:
 *
 * https://avantmaker.com/home/all-about-esp32-arduino-core-library/
 *
 * AvantMaker.com, your premier destination for all things
 * DIY, AI, IoT, Smart Home, and STEM projects. We are dedicated
 * to empowering makers, learners, and enthusiasts with
 * the resources they need to bring their innovative ideas to life.
 */

#include <WiFi.h>
#include <AsyncUDP.h>
#include <ArduinoJson.h>

// WiFi credentials
const char* ssid = "your_SSID";          // Replace with your Wi-Fi SSID
const char* password = "your_PASSWORD";  // Replace with your Wi-Fi password

// Broadcast configuration
const uint16_t broadcastPort = 8888;
const unsigned long broadcastInterval = 30000;  // Broadcast every 30 seconds
const unsigned long cleanupInterval = 60000;    // Cleanup old devices every 60 seconds

AsyncUDP udp;

// Device information structure
struct DeviceInfo {
  String deviceId;
  String deviceName;
  IPAddress ipAddress;
  String services;
  String capabilities;
  unsigned long lastSeen;
  bool isActive;
};

// System configuration and state
struct SystemState {
  String deviceId;
  String deviceName;
  String services;
  String capabilities;
  unsigned long systemStartTime = 0;
  unsigned long lastBroadcast = 0;
  unsigned long lastCleanup = 0;
  unsigned long totalBroadcastsSent = 0;
  unsigned long totalBroadcastsReceived = 0;
  unsigned long totalDevicesDiscovered = 0;
} state;

// Discovered devices registry
DeviceInfo discoveredDevices[10];
int deviceCount = 0;
const int maxDevices = sizeof(discoveredDevices) / sizeof(discoveredDevices[0]);

void setup() {
  Serial.begin(115200);
  Serial.println("Starting ESP32 Network Discovery and Service Announcement System...");
  
  // Initialize device information
  state.deviceId = "ESP32_" + String((uint32_t)ESP.getEfuseMac(), HEX);
  state.deviceName = "IoT Device " + String((uint32_t)ESP.getEfuseMac() & 0xFFFF, HEX);
  state.services = "temperature,humidity,status,control";
  state.capabilities = "sensor_data,remote_control,status_reporting";
  
  Serial.print("Device ID: ");
  Serial.println(state.deviceId);
  Serial.print("Device Name: ");
  Serial.println(state.deviceName);
  Serial.print("Services: ");
  Serial.println(state.services);
  Serial.print("Capabilities: ");
  Serial.println(state.capabilities);
  
  // Initialize WiFi
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  
  Serial.print("Connecting to WiFi");
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
  }
  Serial.println();
  Serial.println("WiFi connected successfully!");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
  Serial.print("Signal strength: ");
  Serial.print(WiFi.RSSI());
  Serial.println(" dBm");
  
  // Initialize UDP for broadcast communication
  if (udp.listen(broadcastPort)) {
    Serial.print("✅ UDP broadcast system initialized on port ");
    Serial.println(broadcastPort);
    
    // Set up packet handler for incoming broadcasts
    udp.onPacket([](AsyncUDPPacket packet) {
      handleIncomingBroadcast(packet);
    });
    
  } else {
    Serial.println("❌ Failed to initialize UDP broadcast system");
    Serial.print("Error code: ");
    Serial.println(udp.lastErr());
  }
  
  state.systemStartTime = millis();
  
  // Send initial broadcast announcement
  sendServiceAnnouncement();
}

void sendServiceAnnouncement() {
  Serial.println("📡 === Broadcasting Service Announcement ===");
  
  // Create JSON announcement message
  StaticJsonDocument<512> announcement;
  announcement["type"] = "service_announcement";
  announcement["device_id"] = state.deviceId;
  announcement["device_name"] = state.deviceName;
  announcement["ip_address"] = WiFi.localIP().toString();
  announcement["services"] = state.services;
  announcement["capabilities"] = state.capabilities;
  announcement["uptime"] = millis() - state.systemStartTime;
  announcement["timestamp"] = millis();
  announcement["signal_strength"] = WiFi.RSSI();
  
  String message;
  serializeJson(announcement, message);
  
  // Send broadcast using broadcast() method
  size_t sentBytes = udp.broadcast(message.c_str());
  if (sentBytes > 0) {
    state.totalBroadcastsSent++;
    state.lastBroadcast = millis();
    
    Serial.print("✅ Service announcement broadcasted successfully");
    Serial.print(" - Sent ");
    Serial.print(sentBytes);
    Serial.println(" bytes");
    Serial.print("Message: ");
    Serial.println(message);
  } else {
    Serial.println("❌ Failed to broadcast service announcement");
    Serial.print("Error code: ");
    Serial.println(udp.lastErr());
  }
}

void sendDiscoveryRequest() {
  Serial.println("🔍 === Broadcasting Discovery Request ===");
  
  // Create JSON discovery request
  StaticJsonDocument<256> request;
  request["type"] = "discovery_request";
  request["device_id"] = state.deviceId;
  request["timestamp"] = millis();
  request["requesting_services"] = "all";
  
  String message;
  serializeJson(request, message);
  
  // Send broadcast discovery request
  size_t sentBytes = udp.broadcast(message.c_str());
  if (sentBytes > 0) {
    state.totalBroadcastsSent++;
    Serial.print("✅ Discovery request broadcasted - Sent ");
    Serial.print(sentBytes);
    Serial.println(" bytes");
  } else {
    Serial.println("❌ Failed to broadcast discovery request");
  }
}

void handleIncomingBroadcast(AsyncUDPPacket packet) {
  state.totalBroadcastsReceived++;
  
  Serial.println("📥 === Received Broadcast Message ===");
  Serial.print("From: ");
  Serial.print(packet.remoteIP());
  Serial.print(":");
  Serial.println(packet.remotePort());
  Serial.print("Length: ");
  Serial.print(packet.length());
  Serial.println(" bytes");
  
  // Parse JSON message
  String receivedMessage;
  receivedMessage.reserve(packet.length());
  for (int i = 0; i < packet.length(); i++) {
    receivedMessage += (char)packet.data()[i];
  }
  
  Serial.print("Message: ");
  Serial.println(receivedMessage);
  
  StaticJsonDocument<512> doc;
  DeserializationError error = deserializeJson(doc, receivedMessage);
  
  if (error) {
    Serial.print("❌ JSON parsing failed: ");
    Serial.println(error.c_str());
    return;
  }
  
  String messageType = doc["type"];
  String senderId = doc["device_id"];
  
  // Ignore messages from self
  if (senderId == state.deviceId) {
    Serial.println("⚠️  Ignoring message from self");
    return;
  }
  
  if (messageType == "service_announcement") {
    handleServiceAnnouncement(doc, packet.remoteIP());
  } else if (messageType == "discovery_request") {
    handleDiscoveryRequest(doc, packet.remoteIP());
  } else if (messageType == "discovery_response") {
    handleDiscoveryResponse(doc, packet.remoteIP());
  } else {
    Serial.print("⚠️  Unknown message type: ");
    Serial.println(messageType);
  }
  
  Serial.println("=== End Broadcast Message ===");
}

void handleServiceAnnouncement(JsonDocument& doc, IPAddress senderIP) {
  Serial.println("🎯 Processing Service Announcement");
  
  String deviceId = doc["device_id"];
  String deviceName = doc["device_name"];
  String services = doc["services"];
  String capabilities = doc["capabilities"];
  
  // Add or update device in registry
  updateDeviceRegistry(deviceId, deviceName, senderIP, services, capabilities);
  
  Serial.print("📋 Device registered: ");
  Serial.print(deviceName);
  Serial.print(" (");
  Serial.print(deviceId);
  Serial.println(")");
}

void handleDiscoveryRequest(JsonDocument& doc, IPAddress senderIP) {
  Serial.println("🔍 Processing Discovery Request");
  
  // Respond to discovery request with our service announcement
  delay(random(100, 1000));  // Random delay to avoid collision
  sendServiceAnnouncement();
}

void handleDiscoveryResponse(JsonDocument& doc, IPAddress senderIP) {
  Serial.println("📬 Processing Discovery Response");
  handleServiceAnnouncement(doc, senderIP);  // Same as service announcement
}

void updateDeviceRegistry(String deviceId, String deviceName, IPAddress ip, String services, String capabilities) {
  // Check if device already exists
  for (int i = 0; i < deviceCount; i++) {
    if (discoveredDevices[i].deviceId == deviceId) {
      // Update existing device
      discoveredDevices[i].deviceName = deviceName;
      discoveredDevices[i].ipAddress = ip;
      discoveredDevices[i].services = services;
      discoveredDevices[i].capabilities = capabilities;
      discoveredDevices[i].lastSeen = millis();
      discoveredDevices[i].isActive = true;
      return;
    }
  }
  
  // Add new device if space available
  if (deviceCount < maxDevices) {
    discoveredDevices[deviceCount].deviceId = deviceId;
    discoveredDevices[deviceCount].deviceName = deviceName;
    discoveredDevices[deviceCount].ipAddress = ip;
    discoveredDevices[deviceCount].services = services;
    discoveredDevices[deviceCount].capabilities = capabilities;
    discoveredDevices[deviceCount].lastSeen = millis();
    discoveredDevices[deviceCount].isActive = true;
    deviceCount++;
    state.totalDevicesDiscovered++;
    
    Serial.print("✅ New device added to registry: ");
    Serial.println(deviceName);
  } else {
    Serial.println("⚠️  Device registry is full, cannot add new device");
  }
}

void cleanupInactiveDevices() {
  unsigned long currentTime = millis();
  unsigned long timeout = 120000; // 2 minutes timeout
  
  for (int i = 0; i < deviceCount; i++) {
    if (currentTime - discoveredDevices[i].lastSeen > timeout) {
      discoveredDevices[i].isActive = false;
      Serial.print("⏰ Device marked as inactive: ");
      Serial.println(discoveredDevices[i].deviceName);
    }
  }
}

void printNetworkStatus() {
  Serial.println("📊 === Network Discovery Status ===");
  Serial.print("System Uptime: ");
  Serial.print((millis() - state.systemStartTime) / 1000);
  Serial.println(" seconds");
  Serial.print("Total Broadcasts Sent: ");
  Serial.println(state.totalBroadcastsSent);
  Serial.print("Total Broadcasts Received: ");
  Serial.println(state.totalBroadcastsReceived);
  Serial.print("Total Devices Discovered: ");
  Serial.println(state.totalDevicesDiscovered);
  Serial.print("Active Devices: ");
  
  int activeCount = 0;
  for (int i = 0; i < deviceCount; i++) {
    if (discoveredDevices[i].isActive) {
      activeCount++;
    }
  }
  Serial.println(activeCount);
  
  Serial.println("=== Discovered Devices ===");
  for (int i = 0; i < deviceCount; i++) {
    if (discoveredDevices[i].isActive) {
      Serial.print("Device: ");
      Serial.print(discoveredDevices[i].deviceName);
      Serial.print(" (");
      Serial.print(discoveredDevices[i].deviceId);
      Serial.println(")");
      Serial.print("  IP: ");
      Serial.println(discoveredDevices[i].ipAddress);
      Serial.print("  Services: ");
      Serial.println(discoveredDevices[i].services);
      Serial.print("  Capabilities: ");
      Serial.println(discoveredDevices[i].capabilities);
      Serial.print("  Last Seen: ");
      Serial.print((millis() - discoveredDevices[i].lastSeen) / 1000);
      Serial.println(" seconds ago");
    }
  }
  
  Serial.print("WiFi Signal: ");
  Serial.print(WiFi.RSSI());
  Serial.println(" dBm");
  Serial.print("Free Heap: ");
  Serial.print(ESP.getFreeHeap());
  Serial.println(" bytes");
  Serial.println("================================");
}

void loop() {
  unsigned long currentTime = millis();
  
  // Send periodic service announcements
  if (currentTime - state.lastBroadcast >= broadcastInterval) {
    sendServiceAnnouncement();
  }
  
  // Cleanup inactive devices periodically
  if (currentTime - state.lastCleanup >= cleanupInterval) {
    state.lastCleanup = currentTime;
    cleanupInactiveDevices();
    printNetworkStatus();
  }
  
  // Send discovery request every 2 minutes
  static unsigned long lastDiscovery = 0;
  if (currentTime - lastDiscovery >= 120000) {
    lastDiscovery = currentTime;
    sendDiscoveryRequest();
  }
  
  // Monitor WiFi connection
  if (WiFi.status() != WL_CONNECTED) {
    Serial.println("⚠️  WiFi connection lost! Attempting reconnection...");
    WiFi.reconnect();
    delay(5000);
  }
  
  // Small delay to prevent overwhelming the system
  delay(100);
}

ESP32 Library Index

ESP32 Arduino Core Library


FAQ

Ready to experiment and explore more about ESP32? Visit our website’s All About ESP32 Resources Hub, packed with tutorials, guides, and tools to inspire your maker journey. Experiment, explore, and elevate your skills with everything you need to master this powerful microcontroller platform!

error: Content is protected !!