ESP32 AsyncUDP Library – printf()

Home / References / ESP32 Library / AsyncUDP Library

Description

The printf() method is an advanced formatted data transmission function in the AsyncUDP library that provides C-style formatted printing capabilities for ESP32 UDP communication. Inherited from the Arduino Print class, this method enables developers to send precisely formatted text, numbers, and data to UDP endpoints using familiar printf-style format specifiers and syntax. The method is available in both the AsyncUDP class and the AsyncUDPPacket class, offering powerful options for sending structured, formatted data over UDP networks.

The printf() method supports comprehensive format specifiers including %d, %i, %u, %x, %X, %o, %f, %e, %E, %g, %G, %c, %s, and %p, along with field width, precision, and alignment modifiers. This makes it ideal for creating professional data reports, precise sensor readings, structured logging output, protocol messages, and complex data formatting requirements.

The method operates asynchronously and integrates seamlessly with ESP32’s networking stack, providing a sophisticated yet familiar interface for UDP formatted text communication in advanced IoT applications, telemetry systems, and data acquisition platforms.

Syntax and Usage

The printf() method uses C-style format strings and can be used in different contexts:

AsyncUDP class: 

udp.printf(format, args...)

Prints formatted data to the connected remote endpoint.

AsyncUDP class with format string:

udp.printf("Value: %d, Status: %s", value, status)

 Prints formatted data with multiple arguments.

AsyncUDPPacket class: 

packet.printf(format, args...)

Prints formatted response data back to the packet sender.

AsyncUDPPacket with format string: 

packet.printf("Result: %.2f%%", percentage)

Prints formatted responses with precision control.

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 printf() method accepts the following arguments:

  • format (const char*): The format string containing literal characters and format specifiers that define how subsequent arguments are formatted.
  • args… (variadic): Variable number of arguments corresponding to the format specifiers in the format string.

Format Specifiers

The printf() method supports standard C format specifiers:

  • %d, %i: Decimal integer
  • %u: Unsigned decimal integer
  • %x, %X: Hexadecimal integer (lowercase/uppercase)
  • %o: Octal integer
  • %f: Floating-point number
  • %e, %E: Scientific notation (lowercase/uppercase)
  • %g, %G: General format (shortest of %f or %e)
  • %c: Single character
  • %s: String
  • %p: Pointer address
  • %%: Literal percent sign

Return Value

The printf() 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 characters formatted and sent. The method processes the format string, applies the specified formatting to the arguments, generates the resulting formatted string, and transmits it via UDP. 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 formatted response back to the original sender’s IP address and port. The method ensures reliable formatted text transmission by utilizing the underlying UDP write() functionality and provides immediate feedback about transmission success through its return value.

Example Code

Simple Example: UDP Printf Sender

This example demonstrates how to use the printf() method to send precisely formatted data to a remote UDP endpoint. The ESP32 connects to a specified remote IP address and port, then periodically sends various types of formatted data using different printf format specifiers including integers, floating-point numbers, strings, and complex data structures. This demonstrates the practical application of the printf() method for professional IoT communications, structured data logging, telemetry systems, and advanced debugging applications.

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 formatted data every 2 seconds. Use the companion receiver example (provided below) on another ESP32 or computer to see the transmitted formatted data.

/*
 * Author: Avant Maker
 * Date: January 15, 2025
 * Version: 1.0
 * License: MIT
 * 
 * Description: 
 * UDP Printf Sender that demonstrates printf() method usage for transmitting
 * precisely formatted text and data to a remote UDP endpoint. This example
 * shows how to use C-style printf() functions for UDP communication, including
 * comprehensive format specifiers, precision control, field width, and
 * structured data formatting. Perfect for professional IoT communications,
 * telemetry systems, and advanced data logging applications.
 *
 * Features Demonstrated:
 * - UDP connection establishment using connect()
 * - Formatted data transmission using printf() method
 * - Comprehensive format specifiers (%d, %f, %s, %x, %o, %e, %g)
 * - Precision and field width control
 * - Scientific notation and hexadecimal formatting
 * - Structured data reports and sensor readings
 * - Professional telemetry message formatting
 * - Advanced debugging output with printf
 *
 * 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 data
 * 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>

// WiFi credentials
const char* ssid = "your_SSID";          // Replace with your Wi-Fi SSID
const char* password = "your_PASSWORD";  // Replace with your Wi-Fi 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;
unsigned long messageCounter = 0;
bool isConnected = false;

// Simulation variables for sensor data
float temperature = 25.3;
float humidity = 62.8;
int lightLevel = 512;
bool ledState = false;
int batteryLevel = 87;
float voltage = 3.31;
float current = 0.145;

// Device information
const char* deviceName = "ESP32-Sensor-Node";
const char* firmwareVersion = "v2.1.3";
const char* location = "Laboratory-A";

void setup() {
  Serial.begin(115200);
  Serial.println("ESP32 UDP Printf Sender - printf() 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.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 printf()
    size_t sent = udp.printf("INIT|Device:%s|FW:%s|MAC:%s|Location:%s|Status:CONNECTED", 
                             deviceName, firmwareVersion, WiFi.macAddress().c_str(), location);
    Serial.printf("Welcome message sent: %d bytes\n", sent);
  } else {
    Serial.println("Failed to connect to UDP endpoint");
    isConnected = false;
  }
  
  Serial.println("Starting printf formatted data transmission...");
  Serial.println("==============================================");
}

void loop() {
  static unsigned long lastSend = 0;
  static int dataType = 0;
  
  // Send data every 2 seconds
  if (millis() - lastSend > 2000) {
    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 printf formatted data based on cycle
    switch (dataType % 7) {
      case 0:
        sendFormattedSensorData();
        break;
      case 1:
        sendPrecisionFloatData();
        break;
      case 2:
        sendHexadecimalData();
        break;
      case 3:
        sendScientificNotation();
        break;
      case 4:
        sendStructuredReport();
        break;
      case 5:
        sendPowerAnalysis();
        break;
      case 6:
        sendSystemTelemetry();
        break;
    }
    
    dataType++;
  }
  
  // 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 sendFormattedSensorData() {
  size_t sent = udp.printf("SENSOR|ID:%04d|Temp:%+06.2f°C|Hum:%05.1f%%|Light:%04d|LED:%s|Batt:%3d%%|Time:%08lu", 
                           messageCounter, temperature, humidity, lightLevel, 
                           ledState ? "ON " : "OFF", batteryLevel, millis()/1000);
  
  Serial.printf("[%lu] Formatted Sensor Data Sent: %d bytes\n", messageCounter, sent);
  Serial.printf("Temperature: %+.2f°C, Humidity: %.1f%%, Light: %d, Battery: %d%%\n", 
                temperature, humidity, lightLevel, batteryLevel);
  Serial.println("─────────────────────────────────────────");
}

void sendPrecisionFloatData() {
  float pi = 3.14159265359;
  float e = 2.71828182846;
  
  size_t sent = udp.printf("PRECISION|PI:%.8f|E:%.8f|Temp:%.4f|Voltage:%.6f|Current:%.6f", 
                           pi, e, temperature, voltage, current);
  
  Serial.printf("[%lu] Precision Float Data Sent: %d bytes\n", messageCounter, sent);
  Serial.printf("High precision: PI=%.8f, E=%.8f, V=%.6f, I=%.6f\n", pi, e, voltage, current);
  Serial.println("─────────────────────────────────────────");
}

void sendHexadecimalData() {
  uint32_t deviceId = 0xABCD1234;
  uint16_t statusFlags = 0x00F3;
  uint8_t errorCode = 0x00;
  
  size_t sent = udp.printf("HEX|DeviceID:0x%08X|Status:0x%04X|Error:0x%02X|MsgCnt:0x%04X|Light:0x%03X", 
                           deviceId, statusFlags, errorCode, (uint16_t)messageCounter, lightLevel);
  
  Serial.printf("[%lu] Hexadecimal Data Sent: %d bytes\n", messageCounter, sent);
  Serial.printf("Device ID: 0x%08X, Status: 0x%04X, Light: 0x%03X\n", deviceId, statusFlags, lightLevel);
  Serial.println("─────────────────────────────────────────");
}

void sendScientificNotation() {
  float powerConsumption = voltage * current;
  float resistance = voltage / current;
  float capacitance = 0.000047; // 47µF
  
  size_t sent = udp.printf("SCIENTIFIC|Power:%e W|Resistance:%e Ω|Capacitance:%e F|Frequency:%E Hz", 
                           powerConsumption, resistance, capacitance, 50000.0);
  
  Serial.printf("[%lu] Scientific Notation Sent: %d bytes\n", messageCounter, sent);
  Serial.printf("Power: %e W, Resistance: %e Ω, Capacitance: %e F\n", 
                powerConsumption, resistance, capacitance);
  Serial.println("─────────────────────────────────────────");
}

void sendStructuredReport() {
  unsigned long uptime = millis() / 1000;
  int hours = uptime / 3600;
  int minutes = (uptime % 3600) / 60;
  int seconds = uptime % 60;
  
  size_t sent = udp.printf("REPORT|%s|%s|Uptime:%02d:%02d:%02d|Heap:%u|RSSI:%d dBm|Status:OPERATIONAL", 
                           deviceName, location, hours, minutes, seconds, 
                           ESP.getFreeHeap(), WiFi.RSSI());
  
  Serial.printf("[%lu] Structured Report Sent: %d bytes\n", messageCounter, sent);
  Serial.printf("Uptime: %02d:%02d:%02d, Free Heap: %u bytes, RSSI: %d dBm\n", 
                hours, minutes, seconds, ESP.getFreeHeap(), WiFi.RSSI());
  Serial.println("─────────────────────────────────────────");
}

void sendPowerAnalysis() {
  float power = voltage * current;
  float efficiency = (power / (voltage * current)) * 100.0;
  
  size_t sent = udp.printf("POWER|V:%7.4fV|I:%8.5fA|P:%8.5fW|Eff:%6.2f%%|Load:%c|Mode:%s", 
                           voltage, current, power, efficiency, 
                           ledState ? 'H' : 'L', batteryLevel > 20 ? "NORMAL" : "LOW_POWER");
  
  Serial.printf("[%lu] Power Analysis Sent: %d bytes\n", messageCounter, sent);
  Serial.printf("V=%7.4fV, I=%8.5fA, P=%8.5fW, Efficiency=%.2f%%\n", 
                voltage, current, power, efficiency);
  Serial.println("─────────────────────────────────────────");
}

void sendSystemTelemetry() {
  size_t sent = udp.printf("TELEMETRY|CPU:%dMHz|RAM:%u/%uKB|Flash:%u/%uKB|Temp:%.1f°C|RSSI:%d|Packets:%lu", 
                           ESP.getCpuFreqMHz(), 
                           (ESP.getHeapSize() - ESP.getFreeHeap())/1024, ESP.getHeapSize()/1024,
                           0, ESP.getFlashChipSize()/1024,
                           temperature, WiFi.RSSI(), messageCounter);
  
  Serial.printf("[%lu] System Telemetry Sent: %d bytes\n", messageCounter, sent);
  Serial.printf("CPU: %dMHz, RAM: %u/%uKB, Temperature: %.1f°C\n", 
                ESP.getCpuFreqMHz(), 
                (ESP.getHeapSize() - ESP.getFreeHeap())/1024, ESP.getHeapSize()/1024,
                temperature);
  Serial.println("─────────────────────────────────────────");
}

void updateSensorValues() {
  // Simulate changing sensor values with realistic variations
  static unsigned long lastUpdate = 0;
  if (millis() - lastUpdate > 1500) {
    lastUpdate = millis();
    
    // Simulate temperature variation
    temperature += (random(-30, 31) / 100.0);
    if (temperature < 20.0) temperature = 20.0;
    if (temperature > 35.0) temperature = 35.0;
    
    // Simulate humidity variation
    humidity += (random(-50, 51) / 100.0);
    if (humidity < 40.0) humidity = 40.0;
    if (humidity > 85.0) humidity = 85.0;
    
    // Simulate light level variation
    lightLevel += random(-30, 31);
    if (lightLevel < 0) lightLevel = 0;
    if (lightLevel > 1023) lightLevel = 1023;
    
    // Simulate voltage variation
    voltage += (random(-50, 51) / 1000.0);
    if (voltage < 3.0) voltage = 3.0;
    if (voltage > 3.6) voltage = 3.6;
    
    // Simulate current variation
    current += (random(-20, 21) / 1000.0);
    if (current < 0.100) current = 0.100;
    if (current > 0.200) current = 0.200;
    
    // Simulate battery level variation
    batteryLevel += random(-1, 2);
    if (batteryLevel < 0) batteryLevel = 0;
    if (batteryLevel > 100) batteryLevel = 100;
    
    // Toggle LED state occasionally
    if (random(0, 20) > 17) {
      ledState = !ledState;
    }
  }
}

void displayStatus() {
  Serial.println("╔════════════════════════════════════════════════════════════════╗");
  Serial.println("║                 PRINTF 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("Device: %s | Location: %s | Firmware: %s\n", deviceName, location, firmwareVersion);
  Serial.printf("Current Values: T=%.2f°C, H=%.1f%%, V=%.4fV, I=%.5fA\n", 
                temperature, humidity, voltage, current);
  Serial.printf("WiFi Signal: %d dBm | Uptime: %lu seconds\n", WiFi.RSSI(), millis() / 1000);
  Serial.printf("Free Heap: %d bytes\n", ESP.getFreeHeap());
  Serial.println("════════════════════════════════════════════════════════════════");
}

Testing Example: UDP Printf Receiver

This companion example demonstrates how to create a UDP receiver that listens for formatted data sent by the previous example. This receiver ESP32 will display all incoming UDP printf-formatted data, allowing you to verify that the printf() method is working correctly with all format specifiers. The receiver provides advanced parsing and display of formatted messages, making it perfect for testing and debugging UDP printf communications with professional data analysis capabilities.

How to test with two ESP32 boards:

  1. Setup the Receiver: Upload this “UDP Printf Receiver” code to your first ESP32 and note its IP address from the Serial Monitor.
  2. Setup the Sender: Upload the previous “UDP Printf 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 printf formatted data transmission and reception in real-time.
  5. Verify Data: Compare sent formatted data on sender with received data on receiver to verify successful printf transmission and formatting.
/*
 * Author: Avant Maker
 * Date: January 15, 2025
 * Version: 1.0
 * License: MIT
 * 
 * Description: 
 * UDP Printf Receiver for testing printf() method functionality. This example
 * creates a UDP server that listens for incoming printf-formatted data and
 * displays it with advanced parsing and professional analysis. It's designed
 * to work with the UDP Printf Sender example to provide comprehensive testing
 * of the AsyncUDP printf() method capabilities with format specifier validation.
 */

#include <WiFi.h>
#include <AsyncUDP.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;
unsigned long totalPacketsReceived = 0;
unsigned long totalBytesReceived = 0;
unsigned long totalPrintfMessages = 0;

// Structure to track sender statistics with printf analysis
struct SenderStats {
  String senderIP;
  unsigned long packetCount;
  unsigned long byteCount;
  unsigned long firstSeen;
  unsigned long lastSeen;
  String lastMessage;
  String messageType;
  String formatType;
};

std::map<String, SenderStats> senderMap;

void setup() {
  Serial.begin(115200);
  Serial.println("ESP32 UDP Printf Receiver - Testing printf() 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());
  
  // Start UDP server
  if (udp.listen(serverPort)) {
    Serial.printf("UDP Printf Server listening on port %d\n", serverPort);
    Serial.println("Waiting for printf formatted data from sender...");
    
    // Set up packet handler
    udp.onPacket([](AsyncUDPPacket packet) {
      handleIncomingPacket(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 handleIncomingPacket(AsyncUDPPacket packet) {
  // Get packet information
  IPAddress senderIP = packet.remoteIP();
  uint16_t senderPort = packet.remotePort();
  size_t packetSize = packet.length();
  
  // Update statistics
  totalPacketsReceived++;
  totalBytesReceived += packetSize;
  totalPrintfMessages++;
  
  // 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.packetCount = 1;
    newSender.byteCount = packetSize;
    newSender.firstSeen = currentTime;
    newSender.lastSeen = currentTime;
    senderMap[senderKey] = newSender;
    
    Serial.println("╔══════════════════════════════════════════════════════════════════╗");
    Serial.println("║                   NEW PRINTF SENDER DETECTED                    ║");
    Serial.println("╚══════════════════════════════════════════════════════════════════╝");
  } else {
    // Existing sender
    senderMap[senderKey].packetCount++;
    senderMap[senderKey].byteCount += packetSize;
    senderMap[senderKey].lastSeen = currentTime;
  }
  
  // Extract and display packet data
  String dataString = "";
  for (size_t i = 0; i < packetSize; i++) {
    dataString += (char)packet.data()[i];
  }
  senderMap[senderKey].lastMessage = dataString;
  
  // Analyze message and format type
  String messageType = analyzeMessageType(dataString);
  String formatType = analyzeFormatType(dataString);
  senderMap[senderKey].messageType = messageType;
  senderMap[senderKey].formatType = formatType;
  
  // Display packet information with detailed printf analysis
  Serial.println("┌──────────────────────────────────────────────────────────────────┐");
  Serial.printf("│ Printf Packet #%lu from %s:%d (%d bytes)\n", 
                totalPacketsReceived, senderIP.toString().c_str(), senderPort, packetSize);
  Serial.printf("│ Type: %s | Format: %s\n", messageType.c_str(), formatType.c_str());
  Serial.println("├──────────────────────────────────────────────────────────────────┤");
  Serial.printf("│ Raw Content: %s\n", dataString.c_str());
  Serial.println("├──────────────────────────────────────────────────────────────────┤");
  
  // Parse and display structured printf data
  parseAndDisplayPrintfData(dataString, messageType);
  
  Serial.println("└──────────────────────────────────────────────────────────────────┘");
  
  // Send acknowledgment back to sender using printf() method
  size_t sent = packet.printf("ACK_PRINTF|ID:%lu|Size:%d|Type:%s|Format:%s|Status:OK|Time:%lu", 
                              totalPacketsReceived, packetSize, messageType.c_str(), 
                              formatType.c_str(), millis()/1000);
  
  Serial.printf("Printf acknowledgment sent: %d bytes\n", sent);
  Serial.println("══════════════════════════════════════════════════════════════════");
}

String analyzeMessageType(const String& data) {
  if (data.startsWith("INIT|")) {
    return "INITIALIZATION";
  } else if (data.startsWith("SENSOR|")) {
    return "SENSOR_DATA";
  } else if (data.startsWith("PRECISION|")) {
    return "PRECISION_FLOAT";
  } else if (data.startsWith("HEX|")) {
    return "HEXADECIMAL";
  } else if (data.startsWith("SCIENTIFIC|")) {
    return "SCIENTIFIC_NOTATION";
  } else if (data.startsWith("REPORT|")) {
    return "STRUCTURED_REPORT";
  } else if (data.startsWith("POWER|")) {
    return "POWER_ANALYSIS";
  } else if (data.startsWith("TELEMETRY|")) {
    return "SYSTEM_TELEMETRY";
  } else {
    return "UNKNOWN";
  }
}

String analyzeFormatType(const String& data) {
  String formatTypes = "";
  
  // Check for common printf format specifiers
  if (data.indexOf("%d") != -1 || data.indexOf("%i") != -1) formatTypes += "INT ";
  if (data.indexOf("%u") != -1) formatTypes += "UINT ";
  if (data.indexOf("%f") != -1) formatTypes += "FLOAT ";
  if (data.indexOf("%e") != -1 || data.indexOf("%E") != -1) formatTypes += "SCI ";
  if (data.indexOf("%x") != -1 || data.indexOf("%X") != -1) formatTypes += "HEX ";
  if (data.indexOf("%o") != -1) formatTypes += "OCT ";
  if (data.indexOf("%s") != -1) formatTypes += "STR ";
  if (data.indexOf("%c") != -1) formatTypes += "CHAR ";
  if (data.indexOf("%g") != -1 || data.indexOf("%G") != -1) formatTypes += "GEN ";
  
  return formatTypes.length() > 0 ? formatTypes : "BASIC";
}

void parseAndDisplayPrintfData(const String& data, const String& type) {
  if (type == "SENSOR_DATA") {
    Serial.println("│ Parsed Printf Sensor Data:");
    // Parse sensor data format with printf formatting
    int idStart = data.indexOf("ID:") + 3;
    int idEnd = data.indexOf("|Temp:");
    int tempStart = data.indexOf("Temp:") + 5;
    int tempEnd = data.indexOf("°C|Hum:");
    int humStart = data.indexOf("Hum:") + 4;
    int humEnd = data.indexOf("%|Light:");
    int lightStart = data.indexOf("Light:") + 6;
    int lightEnd = data.indexOf("|LED:");
    int ledStart = data.indexOf("LED:") + 4;
    int ledEnd = data.indexOf("|Batt:");
    int battStart = data.indexOf("Batt:") + 5;
    int battEnd = data.indexOf("%|Time:");
    int timeStart = data.indexOf("Time:") + 5;
    
    if (idStart > 2 && idEnd > idStart) {
      Serial.printf("│   Message ID: %s\n", data.substring(idStart, idEnd).c_str());
    }
    if (tempStart > 4 && tempEnd > tempStart) {
      Serial.printf("│   Temperature: %s°C (Printf formatted)\n", data.substring(tempStart, tempEnd).c_str());
    }
    if (humStart > 3 && humEnd > humStart) {
      Serial.printf("│   Humidity: %s%% (Printf formatted)\n", data.substring(humStart, humEnd).c_str());
    }
    if (lightStart > 5 && lightEnd > lightStart) {
      Serial.printf("│   Light Level: %s (Printf formatted)\n", data.substring(lightStart, lightEnd).c_str());
    }
    if (ledStart > 3 && ledEnd > ledStart) {
      Serial.printf("│   LED State: %s\n", data.substring(ledStart, ledEnd).c_str());
    }
    if (battStart > 4 && battEnd > battStart) {
      Serial.printf("│   Battery: %s%%\n", data.substring(battStart, battEnd).c_str());
    }
    if (timeStart > 4) {
      Serial.printf("│   Timestamp: %s seconds\n", data.substring(timeStart).c_str());
    }
    
  } else if (type == "PRECISION_FLOAT") {
    Serial.println("│ Parsed Printf Precision Float Data:");
    // Parse high precision floating point data
    int piStart = data.indexOf("PI:") + 3;
    int piEnd = data.indexOf("|E:");
    int eStart = data.indexOf("E:") + 2;
    int eEnd = data.indexOf("|Temp:");
    int voltStart = data.indexOf("Voltage:") + 8;
    int voltEnd = data.indexOf("|Current:");
    int currStart = data.indexOf("Current:") + 8;
    
    if (piStart > 2 && piEnd > piStart) {
      Serial.printf("│   PI (8 decimals): %s\n", data.substring(piStart, piEnd).c_str());
    }
    if (eStart > 1 && eEnd > eStart) {
      Serial.printf("│   E (8 decimals): %s\n", data.substring(eStart, eEnd).c_str());
    }
    if (voltStart > 7 && voltEnd > voltStart) {
      Serial.printf("│   Voltage (6 decimals): %s V\n", data.substring(voltStart, voltEnd).c_str());
    }
    if (currStart > 7) {
      Serial.printf("│   Current (6 decimals): %s A\n", data.substring(currStart).c_str());
    }
    
  } else if (type == "HEXADECIMAL") {
    Serial.println("│ Parsed Printf Hexadecimal Data:");
    // Parse hexadecimal formatted data
    int devStart = data.indexOf("DeviceID:") + 9;
    int devEnd = data.indexOf("|Status:");
    int statStart = data.indexOf("Status:") + 7;
    int statEnd = data.indexOf("|Error:");
    int errStart = data.indexOf("Error:") + 6;
    int errEnd = data.indexOf("|MsgCnt:");
    int msgStart = data.indexOf("MsgCnt:") + 7;
    int msgEnd = data.indexOf("|Light:");
    int lightStart = data.indexOf("Light:") + 6;
    
    if (devStart > 8 && devEnd > devStart) {
      Serial.printf("│   Device ID: %s\n", data.substring(devStart, devEnd).c_str());
    }
    if (statStart > 6 && statEnd > statStart) {
      Serial.printf("│   Status Flags: %s\n", data.substring(statStart, statEnd).c_str());
    }
    if (errStart > 5 && errEnd > errStart) {
      Serial.printf("│   Error Code: %s\n", data.substring(errStart, errEnd).c_str());
    }
    if (msgStart > 6 && msgEnd > msgStart) {
      Serial.printf("│   Message Count: %s\n", data.substring(msgStart, msgEnd).c_str());
    }
    if (lightStart > 5) {
      Serial.printf("│   Light (Hex): %s\n", data.substring(lightStart).c_str());
    }
    
  } else if (type == "SCIENTIFIC_NOTATION") {
    Serial.println("│ Parsed Printf Scientific Notation:");
    // Parse scientific notation data
    int powStart = data.indexOf("Power:") + 6;
    int powEnd = data.indexOf(" W|Resistance:");
    int resStart = data.indexOf("Resistance:") + 11;
    int resEnd = data.indexOf(" Ω|Capacitance:");
    int capStart = data.indexOf("Capacitance:") + 12;
    int capEnd = data.indexOf(" F|Frequency:");
    int freqStart = data.indexOf("Frequency:") + 10;
    int freqEnd = data.indexOf(" Hz");
    
    if (powStart > 5 && powEnd > powStart) {
      Serial.printf("│   Power: %s W (Scientific)\n", data.substring(powStart, powEnd).c_str());
    }
    if (resStart > 10 && resEnd > resStart) {
      Serial.printf("│   Resistance: %s Ω (Scientific)\n", data.substring(resStart, resEnd).c_str());
    }
    if (capStart > 11 && capEnd > capStart) {
      Serial.printf("│   Capacitance: %s F (Scientific)\n", data.substring(capStart, capEnd).c_str());
    }
    if (freqStart > 9 && freqEnd > freqStart) {
      Serial.printf("│   Frequency: %s Hz (Scientific)\n", data.substring(freqStart, freqEnd).c_str());
    }
    
  } else if (type == "POWER_ANALYSIS") {
    Serial.println("│ Parsed Printf Power Analysis:");
    // Parse power analysis with field width formatting
    int voltStart = data.indexOf("V:") + 2;
    int voltEnd = data.indexOf("V|I:");
    int currStart = data.indexOf("I:") + 2;
    int currEnd = data.indexOf("A|P:");
    int powStart = data.indexOf("P:") + 2;
    int powEnd = data.indexOf("W|Eff:");
    int effStart = data.indexOf("Eff:") + 4;
    int effEnd = data.indexOf("%|Load:");
    int loadStart = data.indexOf("Load:") + 5;
    int loadEnd = data.indexOf("|Mode:");
    int modeStart = data.indexOf("Mode:") + 5;
    
    if (voltStart > 1 && voltEnd > voltStart) {
      Serial.printf("│   Voltage: %s V (7.4f format)\n", data.substring(voltStart, voltEnd).c_str());
    }
    if (currStart > 1 && currEnd > currStart) {
      Serial.printf("│   Current: %s A (8.5f format)\n", data.substring(currStart, currEnd).c_str());
    }
    if (powStart > 1 && powEnd > powStart) {
      Serial.printf("│   Power: %s W (8.5f format)\n", data.substring(powStart, powEnd).c_str());
    }
    if (effStart > 3 && effEnd > effStart) {
      Serial.printf("│   Efficiency: %s%% (6.2f format)\n", data.substring(effStart, effEnd).c_str());
    }
    if (loadStart > 4 && loadEnd > loadStart) {
      Serial.printf("│   Load: %s (char format)\n", data.substring(loadStart, loadEnd).c_str());
    }
    if (modeStart > 4) {
      Serial.printf("│   Mode: %s (string format)\n", data.substring(modeStart).c_str());
    }
    
  } else {
    Serial.printf("│ Raw Printf Message: %s\n", data.c_str());
  }
}

void displayStatistics() {
  Serial.println("╔══════════════════════════════════════════════════════════════════╗");
  Serial.println("║                   PRINTF RECEIVER STATISTICS                    ║");
  Serial.println("╚══════════════════════════════════════════════════════════════════╝");
  Serial.printf("Total Printf Messages Received: %lu\n", totalPrintfMessages);
  Serial.printf("Total Packets Received: %lu\n", totalPacketsReceived);
  Serial.printf("Total Characters 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());
  
  if (!senderMap.empty()) {
    Serial.println("\nPrintf Sender Details:");
    Serial.println("IP Address    | Messages | Chars  | First | Last  | Type         | Format");
    Serial.println("--------------|----------|--------|-------|-------|--------------|-------");
    
    unsigned long currentTime = millis();
    for (auto& sender : senderMap) {
      Serial.printf("%-13s | %-8lu | %-6lu | %-5lu | %-5lu | %-12s | %s\n",
                   sender.second.senderIP.c_str(),
                   sender.second.packetCount,
                   sender.second.byteCount,
                   sender.second.firstSeen / 1000,
                   sender.second.lastSeen / 1000,
                   sender.second.messageType.c_str(),
                   sender.second.formatType.c_str());
    }
  }
  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 !!