A minimalistic Internet Radio

1. Motivation

In the previous project I dealt with the I2S subsystem of the esp8266. During the research I found interesting applications like MP3 decoder, LED driver, Internet Radio. The first thing I realized was the internet radio, because it requires minimal hardware.

2. Parts

3. Wiring

            
                           Vext (5..25V) o-----+-------o            
                                              _|_      | /|
                                              / \     |¨| |       
    WEMOS D1 R2                               ¨|¨     |_| | Speaker             
  ----------------.                            |       | \|
                  |                            +-------o
                  |                                    |
                  |                                |¦--' N-CH MOSFET
                  |                                |¦<-. T40N03G
      GPIO_3 / RX o-- audio out ---> Vin o----+----|¦--|     
                  |                           |        |          
                  |                          |¨|       |    
                  |   pushbtn                |_| 10k   |  
                  |   _I_                     |        |      
      GPIO_0 / D3 o---o o---- GND    GND o----+--------'              
                  | 
  ----------------´  
  

4. User interface

I chosed the same single pushbutton operation as in the previous project. The radio stations are stored in an array with name and URL. The clicks with the push button select a station from that list forward or backwards. A double click shows the currently played station.

5. Program Code

The program is based on Earle Philhowers ESP8266audio library and is an adaption of his example code StreamMP3FromHTTP. Check out his examples and you'll be rewarded with an overwhelming amount of food for thought.

The program excerpt shows only the setup() routine and the main loop, in which the MP3 stream of the radio station is played and the button.loop() handles the user interactions.

			
  /**
   * Initialize audio output and start playing
   */
  void initAudio()
  {
    audioLogger = &Serial;
    #ifdef EXTERNAL_DAC
      out = new AudioOutputI2S();  // with external MAX98357 DAC/amplifier
    #else
      out = new AudioOutputI2SNoDAC();
    #endif
    startPlaying();
  }

  /**
   * First, preallocate all the memory needed for 
   * the buffering and codecs, never to be freed
   */
  void initBuffers()
  {
    preallocateBuffer = malloc(preallocateBufferSize);
    preallocateCodec  = malloc(preallocateCodecSize);
    if (!preallocateBuffer || !preallocateCodec) 
    {
      Serial.printf("FATAL ERROR:  Unable to preallocate %d bytes for app\n", 
	                preallocateBufferSize+preallocateCodecSize);
      while (true) delay(1000); // Infinite halt
    }
  }
  
  void setup()
  {
    Serial.begin(115200);
    delay(1000);
    initBuffers();
    initWiFi();
    initAudio();
  }

  void loop()
  {
    if (decoder && decoder->isRunning()) 
    {
      playStream(false);
    }
    button.loop();
  }
			

Interested? Please download the entire program code. The zip-file contains the complete PlatformIO project.

My programming environment is not the native Arduino™ IDE but PlatformIO™ on top of Microsoft's Visual Studio Code™. This combination offers many advantages and allows a much better structuring of the code into several modules especially when we adopt The Object Oriented way.