IOT

Simple ESP32 Internet Web Radio with OLED Display

In this project, an ESP32 board, an audio expansion shield, and an OLED display will be used to create an ESP32 Web Internet Radio. The DAC chip and SD card module were carried over to the merged ESP32 Audio. You can play songs that are online thanks to the I2S chip. The scroll wheel switch on the Audio lets you switch and pause the music, while the SSD1306 screen shows basic song information.

Commercial internet radio receivers are fairly pricey, costing more than $100 on the market. So I made the decision to create a practical, affordable, and simple Internet radio. I had previously created an ESP32 Music Player, which performed admirably, so I chose to use the same hardware to create an Internet Radio.

Hardware Required

All the components required for this project can be easily purchased from Makerfabs. The components purchase link is given below.

S.N.COMPONENTS NAMEDESCRIPTION
1Customized ESP32 BoardMakePython ESP32 Board
2Audio Expansion BoardMakePython Audio Expansion
33D CasingESP32 Audio Fixture Kit
4SpeakersSpeaker with 3.5mm Audio Jack
55V Power SupplyPower Bank

Block Diagram of the ESP32 Web Radio

Below is a block diagram of the ESP32 Internet Radio. We use an ESP32 Audio Expansion Board and a customized ESP32 Module. The ESP32 connects to wifi and searches online data for the specified radio stations.

The project’s guiding concept is that if we can send a precise stream of 32 bytes worth of streaming data to the board, it will simply continue to play. In other words, the ESP32 must establish a fixed port connection to the streaming website and then receive the streaming data exactly 32 bytes at a time. On the other side, the stream will remain to play while the board keeps processing the data like an inflow/outflow machine.

Hardware Requirement & Assembly

We require a customized ESP32 Board for this project. A robust, generic Wifi+ BLE MCU module that supports both C/C++ and Python programming is called MakePython ESP32. With the extremely thorough pin explanation and actual “breadboard compatibility,” it is simple to understand and use. The Arduino IDE is used to program the MakePython ESP32.

A similar Audio Expansion Board is required. The UDA1334ATS audio DAC serves as the foundation for the Audio Expansion Board, which adds audio functionality to ESP projects. It outputs relatively high-quality audio and utilizes I2S to interact with the ESP32.

In addition to these modules, 3D Casing—which is made with 3D modeling software—is necessary. The 3D casing of the smartphone makes it svelte and portable. The STL files can be downloaded from this page.: 3D Case STL File

Assemble all the hardware explained in ESP32 Music Player.

ESP32 Web Internet Radio

Now your ESP32 Web Radio is ready to rock.

Adding Esp32-AudioI2S Library to Arduino IDE

ESP32 Audio’s UDA1334ATS IC does not enable MP3 hardware decoding. Therefore, MP3 decoding and volume control are done using this library. You may play MP3 stations straight from the Internet in addition to reading MP3 files from your SD card.

Download: ESP32-audioI2S Library

Source Code & Program

Upload the code to the ESP32 Board by copying it from the section below. There are certain changes to the code that must be made before uploading.

const char *ssid = “Alexahome”;
const char *password = “loranthus”;

Change the WiFi SSID & Paasword from the line above.

String stations[] = {
“0n-80s.radionetz.de:8000/0n-70s.mp3”,
“mediaserv30.live-streams.nl:8000/stream”,
“www.surfmusic.de/m3u/100-5-das-hitradio,4529.m3u”,
“stream.1a-webradio.de/deutsch/mp3-128/vtuner-1a”,
“mp3.ffh.de/radioffh/hqlivestream.aac”, // 128k aac
“www.antenne.de/webradio/antenne.m3u”,
“listen.rusongs.ru/ru-mp3-128”,
“edge.audio.3qsdn.com/senderkw-mp3”,
“macslons-irish-pub-radio.com/media.asx”};

Include a link to the radio stations you want to listen to or your local station. For instance, if I were visiting India and wanted to listen to Indian radio stations, I would include a link to Indian radio stations.

Here is the project’s complete source code.

#include “Arduino.h”
#include “Audio.h”
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

//Digital I/O used //Makerfabs Audio V2.0
#define I2S_DOUT 27
#define I2S_BCLK 26
#define I2S_LRC 25

//SSD1306
#define MAKEPYTHON_ESP32_SDA 4
#define MAKEPYTHON_ESP32_SCL 5
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

//Button
const int Pin_vol_up = 39;
const int Pin_vol_down = 36;
const int Pin_mute = 35;

const int Pin_previous = 15;
const int Pin_pause = 33;
const int Pin_next = 2;

Audio audio;

const char *ssid = “Alexahome”;
const char *password = “loranthus”;


struct Music_info
{
String name;
int length;
int runtime;
int volume;
int status;
int mute_volume;
} music_info = {“”, 0, 0, 0, 0, 0};

int volume = 21;
int mute_volume = 0;

int runtime = 0;
int length = 0;

String stations[] = {
“0n-80s.radionetz.de:8000/0n-70s.mp3”,
“mediaserv30.live-streams.nl:8000/stream”,
“www.surfmusic.de/m3u/100-5-das-hitradio,4529.m3u”,
“stream.1a-webradio.de/deutsch/mp3-128/vtuner-1a”,
“mp3.ffh.de/radioffh/hqlivestream.aac”, // 128k aac
“www.antenne.de/webradio/antenne.m3u”,
“listen.rusongs.ru/ru-mp3-128”,
“edge.audio.3qsdn.com/senderkw-mp3”,
“macslons-irish-pub-radio.com/media.asx”};
int station_index = 0;
int station_count = sizeof(stations) / sizeof(stations[0]);

void setup()
{
//IO mode init
pinMode(Pin_vol_up, INPUT_PULLUP);
pinMode(Pin_vol_down, INPUT_PULLUP);
pinMode(Pin_mute, INPUT_PULLUP);
pinMode(Pin_previous, INPUT_PULLUP);
pinMode(Pin_pause, INPUT_PULLUP);
pinMode(Pin_next, INPUT_PULLUP);

//Serial
Serial.begin(115200);

//LCD
Wire.begin(MAKEPYTHON_ESP32_SDA, MAKEPYTHON_ESP32_SCL);
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C))
{ // Address 0x3C for 128×32
Serial.println(F(“SSD1306 allocation failed”));
for (;;)
; // Don’t proceed, loop forever
}
display.clearDisplay();
logoshow();

//connect to WiFi
Serial.printf(“Connecting to %s “, ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(“.”);
}
Serial.println(” CONNECTED”);
lcd_text(“Wifi CONNECT”);

//Audio(I2S)
audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT);
audio.setVolume(21); // 0…21

open_new_radio(stations[station_index]);
}

uint run_time = 0;
uint button_time = 0;

void loop()
{
audio.loop();
print_song_time();

//Display logic
if (millis() – run_time > 1000)
{
run_time = millis();
display_music();
}

//Button logic
if (millis() – button_time > 300)
{
if (digitalRead(Pin_next) == 0)
{
Serial.println(“Pin_next”);
if (station_index < station_count – 1)
{
station_index++;
}
else
{
station_index = 0;
}
button_time = millis();
open_new_radio(stations[station_index]);
}
if (digitalRead(Pin_previous) == 0)
{
Serial.println(“Pin_previous”);
if (station_index > 0)
{
station_index–;
}
else
{
station_index = station_count – 1;
}
button_time = millis();
open_new_radio(stations[station_index]);
}
if (digitalRead(Pin_vol_up) == 0)
{
Serial.println(“Pin_vol_up”);
if (volume < 21)
volume++;
audio.setVolume(volume);
button_time = millis();
}
if (digitalRead(Pin_vol_down) == 0)
{
Serial.println(“Pin_vol_down”);
if (volume > 0)
volume–;
audio.setVolume(volume);
button_time = millis();
}
if (digitalRead(Pin_mute) == 0)
{
Serial.println(“Pin_mute”);
if (volume != 0)
{
mute_volume = volume;
volume = 0;
}
else
{
volume = mute_volume;
}
audio.setVolume(volume);
button_time = millis();
}
if (digitalRead(Pin_pause) == 0)
{
Serial.println(“Pin_pause”);
audio.pauseResume();
button_time = millis();
}
}

//Serial logic
if (Serial.available())
{
String r = Serial.readString();
r.trim();
if (r.length() > 5)
{
audio.stopSong();
open_new_radio(r);
}
else
{
audio.setVolume(r.toInt());
}
}
}

void print_song_time()
{
runtime = audio.getAudioCurrentTime();
length = audio.getAudioFileDuration();
}

void open_new_radio(String station)
{
audio.connecttohost(station);
runtime = audio.getAudioCurrentTime();
length = audio.getAudioFileDuration();
Serial.println(“**********start a new radio************”);
}

void display_music()
{
int line_step = 24;
int line = 0;
char buff[20];
;
sprintf(buff, “RunningTime:%d”,runtime);

display.clearDisplay();

display.setTextSize(1); // Normal 1:1 pixel scale
display.setTextColor(SSD1306_WHITE); // Draw white text

display.setCursor(0, line); // Start at top-left corner
display.println(stations[station_index]);
line += line_step * 2;

display.setCursor(0, line);
display.println(buff);
line += line_step;

display.display();
}

void logoshow(void)
{
display.clearDisplay();

display.setTextSize(2); // Normal 1:1 pixel scale
display.setTextColor(SSD1306_WHITE); // Draw white text
display.setCursor(0, 0); // Start at top-left corner
display.println(F(“My ESP32”));
display.setCursor(0, 20); // Start at top-left corner
display.println(F(“WEB` RADIO”));
display.setCursor(0, 40); // Start at top-left corner
display.println(F(“”));
display.display();
delay(2000);
}

void lcd_text(String text)
{
display.clearDisplay();

display.setTextSize(2); // Normal 1:1 pixel scale
display.setTextColor(SSD1306_WHITE); // Draw white text
display.setCursor(0, 0); // Start at top-left corner
display.println(text);
display.display();
delay(500);
}

//**********************************************
// optional
void audio_info(const char *info)
{
Serial.print(“info “);
Serial.println(info);
}
void audio_id3data(const char *info)
{ //id3 metadata
Serial.print(“id3data “);
Serial.println(info);
}

void audio_eof_mp3(const char *info)
{ //end of file
Serial.print(“eof_mp3 “);
Serial.println(info);
}
void audio_showstation(const char *info)
{
Serial.print(“station “);
Serial.println(info);
}
void audio_showstreaminfo(const char *info)
{
Serial.print(“streaminfo “);
Serial.println(info);
}
void audio_showstreamtitle(const char *info)
{
Serial.print(“streamtitle “);
Serial.println(info);
}
void audio_bitrate(const char *info)
{
Serial.print(“bitrate “);
Serial.println(info);
}
void audio_commercial(const char *info)
{ //duration in sec
Serial.print(“commercial “);
Serial.println(info);
}
void audio_icyurl(const char *info)
{ //homepage
Serial.print(“icyurl “);
Serial.println(info);
}
void audio_lasthost(const char *info)
{ //stream URL played
Serial.print(“lasthost “);
Serial.println(info);
}
void audio_eof_speech(const char *info)
{
Serial.print(“eof_speech “);
Serial.println(info);
}

Open the Serial Monitor once the code has been uploaded. When you log in, you will see the information below.

ESP32 Web Radio Test & Demo

By simply turning the device ON after the code has been uploaded to the ESP32 Board, you can begin testing the device. Check to see if the device is logged into the WiFi network.

ESP32 Internet Radio

Your Internet radio powered by the ESP32 is now ready. It’s now appropriate to tune into the radio. So, connect the 3.5mm audio jack to the speaker or headphones. The ESP32 Audio Player Board, as well as the Speaker, can both be powered by the power bank.

When powered on, the gadget will begin playing the preset radio station. The fundamental data is shown on the OLED Display screen.

ESP32 Web Radio

The lower side switch can be pressed or moved to the left or right to change the radio station. To pause, press it inward. The switch on the left is for volume control and muting. Slide it up to increase volume, and slide it down to decrease volume. You may also silence by pressing in.

Conclusion

Hope this blog helps you to understand how to design a Simple ESP32 Internet Web Radio with OLED Display. We, MATHA ELECTRONICS will come back with more informative blogs.

Leave a Reply

Your email address will not be published.