The basic process: set up the ESP32 as a server, then request the file over HTTP
To download a file from an ESP32 running Arduino code, you set up the ESP32 to host a web server that serves the file, then use an HTTP client — either on the ESP32 itself or on another device — to request and save that file. The ESP32 acts like a tiny web server; your computer or phone connects to it over WiFi and downloads the file the same way you would download from any website.
The most common setup is to store a file on the ESP32's SPIFFS (SPI Flash File System) or SD card, write Arduino code that creates an HTTP server, and then use a client to fetch the file. The client can be a web browser, a Python script, curl command, or another microcontroller.
Key Takeaways
- The ESP32 must run a web server sketch that reads the file from storage and sends it over HTTP when requested.
- Files are typically stored on the ESP32's SPIFFS or an attached SD card, and you upload them using the Arduino IDE's tools.
- A client device connects to the ESP32's IP address and requests the file using a URL path you define in your code.
- The ESP32 and client must be on the same WiFi network, or you must know the ESP32's IP address to connect.
- Download speed depends on WiFi signal strength and the file size; large files may take several seconds or longer.
Setting up file storage on the ESP32
Before you can serve a file, you need to store it on the ESP32. The two main options are SPIFFS (built into the ESP32's flash memory) and an SD card connected via SPI pins.
For SPIFFS, install the ESP32 filesystem uploader plugin in the Arduino IDE. In the Arduino IDE, go to Sketch → Show Sketch Folder, create a folder named data inside it, and place your files there. Then use Tools → ESP32 Sketch Data Upload to write the files to the ESP32's flash. This works for small files; SPIFFS typically has 1 to 4 MB available depending on your partition scheme.
For an SD card, wire the card module to the ESP32's SPI pins (usually GPIO 5 for CS, GPIO 18 for CLK, GPIO 23 for MOSI, GPIO 19 for MISO), then use the SD library included with the Arduino IDE. SD cards hold much more data and are easier to swap files in and out without reprogramming the ESP32.
Writing the server code to serve a file
Your Arduino sketch needs to include the WiFi library, the server library, and the filesystem library. Start by connecting the ESP32 to your WiFi network using WiFi.begin(ssid, password). Then create a web server object on a port like 80 (HTTP) using WebServer server(80).
Define a route that handles file requests. For example, server.on("/download", handleDownload) tells the server to call the handleDownload function when a client visits http://[ESP32-IP]/download. Inside that function, open the file from SPIFFS or SD card, read its contents, and send it back with the correct headers.
Here is a minimal example for SPIFFS:
void handleDownload() { File file = SPIFFS.open("/myfile.txt", "r"); if (!file) { server.send(404, "text/plain", "File not found"); return; } server.sendHeader("Content-Disposition", "attachment; filename=myfile.txt"); server.streamFile(file, "application/octet-stream"); file.close(); }
In your setup() function, initialize SPIFFS with SPIFFS.begin(), connect to WiFi, define your routes, and call server.begin(). In loop(), call server.handleClient() to process incoming requests.
Finding the ESP32's IP address and connecting
Once the server is running, you need to know the ESP32's IP address to connect to it. Add this code after WiFi connects to print the IP to the serial monitor:
Serial.print("IP address: "); Serial.println(WiFi.localIP());
Open the Arduino IDE's Serial Monitor (Tools → Serial Monitor) at 115200 baud to see the IP address printed when the ESP32 starts up. It will look something like 192.168.1.100.
On your computer or phone, open a web browser and type http://192.168.1.100/download (replace the IP and path with your actual values). The browser will download the file. Alternatively, use curl from a terminal: curl http://192.168.1.100/download -o myfile.txt.
Downloading files from another microcontroller or device
If you want another ESP32 or Arduino to download the file, use the HTTPClient library. Include #include <HTTPClient.h> and create an HTTP client object. Call http.begin(url) with the full URL, then http.GET() to request the file.
To save the file to the downloading device's storage, read the response stream and write it to SPIFFS or SD card in chunks. This is useful for firmware updates, logging data from one device to another, or syncing files across multiple ESP32 boards.
A Python script on a computer can also download from the ESP32 using the requests library: import requests; r = requests.get('http://192.168.1.100/download'); open('myfile.txt', 'wb').write(r.content). This is often simpler than writing Arduino code if you are testing or prototyping.
Troubleshooting common issues
If the browser shows "connection refused" or times out, check that the ESP32 is powered on, connected to WiFi, and the IP address is correct. Verify the IP in the serial monitor and try pinging it from your computer: ping 192.168.1.100. If the ping fails, the ESP32 is not reachable on the network.
If the file is not found, double-check the file path in your code. SPIFFS paths are case-sensitive and must start with a forward slash, like /myfile.txt. Verify that the file was actually uploaded to the ESP32 using the data upload tool, and check the serial monitor for any error messages during startup.
If the download is slow or incomplete, the WiFi signal may be weak. Move the ESP32 closer to the router or reduce interference from other devices. Large files over slow connections may time out; test with a small file first to confirm the setup works.
Frequently Asked Questions
Can I download a file without knowing the ESP32's IP address?
Not directly, but you can use mDNS (multicast DNS) to give the ESP32 a hostname. Add #include <ESPmDNS.h>, then call MDNS.begin("myesp32") in setup. You can then visit http://myesp32.local/download from any device on the same network without needing the IP address.
What is the maximum file size I can download?
SPIFFS is limited by the partition size you choose during upload, typically 1 to 4 MB. SD cards can hold gigabytes, but very large files may cause memory issues on the ESP32 itself. For files over 10 MB, stream the file in chunks rather than loading it all into RAM at once.
Can I password-protect the file download?
Yes. In your handler function, check for an Authorization header or a query parameter before serving the file. For example, check if the URL contains ?key=secret and only send the file if the key matches. This is basic security and not suitable for sensitive data; use HTTPS for real protection.
How do I download multiple files at once?
Define separate routes for each file, or create a single route that accepts a filename parameter. For example, server.on("/file", handleFile) and check server.arg("name") to see which file was requested. You can then serve different files based on the parameter.
Does the ESP32 stay connected to WiFi while serving files?
Yes, the ESP32 remains connected to WiFi and can serve files indefinitely as long as power is supplied and the code is running. The server loop handles one client at a time by default, so if multiple devices try to download simultaneously, they may experience delays.