Serve complex websites or webapps from a ESP32 module, is that even possible?
With the ESP32 module you can quickly and easily Encode and decode Base64 strings (what is Base64?). This can be achieved by integrating the external C-class base64.h.
Anyone who has ever programmed a web server in Arduino IDE, knows the pain and how ugly the whole thing gets quickly. Let’s look at the following example. This is the HTML-Code to display two buttons.
There has to be some solution to program whole webpage stuff outside of Arduino IDE and in the end copy it somehow to the ESP module.
The idea is to encode the whole website into a Base64 string and save it as a c++ string in Arduino IDE. If the website is requested from a client, the corresponding Base64 string is decoded and sent directly to the client.
Since the ESP32 is supporting hardware encoding and decoding of base64 strings through crypto, we should be able to do this quickly on the fly.
This has the advantage that we’re able to develop the website or webapp in parallel and e.g. if necessary, we can automatically convert the source into a Base64 code via a custom interface. From there you can integrate it into Arduino IDE. If changed, the files can be edited natively as HTML or JavasScript. You just have to replace the updated string in the Arduino IDE.
A quick test has shown that this works. Is this also possible for larger websites? To keep up the motivation we took an HTML5 game. The code comes from https://github.com/nebez/floppybird and has been adapted by us so that it can be delivered completely in one file. First of all, the following must be done:
- Include all external CSS codes in the HTML page
- Convert all images to data-uris
- Convert all audio files to data-uris
You can create data URIs online in various places, for example here: https://www.browserling.com/tools/file-to-base64
At last, you have a single HTML file that contains all the elements of the website. We went ahead and encoded the whole website into a base64 string. Aaaaaand…. unfortunately, the test failed. Apparently the string is too long for ESP32 to encode it and the module resets after a crash. Too little RAM?
So back into the IDE and divide the code into smaller pieces. To be able to make changes easily in the future, the code is divided as follows:
Since the main.js file (which we renamed into game for convenience), also contains the audio files (+/- 10kB each), we unfortunately have to split this file as well.
The splitted files are all minimized (if not already done) . You can do taht easily in duckduckgo.com. To do this, just type “js minifier” in duckduckgo and you will get a form where you can minimize the code:
The minimized code is then converted into a Base64 code. For example here: https://www.base64encode.org/
Now the whole Base64 codes are stored as a string and decoded and served at the appropriate place in the program to the client.
Looks a lot neater, doesn’t it? And that’s all for a website with a size of about 500kB and over 50 files!
The finished code can be found on Github including the individual program parts: https://github.com/janhajk/esp32_flappybird
You can load the ino-file via Arduino-IDE to your ESP32 module after you have adapted your wifi data accordingly. Or you can change the code so that you can access the ESP32 module directly with the wifi of your device. You either give your device the IP yourself via your network administration or it will be assigned automatically and is printed in the Arduino ide Serial Monitor. Now enter the IP in your browser and start playing!
With SPIFFS you can create a Filesystem on your ESP32 Modul and upload the HTML, CSS and JS files directly to it. Here’s an example on how to do this: https://randomnerdtutorials.com/esp32-web-server-spiffs-spi-flash-file-system/