ESP32 AsyncUDP Library – send()

Home / References / ESP32 Library / AsyncUDP Library

Description

The send() method is a specialized data transmission function in the AsyncUDP library that enables ESP32 devices to send UDP packets using the AsyncUDPMessage buffer system. This method is available in both the AsyncUDP class and the AsyncUDPPacket class, providing structured and efficient UDP communication. The method works with pre-constructed message objects that contain the data to be transmitted, offering a higher-level abstraction compared to direct write operations. It’s particularly useful for implementing complex messaging protocols, multi-part data transmission, structured communication systems, IoT data logging, and applications requiring message queuing or buffering. The send() method leverages the AsyncUDPMessage buffer to organize data before transmission, making it ideal for scenarios where you need to construct messages incrementally or when dealing with large amounts of structured data. The method operates asynchronously and integrates seamlessly with ESP32’s FreeRTOS task scheduler, ensuring efficient network communication without blocking the main application loop.

Syntax and Usage

The send() method has two main forms and can be used in different contexts:

AsyncUDP class: 

udp.send(message)

Sends a message buffer to the connected remote endpoint.

AsyncUDPPacket class: 

packet.send(message)

Sends a message buffer back to the packet sender.

For practical applications and examples of this method, please consult the “Example Code” section on this page. This section provides comprehensive guidance to help you better understand and apply the method effectively.

Arguments

The send() method accepts the following argument:

  • message (AsyncUDPMessage&): A reference to an AsyncUDPMessage object containing the data to be transmitted. The message object must be properly constructed and contain valid data before calling send().

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

Return Value

The send() method returns a size_t value indicating the number of bytes successfully transmitted. A return value of 0 indicates that the transmission failed, while a positive value represents the actual number of bytes sent from the message buffer.

For the AsyncUDP class, the method uses the internally stored remote IP address and port from a previous connect() call. For the AsyncUDPPacket class, the method automatically sends the message back to the original sender’s IP address and port.

The method ensures reliable transmission by utilizing the underlying lwIP UDP stack and the AsyncUDPMessage buffer system, providing immediate feedback about transmission success through its return value. The method internally calls the write() function with the message data and length, ensuring consistent behavior across the AsyncUDP library.

Example Code

Simple Example: Message Buffer Sender

This example demonstrates how to use the send() method to transmit data using AsyncUDPMessage buffers. The ESP32 connects to a specified remote endpoint and sends various types of structured messages including text, JSON, binary data, and sensor readings. This demonstrates the practical application of the send() method for IoT communications, data logging, and structured messaging systems that require buffered data transmission.

How to use this example: Upload this code to your ESP32, update the WiFi credentials and remote IP address. The ESP32 will connect to the specified remote endpoint and start sending structured messages every 5 seconds. Use the companion receiver example (provided below) on another ESP32 or computer to see the transmitted data.

/*
 * Author: Avant Maker
 * Date: January 15, 2025
 * Version: 1.0
 * License: MIT
 * 
 * Description: 
 * Message Buffer Sender that demonstrates send() method usage for transmitting
 * structured data using AsyncUDPMessage buffers to a remote UDP endpoint.
 * This example shows how to create, populate, and send message buffers containing
 * different data types including text, JSON, binary data, and sensor readings.
 * It demonstrates practical IoT communication patterns and real-world applications
 * of structured UDP data transmission using the AsyncUDP library.
 *
 * Features Demonstrated:
 * - AsyncUDPMessage buffer creation and management
 * - Structured data transmission using send() method
 * - Multiple message format transmission (text, JSON, binary, sensor data)
 * - Message buffer reuse and optimization
 * - Connection status monitoring and error handling
 * - Automatic reconnection on connection failure
 * - Transmission statistics and buffer utilization monitoring
 * - Memory efficient message handling
 *
 * Hardware Requirements:
 * - ESP32 development board
 * - WiFi network access
 * - Remote UDP server (use companion receiver example)
 *
 * How to use this example:
 * 1. Update WiFi credentials (ssid and password)
 * 2. Update remote IP address and port (remoteIP and remotePort)
 * 3. Upload code to ESP32
 * 4. Use companion receiver example to see transmitted messages
 * 5. Monitor Serial output for transmission status and statistics
 *
 * 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_wifi_ssid";
const char* password = "your_wifi_password";

// Remote server configuration
IPAddress remoteIP(192, 168, 0, 123); // UPDATE: Remote server IP address
const uint16_t remotePort = 8888;      // UPDATE: Remote server port

AsyncUDP udp;
AsyncUDPMessage message(1024); // Create message buffer with 1024 bytes capacity
unsigned long messageCounter = 0;
bool isConnected = false;

// Simulation variables for sensor data
float temperature = 25.0;
float humidity = 60.0;
int lightLevel = 512;
bool ledState = false;

void setup() {
  Serial.begin(115200);
  Serial.println("ESP32 UDP Message Sender - send() Method Demo");
  
  // Display configuration
  Serial.println("=== Configuration ===");
  Serial.printf("Target Server: %s:%d\n", remoteIP.toString().c_str(), remotePort);
  Serial.printf("Device MAC: %s\n", WiFi.macAddress().c_str());
  Serial.printf("Message Buffer Size: %d bytes\n", 1024);
  Serial.println("====================");
  
  // Connect to WiFi
  WiFi.begin(ssid, password);
  Serial.printf("Connecting to WiFi: %s", ssid);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
  }
  
  Serial.println("\nWiFi connected successfully!");
  Serial.printf("Local IP: %s\n", WiFi.localIP().toString().c_str());
  Serial.printf("Gateway: %s\n", WiFi.gatewayIP().toString().c_str());
  Serial.printf("DNS: %s\n", WiFi.dnsIP().toString().c_str());
  Serial.printf("Signal Strength: %d dBm\n", WiFi.RSSI());
  
  // Connect to remote UDP endpoint
  if (udp.connect(remoteIP, remotePort)) {
    Serial.printf("UDP connected to %s:%d\n", remoteIP.toString().c_str(), remotePort);
    isConnected = true;
    
    // Send initial connection message using send() method
    message.flush(); // Clear the message buffer
    String welcomeMsg = "ESP32 Message Sender Connected - Device: " + WiFi.macAddress();
    message.print(welcomeMsg);
    size_t sent = udp.send(message);
    Serial.printf("Welcome message sent: %d bytes\n", sent);
  } else {
    Serial.println("Failed to connect to UDP endpoint");
    isConnected = false;
  }
  
  Serial.println("Starting message transmission...");
  Serial.println("==============================");
}

void loop() {
  static unsigned long lastSend = 0;
  static int messageType = 0;
  
  // Send messages every 5 seconds
  if (millis() - lastSend > 5000) {
    lastSend = millis();
    
    if (!isConnected) {
      // Attempt to reconnect
      Serial.println("Attempting to reconnect...");
      if (udp.connect(remoteIP, remotePort)) {
        isConnected = true;
        Serial.println("Reconnected successfully");
      } else {
        Serial.println("Reconnection failed");
        return;
      }
    }
    
    messageCounter++;
    
    // Send different types of messages based on cycle
    switch (messageType % 5) {
      case 0:
        sendTextMessage();
        break;
      case 1:
        sendSensorMessage();
        break;
      case 2:
        sendJSONMessage();
        break;
      case 3:
        sendBinaryMessage();
        break;
      case 4:
        sendSystemMessage();
        break;
    }
    
    messageType++;
  }
  
  // Update simulated sensor values
  updateSensorValues();
  
  // Display periodic status
  static unsigned long lastStatus = 0;
  if (millis() - lastStatus > 30000) { // Every 30 seconds
    lastStatus = millis();
    displayStatus();
  }
  
  delay(1000);
}

void sendTextMessage() {
  // Clear message buffer and construct text message
  message.flush();
  message.printf("HELLO|%lu|%s|%lu|%d", 
                 messageCounter, 
                 WiFi.macAddress().c_str(), 
                 millis()/1000, 
                 ESP.getFreeHeap());
  
  size_t sent = udp.send(message);
  
  Serial.printf("[%lu] Text Message Sent: %d bytes\n", messageCounter, sent);
  Serial.printf("Content: %s\n", (char*)message.data());
  Serial.printf("Buffer Utilization: %d/%d bytes\n", message.length(), message.space() + message.length());
  Serial.println("─────────────────────────────────────────");
}

void sendSensorMessage() {
  // Clear message buffer and construct sensor data message
  message.flush();
  message.printf("SENSOR|%lu|%.2f|%.1f|%d|%s|%d|%lu", 
                 messageCounter,
                 temperature, 
                 humidity, 
                 lightLevel, 
                 ledState ? "ON" : "OFF",
                 WiFi.RSSI(),
                 millis());
  
  size_t sent = udp.send(message);
  
  Serial.printf("[%lu] Sensor Message Sent: %d bytes\n", messageCounter, sent);
  Serial.printf("Temperature: %.2f°C, Humidity: %.1f%%, Light: %d, LED: %s\n", 
                temperature, humidity, lightLevel, ledState ? "ON" : "OFF");
  Serial.printf("Buffer Utilization: %d/%d bytes\n", message.length(), message.space() + message.length());
  Serial.println("─────────────────────────────────────────");
}

void sendJSONMessage() {
  // Clear message buffer and construct JSON message
  message.flush();
  
  // Use message buffer as JSON document
  DynamicJsonDocument doc(512);
  doc["type"] = "json_data";
  doc["messageId"] = messageCounter;
  doc["deviceId"] = WiFi.macAddress();
  doc["timestamp"] = millis();
  doc["sensors"]["temperature"] = temperature;
  doc["sensors"]["humidity"] = humidity;
  doc["sensors"]["light"] = lightLevel;
  doc["status"]["led"] = ledState;
  doc["status"]["wifi_rssi"] = WiFi.RSSI();
  doc["status"]["free_heap"] = ESP.getFreeHeap();
  doc["status"]["uptime"] = millis() / 1000;
  
  // Serialize JSON to message buffer
  String jsonString;
  serializeJson(doc, jsonString);
  message.print(jsonString);
  
  size_t sent = udp.send(message);
  
  Serial.printf("[%lu] JSON Message Sent: %d bytes\n", messageCounter, sent);
  Serial.printf("JSON Content: %s\n", jsonString.c_str());
  Serial.printf("Buffer Utilization: %d/%d bytes\n", message.length(), message.space() + message.length());
  Serial.println("─────────────────────────────────────────");
}

void sendBinaryMessage() {
  // Clear message buffer and construct binary message
  message.flush();
  
  // Add binary header
  message.write('B'); // Binary message identifier
  message.write('I'); 
  message.write('N');
  message.write(0x00); // Null terminator
  
  // Add binary data structure
  uint32_t msgId = messageCounter;
  uint32_t timestamp = millis();
  float temp = temperature;
  float hum = humidity;
  uint16_t light = lightLevel;
  uint8_t led = ledState ? 1 : 0;
  int8_t rssi = WiFi.RSSI();
  uint32_t heap = ESP.getFreeHeap();
  
  // Write binary data to message buffer
  message.write((uint8_t*)&msgId, sizeof(msgId));
  message.write((uint8_t*)&timestamp, sizeof(timestamp));
  message.write((uint8_t*)&temp, sizeof(temp));
  message.write((uint8_t*)&hum, sizeof(hum));
  message.write((uint8_t*)&light, sizeof(light));
  message.write((uint8_t*)&led, sizeof(led));
  message.write((uint8_t*)&rssi, sizeof(rssi));
  message.write((uint8_t*)&heap, sizeof(heap));
  
  size_t sent = udp.send(message);
  
  Serial.printf("[%lu] Binary Message Sent: %d bytes\n", messageCounter, sent);
  Serial.printf("Binary Data: Header + %d data bytes\n", message.length() - 4);
  Serial.printf("Buffer Utilization: %d/%d bytes\n", message.length(), message.space() + message.length());
  Serial.println("─────────────────────────────────────────");
}

void sendSystemMessage() {
  // Clear message buffer and construct system information message
  message.flush();
  message.printf("SYSTEM|%lu|%s|%dMHz|%db|%db|%ddBm|%lus|%s", 
                 messageCounter,
                 ESP.getChipModel(),
                 ESP.getCpuFreqMHz(),
                 ESP.getFreeHeap(),
                 ESP.getFlashChipSize(),
                 WiFi.RSSI(),
                 millis() / 1000,
                 ESP.getSdkVersion());
  
  size_t sent = udp.send(message);
  
  Serial.printf("[%lu] System Message Sent: %d bytes\n", messageCounter, sent);
  Serial.printf("System: %s @ %dMHz, Heap: %d bytes\n", 
                ESP.getChipModel(), ESP.getCpuFreqMHz(), ESP.getFreeHeap());
  Serial.printf("Buffer Utilization: %d/%d bytes\n", message.length(), message.space() + message.length());
  Serial.println("─────────────────────────────────────────");
}

void updateSensorValues() {
  // Simulate changing sensor values
  static unsigned long lastUpdate = 0;
  if (millis() - lastUpdate > 2000) {
    lastUpdate = millis();
    
    // Simulate temperature variation
    temperature += (random(-20, 21) / 10.0);
    if (temperature < 20.0) temperature = 20.0;
    if (temperature > 30.0) temperature = 30.0;
    
    // Simulate humidity variation
    humidity += (random(-50, 51) / 10.0);
    if (humidity < 40.0) humidity = 40.0;
    if (humidity > 80.0) humidity = 80.0;
    
    // Simulate light level variation
    lightLevel += random(-50, 51);
    if (lightLevel < 0) lightLevel = 0;
    if (lightLevel > 1023) lightLevel = 1023;
    
    // Toggle LED state occasionally
    if (random(0, 10) > 7) {
      ledState = !ledState;
    }
  }
}

void displayStatus() {
  Serial.println("╔══════════════════════════════════════════════════╗");
  Serial.println("║              MESSAGE TRANSMISSION STATUS         ║");
  Serial.println("╚══════════════════════════════════════════════════╝");
  Serial.printf("Messages Sent: %lu\n", messageCounter);
  Serial.printf("Connection Status: %s\n", isConnected ? "Connected" : "Disconnected");
  Serial.printf("Target: %s:%d\n", remoteIP.toString().c_str(), remotePort);
  Serial.printf("Local IP: %s\n", WiFi.localIP().toString().c_str());
  Serial.printf("WiFi Signal: %d dBm\n", WiFi.RSSI());
  Serial.printf("Uptime: %lu seconds\n", millis() / 1000);
  Serial.printf("Free Heap: %d bytes\n", ESP.getFreeHeap());
  Serial.printf("Message Buffer: %d bytes capacity\n", message.space() + message.length());
  Serial.printf("Buffer Available: %d bytes\n", message.space());
  Serial.println("══════════════════════════════════════════════════");
}

Testing Example: UDP Message Receiver

This companion example demonstrates how to create a UDP receiver that listens for messages sent by the previous example. This receiver ESP32 will display all incoming UDP messages in various formats, allowing you to verify that the send() method is working correctly. The receiver provides detailed parsing of different message types including text, sensor data, JSON, binary packets, and system information.

How to test with two ESP32 boards:

  1. Setup the Receiver: Upload this “UDP Message Receiver” code to your first ESP32 and note its IP address from the Serial Monitor.
  2. Setup the Sender: Upload the previous “Message Buffer Sender” code to your second ESP32 and update the remoteIP variable with the first ESP32’s IP address.
  3. Configure Network: Ensure both ESP32 boards are connected to the same WiFi network.
  4. Monitor Results: Open Serial Monitor for both ESP32s to see message transmission and reception in real-time.
  5. Verify Messages: Compare sent messages on sender with received messages on receiver to verify successful transmission.
/*
 * Author: Avant Maker
 * Date: January 15, 2025
 * Version: 1.0
 * License: MIT
 * 
 * Description: 
 * UDP Message Receiver for testing send() method functionality. This example
 * creates a UDP server that listens for incoming messages and displays them in
 * various formats. It's designed to work with the Message Buffer Sender example
 * to provide comprehensive testing of the AsyncUDP send() method with
 * AsyncUDPMessage buffers.
 */

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

// WiFi credentials
const char* ssid = "your_wifi_ssid";
const char* password = "your_wifi_password";

// Server configuration
const uint16_t serverPort = 8888; // Port to listen on

AsyncUDP udp;
AsyncUDPMessage responseMessage(512); // Create response message buffer
unsigned long totalMessagesReceived = 0;
unsigned long totalBytesReceived = 0;

// Structure to track sender statistics
struct SenderStats {
  String senderIP;
  unsigned long messageCount;
  unsigned long byteCount;
  unsigned long firstSeen;
  unsigned long lastSeen;
  String lastMessageType;
  String lastContent;
};

std::map<String, SenderStats> senderMap;

void setup() {
  Serial.begin(115200);
  Serial.println("ESP32 UDP Message Receiver - Testing send() Method");
  
  // Connect to WiFi
  WiFi.begin(ssid, password);
  Serial.printf("Connecting to WiFi: %s", ssid);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
  }
  
  Serial.println("\nWiFi connected successfully!");
  Serial.printf("Receiver IP: %s\n", WiFi.localIP().toString().c_str());
  Serial.printf("Update sender ESP32 with this IP address: %s\n", WiFi.localIP().toString().c_str());
  Serial.printf("Response Buffer Size: %d bytes\n", 512);
  
  // Start UDP server
  if (udp.listen(serverPort)) {
    Serial.printf("UDP Server listening on port %d\n", serverPort);
    Serial.println("Waiting for messages from sender...");
    
    // Set up packet handler
    udp.onPacket([](AsyncUDPPacket packet) {
      handleIncomingMessage(packet);
    });
  } else {
    Serial.println("Failed to start UDP server");
  }
}

void loop() {
  // Display periodic statistics
  static unsigned long lastStats = 0;
  if (millis() - lastStats > 30000) { // Every 30 seconds
    lastStats = millis();
    displayStatistics();
  }
  
  delay(1000);
}

void handleIncomingMessage(AsyncUDPPacket packet) {
  // Get packet information
  IPAddress senderIP = packet.remoteIP();
  uint16_t senderPort = packet.remotePort();
  size_t messageSize = packet.length();
  
  // Update statistics
  totalMessagesReceived++;
  totalBytesReceived += messageSize;
  
  // Update sender statistics
  String senderKey = senderIP.toString() + ":" + String(senderPort);
  unsigned long currentTime = millis();
  
  if (senderMap.find(senderKey) == senderMap.end()) {
    // New sender
    SenderStats newSender;
    newSender.senderIP = senderIP.toString();
    newSender.messageCount = 1;
    newSender.byteCount = messageSize;
    newSender.firstSeen = currentTime;
    newSender.lastSeen = currentTime;
    senderMap[senderKey] = newSender;
    
    Serial.println("╔══════════════════════════════════════════════════════════════════╗");
    Serial.println("║                        NEW SENDER DETECTED                      ║");
    Serial.println("╚══════════════════════════════════════════════════════════════════╝");
  } else {
    // Existing sender
    senderMap[senderKey].messageCount++;
    senderMap[senderKey].byteCount += messageSize;
    senderMap[senderKey].lastSeen = currentTime;
  }
  
  // Extract message data
  String messageData = "";
  for (size_t i = 0; i < messageSize; i++) {
    messageData += (char)packet.data()[i];
  }
  senderMap[senderKey].lastContent = messageData;
  
  // Parse and display message based on type
  String messageType = parseMessageType(messageData, packet.data(), messageSize);
  senderMap[senderKey].lastMessageType = messageType;
  
  Serial.printf("Message #%lu from %s:%d (%d bytes) - Type: %s\n", 
                totalMessagesReceived, senderIP.toString().c_str(), senderPort, messageSize, messageType.c_str());
  
  // Send acknowledgment using send() method
  responseMessage.flush();
  responseMessage.printf("ACK|%lu|%s|%d|%lu", 
                        totalMessagesReceived, 
                        messageType.c_str(), 
                        messageSize, 
                        millis());
  
  size_t sent = packet.send(responseMessage);
  Serial.printf("Acknowledgment sent: %d bytes\n", sent);
  
  Serial.println("──────────────────────────────────────────────────────────────────");
}

String parseMessageType(const String& messageData, const uint8_t* rawData, size_t size) {
  // Determine message type and display accordingly
  if (messageData.startsWith("HELLO|")) {
    Serial.printf("📝 TEXT MESSAGE: %s\n", messageData.c_str());
    return "TEXT";
  }
  else if (messageData.startsWith("SENSOR|")) {
    Serial.printf("🌡️ SENSOR DATA: %s\n", messageData.c_str());
    parseSensorData(messageData);
    return "SENSOR";
  }
  else if (messageData.startsWith("{") && messageData.endsWith("}")) {
    Serial.printf("📋 JSON MESSAGE: %s\n", messageData.c_str());
    parseJSONData(messageData);
    return "JSON";
  }
  else if (size > 4 && rawData[0] == 'B' && rawData[1] == 'I' && rawData[2] == 'N' && rawData[3] == 0x00) {
    Serial.printf("💾 BINARY MESSAGE: %d bytes\n", size);
    parseBinaryData(rawData, size);
    return "BINARY";
  }
  else if (messageData.startsWith("SYSTEM|")) {
    Serial.printf("🖥️ SYSTEM INFO: %s\n", messageData.c_str());
    parseSystemData(messageData);
    return "SYSTEM";
  }
  else {
    Serial.printf("❓ UNKNOWN MESSAGE: %s\n", messageData.c_str());
    return "UNKNOWN";
  }
}

void parseSensorData(const String& data) {
  // Parse sensor data format: SENSOR|msgId|temp|humidity|light|led|rssi|timestamp
  int fields[7];
  String values[7];
  int fieldIndex = 0;
  int startIndex = 7; // Skip "SENSOR|"
  
  for (int i = startIndex; i < data.length() && fieldIndex < 7; i++) {
    if (data.charAt(i) == '|' || i == data.length() - 1) {
      values[fieldIndex] = data.substring(startIndex, i == data.length() - 1 ? i + 1 : i);
      startIndex = i + 1;
      fieldIndex++;
    }
  }
  
  if (fieldIndex >= 6) {
    Serial.printf("   📊 Msg ID: %s, Temp: %s°C, Humidity: %s%%, Light: %s\n", 
                  values[0].c_str(), values[1].c_str(), values[2].c_str(), values[3].c_str());
    Serial.printf("   📡 LED: %s, RSSI: %sdBm, Time: %sms\n", 
                  values[4].c_str(), values[5].c_str(), values[6].c_str());
  }
}

void parseJSONData(const String& jsonData) {
  DynamicJsonDocument doc(512);
  DeserializationError error = deserializeJson(doc, jsonData);
  
  if (!error) {
    Serial.printf("   📋 Type: %s, Msg ID: %d, Device: %s\n", 
                  doc["type"].as<String>().c_str(),
                  doc["messageId"].as<int>(),
                  doc["deviceId"].as<String>().c_str());
    Serial.printf("   🌡️ Temp: %.1f°C, Humidity: %.1f%%, Light: %d\n",
                  doc["sensors"]["temperature"].as<float>(),
                  doc["sensors"]["humidity"].as<float>(),
                  doc["sensors"]["light"].as<int>());
    Serial.printf("   📡 LED: %s, RSSI: %ddBm, Heap: %d bytes\n",
                  doc["status"]["led"].as<bool>() ? "ON" : "OFF",
                  doc["status"]["wifi_rssi"].as<int>(),
                  doc["status"]["free_heap"].as<int>());
  } else {
    Serial.printf("   ❌ JSON Parse Error: %s\n", error.c_str());
  }
}

void parseBinaryData(const uint8_t* data, size_t size) {
  if (size >= 32) { // Minimum expected binary data size
    const uint8_t* ptr = data + 4; // Skip "BIN\0" header
    
    uint32_t msgId = *(uint32_t*)ptr; ptr += 4;
    uint32_t timestamp = *(uint32_t*)ptr; ptr += 4;
    float temperature = *(float*)ptr; ptr += 4;
    float humidity = *(float*)ptr; ptr += 4;
    uint16_t light = *(uint16_t*)ptr; ptr += 2;
    uint8_t led = *(uint8_t*)ptr; ptr += 1;
    int8_t rssi = *(int8_t*)ptr; ptr += 1;
    uint32_t heap = *(uint32_t*)ptr; ptr += 4;
    
    Serial.printf("   💾 Msg ID: %u, Time: %ums, Temp: %.2f°C\n", msgId, timestamp, temperature);
    Serial.printf("   📊 Humidity: %.1f%%, Light: %u, LED: %s\n", humidity, light, led ? "ON" : "OFF");
    Serial.printf("   📡 RSSI: %ddBm, Heap: %u bytes\n", rssi, heap);
  } else {
    Serial.printf("   ❌ Binary data too small: %d bytes\n", size);
  }
}

void parseSystemData(const String& data) {
  // Parse system data format: SYSTEM|msgId|chip|freq|heap|flash|rssi|uptime|sdk
  String values[8];
  int fieldIndex = 0;
  int startIndex = 7; // Skip "SYSTEM|"
  
  for (int i = startIndex; i < data.length() && fieldIndex < 8; i++) {
    if (data.charAt(i) == '|' || i == data.length() - 1) {
      values[fieldIndex] = data.substring(startIndex, i == data.length() - 1 ? i + 1 : i);
      startIndex = i + 1;
      fieldIndex++;
    }
  }
  
  if (fieldIndex >= 7) {
    Serial.printf("   🖥️ Chip: %s @ %s, Heap: %s, Flash: %s\n", 
                  values[1].c_str(), values[2].c_str(), values[3].c_str(), values[4].c_str());
    Serial.printf("   📡 RSSI: %s, Uptime: %s, SDK: %s\n", 
                  values[5].c_str(), values[6].c_str(), fieldIndex > 7 ? values[7].c_str() : "N/A");
  }
}

void displayStatistics() {
  Serial.println("╔══════════════════════════════════════════════════════════════════╗");
  Serial.println("║                      MESSAGE RECEIVER STATISTICS                ║");
  Serial.println("╚══════════════════════════════════════════════════════════════════╝");
  Serial.printf("Total Messages Received: %lu\n", totalMessagesReceived);
  Serial.printf("Total Bytes Received: %lu\n", totalBytesReceived);
  Serial.printf("Active Senders: %d\n", senderMap.size());
  Serial.printf("Server Uptime: %lu seconds\n", millis() / 1000);
  Serial.printf("Free Heap: %d bytes\n", ESP.getFreeHeap());
  Serial.printf("WiFi Signal: %d dBm\n", WiFi.RSSI());
  Serial.printf("Response Buffer: %d bytes capacity\n", responseMessage.space() + responseMessage.length());
  
  if (!senderMap.empty()) {
    Serial.println("\nSender Details:");
    Serial.println("IP Address    | Messages | Bytes  | Last Type | Status   | Last Seen");
    Serial.println("--------------|----------|--------|-----------|----------|----------");
    
    unsigned long currentTime = millis();
    for (auto& sender : senderMap) {
      String status = (currentTime - sender.second.lastSeen < 30000) ? "Active" : "Inactive";
      Serial.printf("%-13s | %-8lu | %-6lu | %-9s | %-8s | %lu\n",
                   sender.second.senderIP.c_str(),
                   sender.second.messageCount,
                   sender.second.byteCount,
                   sender.second.lastMessageType.c_str(),
                   status.c_str(),
                   sender.second.lastSeen / 1000);
    }
  }
  Serial.println("══════════════════════════════════════════════════════════════════");
}

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

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 !!