"HiFi" Online Radio V2: WebUI for Remote Control + Dynamic File Loading (via PlatformIO)
by Shadowilla in Circuits > Microcontrollers
53 Views, 0 Favorites, 0 Comments
"HiFi" Online Radio V2: WebUI for Remote Control + Dynamic File Loading (via PlatformIO)


Hi everyone! If you are here, you have probably already seen (and hopefully built!) my previous project. There, I showed how to make a Music Streamer using ESP32 + VS1053 as the main hardware, using the Arduino IDE interface.
In Step 4 of that instructable, I mention a few things I planned to add over time. Well, that time has come, and now I have made some of those upgrades, which are mainly:
- A Web UI to control the radio.
- The ability to update your radio stream list using a txt file, so there's no need to rebuild and upload code every time you add or change a streaming URL.
- *** Pending *** Switching to an ESP32 board with PSRAM for better performance.
To implement these upgrades, I moved from Arduino IDE (and '.ino' files) to PlatformIO IDE ('.cpp' files). Although I recently started using this tool, I can see the potential compared to the Arduino IDE, which is good for simple projects or when you are starting out in the microcontroller world. But as projects become more complex, PlatformIO certainly is a step-up along the way. And if you are already used to using the Arduino IDE, switching to PlatformIO won't be too difficult.
As an extra result of this subproject, there are some improvements. For example:
- a) An easier way to upload files (be it Stream URLs, or HTML files)
- b) An easier way to change configurable variables
- c) Better structured code, written with proper C++ practices in mind
So, let's get started!!
Supplies
If you are building this from scratch, this is the hardware used on the original project and that is completely valid for this one. For details on how to build it, check out the original post, but use the new code and instructions from here.
- ESP32 (I used ESP32-WROOM-32U so I could connect an external WiFi antenna to it)
- Optional (not used in the original project): ESP32-S3 with PSRAM.
- VS1053 MP3 Module
- TFT (for this project I used 1.8 inch 128x160 TFT)
- Buttons
- WiFi Antenna (with PCI U.FL IPX connector to attach to ESP 32U model)
- IR Receiver
- Cables
- Solder iron
Optionals (but really useful):
- Proto PCBs (to mount ESP and buttons)
- JST plugs (to avoid some soldering and ease connection/interchange of components)
- Glue gun
- Some skills (wood, metal, plastic) for the case
- Multimeter (to check voltages and continuity to avoid shortcircuits). I recommend 2 models: one very light and portable (UT120C), one more robust (UT139C)
The New Files
Here's the link to a compressed file with the essential code to test this instructable with the hardware listed above and using the GPIO indicated in the source file (and in the diagram of my previous post).
From Arduino IDE to PlatformIO IDE




Switching from Arduino IDE to PlatformIO IDE is actually very simple.
The first thing to do is to download VS Code and then install the PlatformIO extension. There are plenty of tutorials on the internet on how to do this, so I won't go into detail here, but it’s very straightforward!!
Once you have the PlatformIO extension installed in VS Code -and if you already built this project- migrating from your old '.ino' file is really simple. If this is your first time building the project, you can use the code from this instructable right away! Check the pictures from this section if something is not clear below.
First you must create a folder for your new (updated) project with any name you want. Here's the basic structure of this new folder:
- Inside the "data" folder, we'll place any extra files that we want to upload to our project (such as the radio presets file, the HTML of our web UI, etc.).
- Inside the "lib" folder, we'll include all the libraries that are specific and custom to our hardware. In this case, I'm including only the VS1053, TFT and IRremote libraries, since they have custom files for my hardware configuration. All the generic libraries (like WebServer, Preferences, etc.) are added automatically. If there's a special library that can be updated without disrupting your code and is not included automatically, you can add it to a configuration file (check point 4).
- Inside the "src" folder, we'll put our OLD '.ino' file, and rename it to 'main', and its extension to '.cpp', so your code will be shown as 'main.cpp' (check Step 5 for more details).
- In the root folder, we’ll place the platformio.ini file, which contains some basic configuration settings for the project. This file is automatically created when you start a new PlatformIO project.
Ok! Now you have your basic folder structure complete. Now, we'll open VS Code and select the PlatformIO icon on the left and then click on 'Pick a folder'. Select the folder we created and VS Studio will create a new Workspace for our project. New files will be created automatically in our folder (we don't need to do anything with them).
And at least for this project, that's it!
Upload Extra Files



Before uploading the main code, we'll upload our aux. files. In this case there are two:
- The list of radio presets of our preference
- The Web UI file(s)
The main benefit of this, is that with this method we don't need to rebuild and upload our entire code every time we make a change to these 2 files. I'll explain the method with 1 file, but it's exactly the same for the other or every side file that we want to upload. Now our code is clean, and we don't need to modify it as we update our radios/webpage.
So first, in our PlatformIO workspace, we select the file we want to upload manually. The selection of the correct file is very important!! So in our example, we'll upload the index.html that handles our Web UI (check the photos in this section).
Then, with the file SELECTED, we go to the PlatformIO icon, and go to:
Project Tasks -> esp32dev -> Platform -> Upload Filesystem Image
As soon as you click that option, the file will upload automatically. The terminal will show if the task was successfully completed.
And that's it! If you want to upload a different file (or the same with modifications) at any time, repeat the process.
Build & Upload!

Once you've done all the previous steps, build and upload the code to your hardware and enjoy these new changes right away!!
For Those Who Made Their Own Project - Important!! (Code Changes)
OK, you have your ".ino" file from your old project that you changed (only in name, same content inside) to "main.cpp". Now, we need to edit the code just a little bit to make it work (you can do it directly in VS Code by selecting the file from the folder tree or using another text editor.
PlatformIO IDE is a little less forgiving than Arduino IDE regarding the order of our variable declarations, functions, etc.
You'll have to re-order your code, so it can work properly. Nothing can go after "setup" or "loop", since all the things you call them from there must have already been declared in the previous lines of the code: each variable or function must have been declared 'above' before you are able to call them. So check the order of everything in your code before building and uploading. If not, errors will appear!
Also, for the upgrades I'm making, some things must be changed regarding the old code. There are a few tweaks here and there to help me with the new functions, but the main changes I made are:
Custom Variables:
Besides changing the order of variables and functions from my old ino file included in the original instructable, I took the opportunity to improve the code a little bit and left all modifiable variables at the beginning of the code. So now, if you have different hardware or want to try new things, you can change them directly at the beginning of the code, without messing with it.
Radio Presets:
There's no need to declare Radio Presets inside the code like this:
Now, they are put in a txt file and uploaded separately (see Step 3). We 'read' them from our file each time our hardware resets, using a 'vector':
If you use a different name for your 'radio presets' file, you'll have to change the name in this part of the code too.
Here, we have to add a little tweak to our function that connects to a given radio:
Now, we only have to worry about having our radio presets file up to date, leaving the code untouched.
Web Functions
First, we need to upload an 'index.html' file (like the 'radiopresets.txt' file from the previous paragraph) in the same way indicated in Step 3. Here you'll have the web page with the design of your choosing, so you can control this radio from any Web Browser. I've added a file so you can try it and modify it as you please.
I created a 'main server' function which stores a subset of functions that will make our Web UI work properly. The main functions in this part are:
- Initialization of the index.html file, with the webdesign of our choosing
- Handling of data relevant from our radio: Station Name, Song Name, Bitrate
- Handling of buttons in our Web UI: Next, Previous, Volume Bar, Mute
- Handling our manual inputs from the Web UI
- Initialization of the server
This main function is called as soon as the WiFi is connected.
You can get creative and add your own functions too!! Just remember to make these additions in the code AND in the HTML file.
Setup & Loop
In the 'Setup', we only added the initialization of LittleFS that will load our 'radio presets' file previously uploaded. The rest of the setup remains the same versus the old code.
In the Loop, we only added the initialization to check any HTTP client request for our Web UI:
Other minor changes were done to some functions, where I included new 'border conditions', so the Web UI could work properly.
And that's it! You should have your code working with these new additions without any trouble!
Final Thoughts
The only issue I have encountered with this modifications, is that the performance decreased a little bit with bitrates > 128kbps. It seems that RAM plays an important role with the web server handling, so the streaming got hurt in the process. A pending task I have (that I'll update in this same instructable) is to use an ESP with more RAM.
If you find something else, or have any comments or proposals, please let me know in the comments!!
Also, let me know if you did it (from scratch or a built project) and share your results!