I got my ESP32 on my local home WiFi network, but it doesn't respond to anything yet. The next step is to write code so it could act as a static web server, sending files stored in ESP32 flash memory to clients requesting them via HTTP GET. The good news is that setting up a HTTP server was really easy, and I quickly got it up and running to serve a "Hello World" string hard-coded in my ESP32 source code.

I briefly considered calling this situation good enough and move on. I could embed my HTML/CSS/JavaScript files as hard-coded strings inside my C files. But doing so meant reviewing those files to make sure they don't have conflicts with C string syntax, and that's something I'd have to do every time I wanted to update any of those files. This is quite clumsy. What I really want is to keep those files to be served over HTTP separate from my C code, so that they could be updated independently of code and I don't have to review them for C string incompatibility.

Doing this requires carving out a portion of an ESP32's flash memory storage for a simple file storage system called SPIFFS. Allocation of flash storage is declared in a partition file, which is a list of comma-separated values (CSV) of partition information like size, offset, and assigned purpose. PlatformIO ESP-IDF project template includes a default partition file but it had no provision for a SPIFFS partition. I need to add one to my project to override that default. I found an example partition file as my starting point, copying it into my project and making only minor changes. (I didn't need quite as large of a SPIFFS partition.) If I were using ESP-IDF directly, I believe I would use the menuconfig tool to point to my partition file. But as I'm using ESP-IDF indirectly via PlatformIO, I specified my partition file location using a parameter in the platformio.ini configuration file.

Once I have a partition, I need to put my files in it. Apparently it's not as simple as using a USB flash drive, I have to build the entire data partition (like building a disk image for a PC) and upload the whole thing. There are ESP-IDF command line tools to build SPIFFS partition, I decided to go with PlatformIO route by specifying the platformio.ini parameter data-dir. I could point it at my Node.js working directory, which is great because that meant I only had one copy of these files in my code repository. Eliminating the task of keeping multiple copies in sync. From the PlatformIO UI I could then use "Platform/Build Filesystem Image" followed by "Platform/Upload Filesystem Image". I haven't figured out if this is necessarily separate from code update or if there's a way to do both at the same time.

Putting files in SPIFFS isn't useful until I have code to read those files. I followed the links to Espressif code example for reading and writing to SPIFFS. And ugh... I haven't had to deal with old school C file input/output API in quite some time. I briefly considered the effort to keep things memory efficient by breaking these file I/O actions up into small pieces, but I don't need that kind of sophistication just yet. In order to simplify code, and because I have RAM to spare at the moment, I allocated a large buffer so all the operations to read from SPIFFS and send via HTTP can be done in a single pass. Which worked well for sending data to the control client, but now I need to listen to control commands coming back.

[Code for this project is publicly available on GitHub.]