Home / References / ESP32 Library / WebServer Library
Description
The sendContent_P()
method is a powerful function in the ESP32 WebServer Library designed to send content stored in PROGMEM (program memory) to a client as part of an HTTP response. This method is particularly useful for serving static content, such as HTML, CSS, or JavaScript, efficiently by leveraging the ESP32’s flash memory, reducing RAM usage. It is ideal for projects where memory optimization is key, allowing makers to deliver web content seamlessly.
Syntax and Usage
The sendContent_P()
method can be used in two distinct ways depending on whether you need to specify the content length explicitly. Below are the available syntaxes:
- Without Length Argument: Sends PROGMEM content without specifying its size, relying on the method to determine the length automatically using
strlen_P()
. - With Length Argument: Sends PROGMEM content with an explicitly defined size, giving you precise control over the data being transmitted.
Here’s how to use it in code:
void sendContent_P(PGM_P content);
void sendContent_P(PGM_P content, size_t size);
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.
Argument(s)
- content (PGM_P): A pointer to the data stored in PROGMEM. This argument specifies the content to be sent to the client. It must be defined using the
PROGMEM
keyword to ensure it resides in flash memory. - size (size_t, optional): The length of the content in bytes. This argument is used only in the second syntax variant to explicitly define how many bytes of the PROGMEM content should be sent. If omitted, the method calculates the length automatically.
Return Value
The sendContent_P()
method does not return a value. It directly writes the specified PROGMEM content to the current client connection as part of the HTTP response. If the operation fails (e.g., due to a disconnected client), it will silently terminate without throwing an error, as it operates within the WebServer’s client handling context.
Example Codes
Example: Using sendContent_P() Without Length Argument
This code demonstrates how to use the ESP32 WebServer Library’s sendContent_P()
method to serve HTML content stored in PROGMEM. This technique helps to conserve RAM on the ESP32 by storing static HTML content in flash memory.
To use this code, replace “your-SSID” and “your-PASSWORD” with your Wi-Fi credentials. After uploading the code to your ESP32, open the Serial Monitor to find the ESP32’s IP address. Then, open a web browser and navigate to that IP address to view the HTML content served from PROGMEM.
/*
* Author: Avant Maker
* Date: March 17, 2025
* Version: 1.0
* License: MIT
*
* Description:
* This example demonstrates how to use ESP32 WebServer Library's
* sendContent_P() method to server HTML content stored in PROGMEM,
* which helps conserve RAM on your ESP32 device.
*
* 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.
*/
/*
ESP32 WebServer sendContent_P Example
This sketch demonstrates how to use the sendContent_P method of the ESP32 WebServer
library to serve web content stored in program memory (PROGMEM). This approach
helps conserve RAM when serving larger static content like HTML pages.
Created for AvantMaker.com
*/
#include <WiFi.h>
#include <WebServer.h>
// Network credentials
const char* ssid = "your_SSID"; // Replace with your Wi-Fi SSID
const char* password = "your_PASSWORD"; // Replace with your Wi-Fi password
// Web server on port 80
WebServer server(80);
// HTML content stored in program memory (PROGMEM)
// This helps to save RAM as the HTML is stored in flash memory instead
const char MAIN_page[] PROGMEM = R"rawliteral(
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ESP32 PROGMEM Content Example</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
background-color: #f8f9fa;
color: #333;
}
.container {
max-width: 800px;
margin: 0 auto;
background-color: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
h1 {
color: #0066cc;
text-align: center;
}
.section {
margin-bottom: 20px;
padding: 15px;
background-color: #e9f7fe;
border-radius: 5px;
}
.footer {
text-align: center;
margin-top: 30px;
font-size: 0.8em;
color: #666;
}
</style>
</head>
<body>
<div class="container">
<h1>AvantMaker ESP32 WebServer sendContent_P Demo</h1>
<div class="section">
<h2>About This Example</h2>
<p>This page demonstrates how the ESP32 WebServer library's <code>sendContent_P</code> method works.
The entire HTML content is stored in PROGMEM (program memory) rather than RAM, which is
especially important when serving larger web pages.</p>
</div>
<div class="section">
<h2>Benefits of Using PROGMEM</h2>
<ul>
<li>Conserves precious RAM</li>
<li>Allows serving larger web pages</li>
<li>No need to allocate dynamic memory for content</li>
<li>More stable operation with less chance of memory fragmentation</li>
</ul>
</div>
<div class="section">
<h2>ESP32 Status</h2>
<p>WiFi SSID: %SSID%</p>
<p>IP Address: %IP%</p>
<p>Free Heap: %HEAP% bytes</p>
<p>Uptime: %UPTIME% seconds</p>
</div>
<div class="footer">
<p>Created for AvantMaker.com - Your Premier Hub for DIY, AI, IoT, and STEM Innovation</p>
</div>
</div>
</body>
</html>
)rawliteral";
// Function to handle root path
void handleRoot() {
String html = FPSTR(MAIN_page); // Convert PROGMEM content to String
// Replace placeholders with dynamic values
html.replace("%SSID%", String(ssid));
html.replace("%IP%", WiFi.localIP().toString());
html.replace("%HEAP%", String(ESP.getFreeHeap()));
html.replace("%UPTIME%", String(millis() / 1000));
// Set content type
server.setContentLength(html.length());
server.send(200, "text/html", ""); // Send the header but no content yet
// Send content in chunks using sendContent_P
// For demonstration, we'll split the content into chunks of 1024 bytes
const int chunkSize = 1024;
for (size_t i = 0; i < html.length(); i += chunkSize) {
// Calculate the size of this chunk
size_t currentChunkSize = html.length() - i;
if (currentChunkSize > chunkSize) {
currentChunkSize = chunkSize;
}
// Create a temporary buffer for this chunk
char chunk[chunkSize + 1];
html.substring(i, i + currentChunkSize).toCharArray(chunk, currentChunkSize + 1);
// Send the chunk
server.sendContent(chunk);
}
}
// Alternative function showcasing direct use of sendContent_P with PROGMEM data
void handleDirectPROGMEM() {
// Set content type
server.send(200, "text/html", ""); // Send only headers
// Send content directly from PROGMEM
// This method sends the entire content at once
server.sendContent_P(MAIN_page);
}
// Function to handle 404 Not Found
void handleNotFound() {
String message = "File Not Found\n\n";
message += "URI: ";
message += server.uri();
message += "\nMethod: ";
message += (server.method() == HTTP_GET) ? "GET" : "POST";
message += "\nArguments: ";
message += server.args();
message += "\n";
for (uint8_t i = 0; i < server.args(); i++) {
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
}
server.send(404, "text/plain", message);
}
void setup() {
Serial.begin(115200);
delay(1000);
// Connect to Wi-Fi
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
// Print connection details
Serial.println("");
Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
// Setup server routes
server.on("/", handleRoot);
server.on("/direct", handleDirectPROGMEM); // Alternative route showing direct PROGMEM usage
server.onNotFound(handleNotFound);
// Start server
server.begin();
Serial.println("HTTP server started");
}
void loop() {
server.handleClient();
// Add any additional background processing here
}
ESP32 Library Index
- ESP32 WiFi Library
- ESP32 WiFiClient Library
- ESP32 HTTPClient Library
- ESP32 WiFiClientSecure Library
- ESP32 WebServer Library
- Server Operation
- Client Hnadling
- Routing and Handlers
- Authentication
- Request 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!