A ESP32-CAM Captive Portal written in Arduino C++ (think airport Wi-Fi sign-in page) that works on all devices1 and enables wireless file sharing from an SD card.
This code is an example of a captive portal for the ESP32-CAM, using the AsyncTCP library. The code sets up a soft access point with the given SSID and no password and configures a DNS server to redirect all traffic to the captive portal web server running on the ESP32. The captive portal serves an HTML page with file sharing capabilities, allowing users to browse and download files from the connected SD card.
The code also includes some workarounds and documents limitations for different devices and browsers, such as a workaround for Windows 11 captive portal and limitations on the Safari (iOS) browser.
RAM: [= ] 11.6% (used 37976 bytes from 327680 bytes)
Flash: [== ] 22.6% (used 711089 bytes from 3145728 bytes)
- About 0.1s reload time using modern browsers and systems
- SD Card File Sharing: Browse and download files wirelessly from the ESP32-CAM's SD card
- Automatic SD Card Detection: Initializes and reports SD card status on boot
- Web-based File Browser: Simple interface to view all files on the SD card
- Cross-platform Compatibility: Works on all major operating systems and browsers
- Lots of comments that explain how it all works
The captive portal now includes an SD card file browser with a "View Files" link that displays all files stored on the connected SD card as downloadable links.
This is a simple all-in-one GUI tool that can be downloaded from here.
Download the firmware from the releases page and select the serial port from the dropdown menu. Press the "Flash ESP" button to flash the ESP32-CAM.
If you are running Windows, you will most likely need a driver from here before your computer will show the ESP32-CAM com port in the drop-down menu in ESPhome Flasher.
- Make sure Git client is installed on your system. You can install it from here.
- Download and install Visual Studio Code by Microsoft from here.
- Open Visual Studio Code and go to the Extensions manager (the icon with the stacked blocks in the left bar).
- Search for "platformio" and install the PlatformIO extension.
- Download the source code by running a git clone (Git GUI can be found in your right-click menu) with the link: https://github.com/CDFER/Captive-Portal-ESP32-CAM-File-Sharing.git in your projects folder.
- In VS Code, go to File -> Open Folder and open the root folder (the one that contains platformio.ini, NOT the src folder).
- Insert an SD card into the ESP32-CAM module before powering on for file sharing functionality.
- Upload to the ESP32-CAM using the right arrow button in the bottom left corner of VS Code (it takes a while for the first compile).
- Supported Cards: MicroSD cards (FAT32 formatted recommended)
- File Types: All file types supported for download
- Capacity: Tested with cards up to 32GB
- File Access: Files appear as clickable download links in the web interface
- Status Monitoring: SD card detection and initialization status displayed in Serial Monitor
| Status | Version | Connect | Popup | Serve Page | SD Card | OS | Device Name | Browser | Notes |
|---|---|---|---|---|---|---|---|---|---|
| ✅ | 0.5.0 | ✅ | ✅ | ✅ | ✅ | Win 11 Home (22H2) | 13600k Custom PC | Firefox | |
| ✅ | 0.5.0 | ✅ | ✅ | ✅ | ✅ | Win 11 Home (22H2) | 13600k Custom PC | Chrome | |
| ❌ | 0.5.0 | ❌ | ✅ | ✅ | ❓ | Android 11 (OxygenOS11) | OnePlus 6 | Default | Cellular must be off |
| ✅ | 0.5.0 | ✅ | ✅ | ✅ | ❓ | Android 9 (OneUI1) | Samsung A53 | Default | |
| ✅ | 0.5.0 | ✅ | ✅ | ✅ | ❓ | Win 11 Home (22H2) | XPS15 9550 | Firefox | |
| ✅ | 0.5.0 | ✅ | ✅ | ✅ | ❓ | Win 11 Home (22H2) | XPS15 9550 | Chrome | |
| ✅ | 0.4.0 | ✅ | ✅ | ✅ | ❓ | Ubuntu 22.04 | HP Pavilion PC | ||
| ✅ | 0.4.0 | ✅ | ✅ | ✅ | ❓ | iOS 16.2 | iPhone X | ||
| ✅ | 0.4.0 | ✅ | ✅ | ✅ | ❓ | Android 12 | Galaxy Tab A7 Lite | ||
| ✅ | 0.3.0 | ✅ | ❌ | ✅ | ❓ | macOS X (10.6.8) | MacBook Air (2011) | Safari | |
| ✅ | 0.3.0 | ✅ | ❌ | ✅ | ❓ | Windows 7 Starter | Toshiba NB200 | IE | |
| ✅ | 0.3.0 | ✅ | ✅ | ✅ | ❓ | iOS 9 (9.3.5) | iPad Mini (2012) | Default | |
| ✅ | 0.3.0 | ✅ | ✅ | ✅ | ❓ | iOS 10 (10.3.3) | iPhone 5c | Default | |
| ✅ | 0.2.0 | ✅ | ✅ | ✅ | ❓ | iPhone X | Default | thx @SNERTTT | |
| ✅ | 0.2.0 | ✅ | ✅ | ✅ | ❓ | Redmi Note 10 | Default | thx @SNERTTT | |
| ✅ | 0.2.0 | ✅ | ✅ | ✅ | ❓ | iOS 16 | iPhone XR | Default | |
| ❌ | 0.2.0 | ✅ | ❌ | ✅ | ❓ | MacOS Monterey (12.5.1) | MacBook Pro 16 2019 | Chrome | |
| ❌ | 0.2.0 | ✅ | ❌ | ✅ | ❓ | MacOS Monterey (12.5.1) | MacBook Pro 16 2019 | Safari | |
| ✅ | 0.1.0 | ✅ | ✅ | ✅ | ❓ | Win 10 Pro | XPS15 9575 | Edge | |
| ✅ | 0.1.0 | ✅ | ✅ | ✅ | ❓ | Win 10 Edu | XPS15 9570 | Edge | |
| ✅ | 0.1.0 | ✅ | ✅ | ✅ | ❓ | Android 12 (OneUI4.1) | Samsung S20 FE 5G | Default |
If you test this code on a device (even if it works), it would be really helpful if you fill out the form here.
- OnePlus 6 phone (Oxygen OS 11) sometimes gets stuck on setting client-side IP address when cellular is on.
- On older devices, you may need to open a web browser for it to display.
- Maximum of 4 clients connected at the same time.
- macOS post macOS Big Sur no popup.
- SD Card must be inserted before power-on for proper detection and file sharing functionality.
- Only FAT32 formatted SD cards have been tested for compatibility.
- Large files may take time to download depending on ESP32-CAM processing capabilities.
- If you have a lot of tabs open in Windows 11 (and probably other OS), it increases the load on the ESP32 DNS server.
- HTML webpage being served multiple times.
- Test on other ESP32 chip variants (all testing so far is on the ESP32 D0WDQ6 chip in the ESP32S module).
- Test increasing the maximum number of clients connected from 4 to the maximum supported 10.
- SD Card compatibility testing with various card sizes and brands.
- File download performance testing with different file sizes and types.
- Simultaneous file access testing with multiple clients.
- Set client DHCP IP address range in private space (currently, clients must accept DHCP Server Range: 4.3.2.2 to 4.3.2.12).
- Support integrating the DHCP or IPv6 Router Advertisement (RA) options for Captive Portals on iOS 14+ and macOS Big Sur+. More information
- Port WLED-WebInstaller.
- RCF 7710 DHCP option for captive portal detection. Issue
- File upload functionality to allow users to upload files to the SD card.
- File management features such as delete, rename, and create folders.
- Image/video preview capabilities leveraging ESP32-CAM functionality.
- File search and filtering options for better file organization.
- Progress indicators for large file downloads.
To support this and my future work, you can now purchase one of my own handmade CO2 sensors through my website: https://www.keastudios.co.nz.
This work was done as part of a project with Simon Ingram of Terrestrial Assemblages with the support of Govett-Brewster Art Gallery / Len Lye Centre.
Thanks to @me-no-dev and everyone at @Espressif Systems for making a really awesome chip and porting it to Arduino.
Thanks to @LTRTNZ for putting up with my never-ending shit, and @vincentd123 for helping me through this crazy year.
Footnotes
-
Note: It might not work on all devices due to various reasons such as captive portal detection algorithms, browser compatibility, and device limitations. ↩
