Home / References / ESP32 Library / AsyncUDP Library
Description
The write() method is a fundamental data transmission function in the AsyncUDP library that enables ESP32 devices to send UDP packets to connected remote endpoints. This method is available in both the AsyncUDP class and the AsyncUDPPacket class, providing flexible options for UDP communication. The method works with established UDP connections and automatically sends data to the previously connected remote IP address and port. It’s particularly useful for implementing real-time communication protocols, IoT sensor data transmission, remote control systems, telemetry applications, and bi-directional communication between ESP32 devices. The write() method supports both single-byte and multi-byte data transmission, making it versatile for various data types including strings, binary data, sensor readings, and structured messages. 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 write() method has two main overloads and can be used in different contexts:
– AsyncUDP class:
udp.write(data, length)Sends data to the connected remote endpoint.
– AsyncUDP class single byte:
udp.write(singleByteData)Sends a single byte to the connected remote endpoint.
– AsyncUDPPacket class:
packet.write(data, length)Sends response data back to the packet sender.
– AsyncUDPPacket single byte:
packet.write(singleByteData)Sends a single byte response back to the packet sender.
Arguments
The write() method accepts the following arguments:
- data (const uint8_t*): A pointer to the data buffer containing the bytes to be transmitted. This can be any binary data, string, or structured data that needs to be sent via UDP.
- len (size_t): The number of bytes to transmit from the data buffer. The maximum size is limited by CONFIG_TCP_MSS (typically 1460 bytes).
- singleByteData (uint8_t): For single-byte overload, a single byte value to be transmitted.
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.
Return Value
The write() 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. 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 response back to the original sender’s IP address and port. The method ensures reliable transmission by utilizing the underlying lwIP UDP stack and provides immediate feedback about transmission success through its return value.
This page is part of the Comprehensive Guide to the ESP32 Arduino Core Library, accessible on AvantMaker.com.
Example Code
Simple Example: UDP Data Sender
This example demonstrates how to use the write() method to send data to a remote UDP endpoint. The ESP32 connects to a specified remote IP address and port, then periodically sends various types of data including strings, sensor readings, and JSON messages. This demonstrates the practical application of the write() method for IoT communications, remote monitoring, and data logging 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 data 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:
* Simple UDP Data Sender that demonstrates write() method usage
* for transmitting various types of data to a remote UDP endpoint.
* This example shows how to connect to a remote UDP server and send
* different data types including strings, numbers, JSON, and binary data.
* It demonstrates practical IoT communication patterns and real-world
* applications of UDP data transmission using the AsyncUDP library.
*
* Features Demonstrated:
* - UDP connection establishment using connect()
* - Data transmission using write() method
* - Multiple data format transmission (text, JSON, binary)
* - Sensor data simulation and transmission
* - Connection status monitoring and error handling
* - Automatic reconnection on connection failure
* - Data transmission statistics and monitoring
*
* 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>
#include <ArduinoJson.h>
// WiFi credentials
const char* ssid = "your_SSID"; // Replace with your Wi-Fi SSID
const char* password = "your_PASSWORD"; // Replace with your Wi-Fi password
// 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.0;
float humidity = 60.0;
int lightLevel = 512;
bool ledState = false;
void setup() {
Serial.begin(115200);
Serial.println("ESP32 UDP Data Sender - write() 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
String welcomeMsg = "ESP32 UDP Sender Connected - Device: " + WiFi.macAddress();
size_t sent = udp.write((uint8_t*)welcomeMsg.c_str(), welcomeMsg.length());
Serial.printf("Welcome message sent: %d bytes\n", sent);
} else {
Serial.println("Failed to connect to UDP endpoint");
isConnected = false;
}
Serial.println("Starting data transmission...");
Serial.println("==============================");
}
void loop() {
static unsigned long lastSend = 0;
static int dataType = 0;
// Send data 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 data based on cycle
switch (dataType % 5) {
case 0:
sendTextMessage();
break;
case 1:
sendSensorData();
break;
case 2:
sendJSONData();
break;
case 3:
sendBinaryData();
break;
case 4:
sendSystemInfo();
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 sendTextMessage() {
String message = "Hello from ESP32! Message #" + String(messageCounter) +
" | Time: " + String(millis()/1000) + "s" +
" | Free Heap: " + String(ESP.getFreeHeap()) + "b";
size_t sent = udp.write((uint8_t*)message.c_str(), message.length());
Serial.printf("[%lu] Text Message Sent: %d bytes\n", messageCounter, sent);
Serial.printf("Content: %s\n", message.c_str());
Serial.println("─────────────────────────────────────────");
}
void sendSensorData() {
String sensorData = "SENSOR_DATA|" + String(temperature, 2) + "|" +
String(humidity, 1) + "|" + String(lightLevel) + "|" +
String(ledState ? "ON" : "OFF");
size_t sent = udp.write((uint8_t*)sensorData.c_str(), sensorData.length());
Serial.printf("[%lu] Sensor Data 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.println("─────────────────────────────────────────");
}
void sendJSONData() {
// Create JSON document
DynamicJsonDocument doc(256);
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();
String jsonString;
serializeJson(doc, jsonString);
size_t sent = udp.write((uint8_t*)jsonString.c_str(), jsonString.length());
Serial.printf("[%lu] JSON Data Sent: %d bytes\n", messageCounter, sent);
Serial.printf("JSON: %s\n", jsonString.c_str());
Serial.println("─────────────────────────────────────────");
}
void sendBinaryData() {
// Create binary data packet
struct {
uint32_t messageId;
uint32_t timestamp;
float temperature;
float humidity;
uint16_t lightLevel;
uint8_t ledState;
int8_t wifiRSSI;
uint32_t freeHeap;
} binaryPacket;
binaryPacket.messageId = messageCounter;
binaryPacket.timestamp = millis();
binaryPacket.temperature = temperature;
binaryPacket.humidity = humidity;
binaryPacket.lightLevel = lightLevel;
binaryPacket.ledState = ledState ? 1 : 0;
binaryPacket.wifiRSSI = WiFi.RSSI();
binaryPacket.freeHeap = ESP.getFreeHeap();
size_t sent = udp.write((uint8_t*)&binaryPacket, sizeof(binaryPacket));
Serial.printf("[%lu] Binary Data Sent: %d bytes\n", messageCounter, sent);
Serial.printf("Binary packet size: %d bytes\n", sizeof(binaryPacket));
Serial.println("─────────────────────────────────────────");
}
void sendSystemInfo() {
String systemInfo = "SYSTEM|" + String(ESP.getChipModel()) + "|" +
String(ESP.getCpuFreqMHz()) + "MHz|" +
String(ESP.getFreeHeap()) + "b|" +
String(ESP.getFlashChipSize()) + "b|" +
String(WiFi.RSSI()) + "dBm";
size_t sent = udp.write((uint8_t*)systemInfo.c_str(), systemInfo.length());
Serial.printf("[%lu] System Info Sent: %d bytes\n", messageCounter, sent);
Serial.printf("Content: %s\n", systemInfo.c_str());
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("║ 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.println("══════════════════════════════════════════════════");
}Testing Example: UDP Data Receiver
This companion example demonstrates how to create a UDP receiver that listens for data sent by the previous example. This receiver ESP32 will display all incoming UDP data in various formats, allowing you to verify that the write() method is working correctly. The receiver provides detailed parsing of different data types including text messages, sensor data, JSON, and binary packets.
How to test with two ESP32 boards:
- Setup the Receiver: Upload this “UDP Data Receiver” code to your first ESP32 and note its IP address from the Serial Monitor.
- Setup the Sender: Upload the previous “UDP Data 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 data transmission and reception in real-time.
- Verify Data: Compare sent data on sender with received data 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 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!