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:
- Setup the Receiver: Upload this “UDP Printf Receiver” code to your first ESP32 and note its IP address from the Serial Monitor.
- Setup the Sender: Upload the previous “UDP Printf Sender” code to your second ESP32 and update the
remoteIPvariable with the first ESP32’s IP address. - Configure Network: Ensure both ESP32 boards are connected to the same WiFi network.
- Monitor Results: Open Serial Monitor for both ESP32s to see printf formatted data transmission and reception in real-time.
- 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 WiFi Library
- ESP32 WiFiClient Library
- ESP32 HTTPClient Library
- ESP32 WiFiClientSecure Library
- ESP32 WebServer Library
- ESP32 AsyncUDP Librarry
- Connection Management
- Data Transimission
- Broadcast Multicast
- Network Information
- Which ESP32 Boards are Recommended for Learners
- How to Copy Codes from AvantMaker.com
- What is SPIFFS and how to upload files to it?
- What is LIttleFS and how to upload files to it?
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!