Instead of adapting an existing Internet Radio project to my needs (like support for air traffic control stations), I decided that it would be easier to write my own sketch from scratch. I’m satisfied with the first results, and I learned a lot during this project.
Keypad controlled prototype in radio mode (left) and ATC mode (right)
The radio runs without problems on a Wemos D1 R2, driving an Adafruit VS1053 breakout and a 2.4″ ili9341 TFT display. It can be controlled with a 16-key matrix keypad (the pictures show a Wemos D1 Mini Pro, but its wifi turned out to be too slow for some stations).
The prototype uses almost 500 lines of code for the radio. David Bird’s excellent METAR functions take yet another 500 lines. Too big to post on this page, I’m afraid…
It has the following features (more will be added later):
- Can play mp3 encoded streams from internet radio stations (up to 320 Kbps).
- Built in webserver accepts control commands via a browser.
- Can also be controlled with a 4×4 matrix keypad, using VS1053’s own GPIO pins.
- Offers storage of 40 station presets (grouped in four bands).
- Displays station name and song title on TFT display and web page.
- Displays a decoded weather report (METAR) when playing an air traffic control (ATC) channel. The first 10 stations in the preset list are reserved for ATC stations (I used David Bird’s excellent functions for METAR decoding).
- A 30 Kbyte ring buffer is used for smooth playback.
- Can play stations with redirected urls.
- Designed to handle chunked transfer encoded streams if necessary (I was unable to test this, because I couldn’t find any station that uses this encoding).
- Stereo dB levels can be read directly from the chip and be used to drive VU meters from PWM pins (or DACs on ESP32).
Below is a flow chart of the initial connection, followed by the streaming process (basically a finite state machine). In practice, it all comes down to determining each incoming byte’s function within the stream by keeping track of some counters and states. Once the actual streaming has started, an incoming byte can be one of the next types:
- audio byte – will be sent to a ringbuffer that feeds the VS1053 decoder
- metadata byte – a human readable character from the song title
- metadata size – an integer; multiplied by 16, it is the following song title’s length
- CR or LF – used as separators
- chunk size (if station uses chunked transfer encoding) – size of the next chunk