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 from 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).
  • Controlled by means of 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 a TFT display.
  • 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.
  • 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.

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:

  1. audio byte – will be sent to a ringbuffer that feeds the VS1053 decoder
  2. metadata byte – a human readable character from the song title
  3. metadata size – an integer; multiplied by 16, it is the following song title’s length
  4. CR or LF – used as separators
  5. chunk size (if station uses chunked transfer encoding) – size of the next chunk

Keep streaming

While still in an early stage of research for my Internet Radio (previous post), I came across Ed Smallenburg’s comprehensive Esp-radio project on github. It’s a very well documented project with a heavily commented sketch.

Instead of proceeding with my own (basic) Internet radio project, I decided to take Ed’s nearly flawless Esp-radio as a starting point, and adapt it according to my personal needs. Most important change will be the addition of two small oled displays for emulating analog VU meters.

There’s also an (even better?) version for ESP32 by the same author. This persuaded me to finally enter the ESP32 world, so now I’m the proud owner of a Wemos LOLIN32 Pro. My hope is that this powerful dual core board will be able to drive the entire setup of radio, TFT touch display, IR remote and VU meter oleds.


Unfortunately, my Wemos LOLIN32 Pro is from a batch with a faulty serial chip (CP2104). Most of the time, my PC will not recognize the board when I connect it, resulting in the serial chip becoming very hot within 5 seconds. This is my fourth Wemos device, two of which were crap!

However, when the board is recognized, it works fine and I even managed to upload and run the ESP32-Radio sketch. As for performance, I would say that both versions (ESP8266 and ESP32) seem equally satisfying and stable.

Below is a screenshot of the web interface. I removed and changed some buttons from the original version, and added a “now playing” display that updates every two seconds.

My futher plans with an ESP32 based Internet radio will have to wait for the replacement of my board. Planned changes are mainly peripheral and cosmetic, like adding VU-meters and a frequency analyzer. To be continued (stay tuned…)

Stream it!


The purchase of this versatile breakout board from Adafruit immediately made me put on hold all my ongoing projects. May the stream be with me!


This breakout board, built around the VS1053B chip, decodes various digital (stereo) audio formats such as MP3, AAC, Ogg Vorbis, WMA, MIDI, FLAC, WAV (PCM and ADPCM), and sends the analog signal to a female headphone plug (included as a breadboard friendly separate part). It can also record audio in both PCM (WAV) and compressed Ogg Vorbis format. All functions can be controlled over SPI.

Other features of the breakout board are:

  • microSD card holder for storing audio files
  • works with 3.3V and 5V boards (5V compliant pins)
  • 8 digital GPIO pins (not 5V compliant)
  • Volume, bass and treble control
  • a microphone input port
  • MIDI mode (reads MIDI data on the UART pin)
  • Additional functions (e.g. spectrum analyzer and VU meters) available via plugins

I had noticed the board before, but what made me decide to purchase it was this very simple esp8266 Internet Radio sketch on the Adafruit site. The fact that the VS1053 chip can handle mp3 live streams, delivered by an esp8266, means that it can be used for building a music streamer/internet radio! Since the esp8266 is capable of acting as a web client and a web server at the same time, it should be possible (in theory) to control the player with any web device (apart from several additional options, like buttons, IR remotes, rotary encoders, keypads, joysticks…).

After soldering the included header pins, I started with some simple MP3 playback from an SD card. My vintage Sennheiser Ovation was impressed! Then, with great expectations, I ran the Internet Radio sketch…. No sound! Not even debug messages on the serial monitor. Although Adafruit only, my hardware wasn’t from their new Feather/Wing line, for which the sketch was written. After quite some desperate attempts, almost losing hope, out of the blue came Bob Dylan’s “there must be some way out of here“. How appropriate (just as “something is happening, but you don’t know what it is” would have been). What did the trick was connecting the RST pins of the VS1053 and esp8266 boards, although the Adafuit example sketch suggests otherwise in the following line:


Here’s what I plan to do next:

  • Add a display (probably SPI, claiming two additional esp8266 pins; only one left…)
  • Make the esp8266 run a web server, listening to commands via a web page, very similar to the one I wrote for controlling my Transporter
  • Add manual control (buttons, IR, keypad?). The board’s own GPIO pins can be used for simple high/low devices like buttons
  • Support a list of selectable presets, pointing to internet radio stations
  • Make it possible to switch between radio mode and file mode (play ‘local’ music files)
  • Implement a larger (cyclic) buffer for more stability