Hardware components | ||||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
Software apps and online services | ||||||
![]() |
|
I have used the code from my bluetooth Web Radio and made a version that doesn't require an android phone. The menu functions are accessed using 3 miniature switches.
I have used the ESP32 WROOM devkit wifi, (you'll need to edit the code and insert your wifi SSID and Password.) For display i have used the SSD1306 OLED (128x64). Make sure you are using the correct address. I have used the UDA1334 DAC because once it is set up properly, it sounds quite good using a decent amplifier.
The I2C pins are standard wire configuration for the ESP32 SCL = 22 .. SDA = 21. The I2S DAC also uses standard configuration so there should be no problem. I have found these DACS can be damaged easily by static so take care handling them.
The three buttons are Select, Down, and UP.. to navigate through the preset stations. The Audio library is a big buggy when it has no data from a given URL so just be patient when scanning up and down the presets.
Each preset has it's own header file. Edit these as you wish keeping to the format and leave the last entry as an EOF marker.
I will try to answer any questions or comments.
#include <Arduino.h>
#include <WiFi.h>
#include <Audio.h> //https://github.com/schreibfaul1/ESP32-audioI2S
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Fonts/FreeMonoBold9pt7b.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define I2S_DOUT 25
#define I2S_BCLK 27
#define I2S_LRC 26
#include "Trance.h"
#include "Lounge.h"
#include "UK.h"
#include "Talk.h"
#include "Dance.h"
#include "Disco.h"
#define OLED_RESET -1
#define SCREEN_ADDRESS 0x3C
Audio audio;
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
String ssid = "*********"; // Insert your own router SSID
String password = "*********"; // and Password
const byte Select = 4;
const byte Down = 5;
const byte Up = 18;
String Stations[] ={"Null","Lounge ","Trance ","Disco ","Talk ","UK ","Dance "};
int Trance = 0;
int Dance = 0;
int Disco = 0;
int Lounge =0;
int Talk = 0;
int UK = 0;
byte Menu_1 = 2;
int TEMP = 0;
void Menu_Draw() {
switch (Menu_1) {
case 1:
display.drawRect(0,0,70,17,SSD1306_WHITE);// Lounge
audio.connecttohost(Lounge_Stations[Lounge].c_str());
TEMP = Lounge;
break;
case 2:
display.drawRect(0,18,70,17,SSD1306_WHITE);// Trance
audio.connecttohost(Trance_Stations[Trance].c_str());
TEMP = Trance;
break;
case 3:
display.drawRect(0,36,60,17,SSD1306_WHITE);// Disco
audio.connecttohost(Disco_Stations[Disco].c_str());
TEMP = Disco;
break;
case 4:
display.drawRect(72,0,55,17,SSD1306_WHITE);// Talk
audio.connecttohost(Talk_Stations[Talk].c_str());
TEMP = Talk;
break;
case 5:
display.drawRect(72,18,55,17,SSD1306_WHITE);// UK
audio.connecttohost(UK_Stations[UK].c_str());
TEMP = UK;
break;
case 6:
display.drawRect(62,36,65,17,SSD1306_WHITE);// Dance
audio.connecttohost(Dance_Stations[Dance].c_str());
TEMP = Dance;
break;
}
}
void Menu_Undraw() {
switch (Menu_1) {
case 1:
display.drawRect(0,0,70,17,SSD1306_BLACK);// Lounge
break;
case 2:
display.drawRect(0,18,70,17,SSD1306_BLACK);// Trance
break;
case 3:
display.drawRect(0,36,60,17,SSD1306_BLACK);// Disco
break;
case 4:
display.drawRect(72,0,55,17,SSD1306_BLACK);// Talk
break;
case 5:
display.drawRect(72,18,55,17,SSD1306_BLACK);// UK
break;
case 6:
display.drawRect(62,36,65,17,SSD1306_BLACK);// Dance
break;
}
}
void setup() {
// Serial.begin(115200);
pinMode (Select,INPUT_PULLUP);
pinMode (Down,INPUT_PULLUP);
pinMode (Up,INPUT_PULLUP);
if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;); // Don't proceed, loop forever
}
WiFi.disconnect();
WiFi.mode(WIFI_STA);
WiFi.begin(ssid.c_str(), password.c_str());
while (WiFi.status() != WL_CONNECTED) delay(1500);
audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT);
audio.setVolume(12); // 0...21
display.setTextColor(SSD1306_WHITE);
display.clearDisplay();
display.setTextSize(2);
display.setCursor(0,0);
display.print("Trance ");
display.println(Trance);
display.setTextSize(1);
display.display();
audio.connecttohost(Trance_Stations[Trance].c_str());
}
void loop() {
if (!digitalRead(Select)) {
while (!digitalRead(Select)) {
}
Menu();
display.setFont();
display.clearDisplay();
display.setTextSize(2);
display.setCursor(0,0);
display.print(Stations[Menu_1]);
display.println(TEMP);
display.display();
display.setTextSize(1);
}
audio.loop();
switch (Menu_1) {
case 1:
Lounge_Select();
break;
case 2:
Trance_Select();
break;
case 3:
Disco_Select();
break;
case 4:
Talk_Select();
break;
case 5:
UK_Select();
break;
case 6:
Dance_Select();
break;
}
Trance_Select();
}
void Menu() {
display.setFont(&FreeMonoBold9pt7b);
display.clearDisplay();
display.setTextSize(1);
display.setCursor(0,12);
display.println("Lounge Talk");
display.println("Trance UK");
display.println("Disco Dance");
Menu_Draw();
display.display();
while (digitalRead(Select)) {
if (!digitalRead(Down)) {
while (!digitalRead(Down)) {
}
Menu_Undraw();
Menu_1++;
if (Menu_1 > 6) {
Menu_1 = 1;
}
Menu_Draw();
display.display();
}
if (!digitalRead(Up)) {
while (!digitalRead(Up)) {
}
Menu_Undraw();
Menu_1--;
if (Menu_1 < 1) {
Menu_1 = 6;
}
Menu_Draw();
display.display();
}
}
while (!digitalRead(Select)) {
}
}
void Dance_Select() {
if (!digitalRead(Down) && (Dance_Stations [Dance +1] != "EOF")) {
display.clearDisplay();
display.setTextSize(2);
display.setCursor(0,0);
while (!digitalRead(Down)) {
}
Dance++;
TEMP = Dance;
display.print("Dance ");
display.println(Dance);
display.display();
display.setTextSize(1);
audio.connecttohost(Dance_Stations[Dance].c_str());
}
if (!digitalRead(Up) && Dance) {
display.clearDisplay();
display.setTextSize(2);
display.setCursor(0,0);
while (!digitalRead(Up)) {
}
Dance--;
TEMP = Dance;
display.print("Dance ");
display.println(Dance);
display.display();
display.setTextSize(1);
audio.connecttohost(Dance_Stations[Dance].c_str());
}
}
void Disco_Select() {
if (!digitalRead(Down) && (Disco_Stations [Disco +1] != "EOF")) {
display.clearDisplay();
display.setTextSize(2);
display.setCursor(0,0);
while (!digitalRead(Down)) {
}
Disco++;
TEMP = Disco;
display.print("Disco ");
display.println(Disco);
display.display();
display.setTextSize(1);
audio.connecttohost(Disco_Stations[Disco].c_str());
}
if (!digitalRead(Up) && Disco) {
display.clearDisplay();
display.setTextSize(2);
display.setCursor(0,0);
while (!digitalRead(Up)) {
}
Disco--;
TEMP = Disco;
display.print("Disco ");
display.println(Disco);
display.display();
display.setTextSize(1);
audio.connecttohost(Disco_Stations[Disco].c_str());
}
}
void Lounge_Select() {
if (!digitalRead(Down) && (Lounge_Stations [Lounge +1] != "EOF")) {
display.clearDisplay();
display.setTextSize(2);
display.setCursor(0,0);
while (!digitalRead(Down)) {
}
Lounge++;
TEMP = Lounge;
display.print("Lounge ");
display.println(Lounge);
display.display();
display.setTextSize(1);
audio.connecttohost(Lounge_Stations[Lounge].c_str());
}
if (!digitalRead(Up) && Lounge) {
display.clearDisplay();
display.setTextSize(2);
display.setCursor(0,0);
while (!digitalRead(Up)) {
}
Lounge--;
TEMP = Lounge;
display.print("Lounge ");
display.println(Lounge);
display.display();
display.setTextSize(1);
audio.connecttohost(Lounge_Stations[Lounge].c_str());
}
}
void Trance_Select() {
if (!digitalRead(Down) && (Trance_Stations [Trance +1] != "EOF")) {
display.clearDisplay();
display.setTextSize(2);
display.setCursor(0,0);
while (!digitalRead(Down)) {
}
Trance++;
TEMP = Trance;
display.print("Trance ");
display.println(Trance);
display.display();
display.setTextSize(1);
audio.connecttohost(Trance_Stations[Trance].c_str());
}
if (!digitalRead(Up) && Trance) {
display.clearDisplay();
display.setTextSize(2);
display.setCursor(0,0);
while (!digitalRead(Up)) {
}
Trance--;
TEMP = Trance;
display.print("Trance ");
display.println(Trance);
display.display();
display.setTextSize(1);
audio.connecttohost(Trance_Stations[Trance].c_str());
}
}
void Talk_Select() {
if (!digitalRead(Down) && (Talk_Stations [Talk +1] != "EOF")) {
display.clearDisplay();
display.setTextSize(2);
display.setCursor(0,0);
while (!digitalRead(Down)) {
}
Talk++;
TEMP = Talk;
display.print("Talk ");
display.println(Talk);
display.display();
display.setTextSize(1);
audio.connecttohost(Talk_Stations[Talk].c_str());
}
if (!digitalRead(Up) && Talk) {
display.clearDisplay();
display.setTextSize(2);
display.setCursor(0,0);
while (!digitalRead(Up)) {
}
Talk--;
TEMP = Talk;
display.print("Talk ");
display.println(Talk);
display.display();
display.setTextSize(1);
audio.connecttohost(Talk_Stations[Talk].c_str());
}
}
void UK_Select() {
if (!digitalRead(Down) && (UK_Stations [UK +1] != "EOF")) {
display.clearDisplay();
display.setTextSize(2);
display.setCursor(0,0);
while (!digitalRead(Down)) {
}
UK++;
TEMP = UK;
display.print("UK ");
display.println(UK);
display.display();
display.setTextSize(1);
audio.connecttohost(UK_Stations[UK].c_str());
}
if (!digitalRead(Up) && UK) {
display.clearDisplay();
display.setTextSize(2);
display.setCursor(0,0);
while (!digitalRead(Up)) {
}
UK--;
TEMP = UK;
display.print("UK ");
display.println(UK);
display.display();
display.setTextSize(1);
audio.connecttohost(UK_Stations[UK].c_str());
}
}
// optional
//void audio_info(const char *info){
// display.print("info "); display.println(info);
// display.display();
//}
//void audio_id3data(const char *info){ //id3 metadata
// display.print("id3data ");display.println(info);
// display.display();
//}
//void audio_eof_mp3(const char *info){ //end of file
// display.print("eof_mp3 ");display.println(info);
// display.display();
//}
void audio_showstation(const char *info){
display.println(info);
display.display();
}
void audio_showstreamtitle(const char *info){
display.print("Title ");display.println(info);
display.display();
}
void audio_bitrate(const char *info){
display.print("bitrate ");display.println(info);
display.display();
}
//void audio_commercial(const char *info){ //duration in sec
// display.print("commercial ");display.println(info);
// display.display();
//}
//void audio_icyurl(const char *info){ //homepage
// display.print("icyurl ");display.println(info);
// display.display();
//}
//void audio_lasthost(const char *info){ //stream URL played
// display.print("lasthost ");display.println(info);
// display.display();
// }
Comments
Please log in or sign up to comment.