stevie135s
Published © GPL3+

Web Radio

Internet radio on a TTGO T-Display controlled by a bluetooth android phone app

IntermediateWork in progress5,886
Web Radio

Things used in this project

Hardware components

Arduino ESP32 TTGO T-Display
×1
UDA1334A Dac Module
×1
HC-05 Bluetooth Module
HC-05 Bluetooth Module
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Custom parts and enclosures

Web Radio v9

Android app.. upload and install to phone
Version 9..Just cosmetic changes

Schematics

Circuit

Connection Details

Code

URL_Zips

C/C++
URL Lists.. Unzip to the same folder as the INO.. just includes EOF at the end of each list
No preview (download only).

Web_Radio V10

Arduino
Update to calculate the size of each URL array
// UPDATED 3  SIZEOF NOW CALCULATES ELEMENTS (NOT BYTES)IN ARRAY
// UPDATED 2  INCLUDE APP GENRES and URL SETUP ON OPENING OF APP
// UPDATED 1  APP VERSION WITH VOLUME DISPLAY AND 60 CHAR URL

// IF YOU HAVE PREVIOUS CODE VERSIONS YOU NEED TO REFLASH
// IF YOU HAVE PREVIOUS ANDROID VERSION YOU NEED TO UNINSTALL IT

#include "Arduino.h"
#include <TFT_eSPI.h>
#include <WiFi.h>
#include <Audio.h> //https://github.com/schreibfaul1/ESP32-audioI2S
#include "Trance.h"
#include "Lounge.h"
#include "UK.h"
#include "Talk.h"
#include "Dance.h"
#include "Disco.h"
#include <SoftwareSerial.h> // This is the ESPSoftwareserial Version https://github.com/plerup/espsoftwareserial/


#define I2S_DOUT      25 // Preset I2S pins on the ESP32
#define I2S_BCLK      27
#define I2S_LRC       26

SoftwareSerial serialBT;

int CH_Pointer = 0;
int OLD_Pointer = 0;
int Volume = 15;
int action = -1;
int Genres = 1;
const String Spc = "                                                            ";
String Str = Spc;
String Str1;
int Sizeof;
int SizeofTrance;
int SizeofDance;
int SizeofDisco;
int SizeofLounge;
int SizeofTalk;
int SizeofUK;


#define blue 0x5D9B
#define darkred 0xA041

TFT_eSPI tft = TFT_eSPI(); // Invoke Custom Library
Audio audio;

String ssid =     "********";
String password = "********";


void setup() {
  Serial.begin(115200);
    int i = 0;
    while (Dance_Stations[i] != "EOF") {
      i++;
    }
    SizeofDance = i;
    i = 0;
    while (Disco_Stations[i] != "EOF") {
      i++;
    }
    SizeofDisco = i;
    i = 0;
        while (Lounge_Stations[i] != "EOF") {
      i++;
    }
    SizeofLounge = i;
    i = 0;
    while (Talk_Stations[i] != "EOF") {
      i++;
    }
    SizeofTalk = i;
    i = 0;
        while (Trance_Stations[i] != "EOF") {
      i++;
    }
    SizeofTrance = i;
    i = 0;
        while (UK_Stations[i] != "EOF") {
      i++;
    }
    SizeofUK = i;
    Sizeof = SizeofTrance;
    Serial.println(SizeofDance);
    Serial.println(SizeofDisco);
    Serial.println(SizeofLounge);
    Serial.println(SizeofTalk);
    Serial.println(SizeofTrance);
    Serial.println(SizeofUK);
  

    serialBT.begin(9600,SWSERIAL_8N1,13,12,false); // Bluetooth device name
    tft.init();
    tft.setRotation(3);
    tft.fillScreen(TFT_BLACK);
    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(Volume); // 0...21
    CH_Change();

}

void loop(){

  action = serialBT.read();
  if (action > 0) {
    if (action < 7) {
      Genres = action ;
      CH_Pointer = 0;
      OLD_Pointer = 0;
      serialBT.print("1"); // Print URL
      CH_Change();
    }
    else {
      switch (action) {
        case 8:                  //App request for Genres and url
        serialBT.print(Genres);
        serialBT.print(Str.substring(0,60)); //Send URL info to app
        
        break;
        
        case 11:
        if (Volume > 0 ) {
          Volume--;
          audio.setVolume(Volume);
        }
          Str1 = String(Volume) + "  ";
          serialBT.print( Str1.substring(0,2));  // Send Volume level to phoone

         break;

        case 12:        
        if (Volume < 21) {
          Volume++;
          audio.setVolume(Volume);
        }
          Str1 = String(Volume) + "  ";
          serialBT.print( Str1.substring(0,2));  // Send Volume level to phoone

        break;

        case 13:
        if (CH_Pointer > 0) {
          CH_Pointer--;
          serialBT.print("1"); // Print URL
        }
        else {
        serialBT.print("0"); // Don't print URL
        }
        
        break;

        case 14:
        if (CH_Pointer < Sizeof) {
          CH_Pointer++;
          serialBT.print("1"); // Print URL
        }
        else {
          serialBT.print("0"); // Don't print URL
        }
        
        break;

        case 16 :
        audio.pauseResume();
        break;
        
      }

  if (OLD_Pointer != CH_Pointer) {
    OLD_Pointer = CH_Pointer;
    CH_Change();

          }

       }

    }


    audio.loop();
  
    }

void CH_Change() {
    audio.stopSong();
    tft.setTextColor(TFT_WHITE,TFT_BLACK);
    tft.setTextSize(3);
    tft.setCursor(10,10);
    tft.print("PLEASE WAIT                                                     ");
    tft.setCursor(10,10);    


  
  switch(Genres) {
    case 1:

    Str = String(Trance_Stations [CH_Pointer])+ Spc;
    serialBT.print(Str.substring(0,60));
    audio.connecttohost(Trance_Stations[CH_Pointer].c_str());
    Sizeof = SizeofTrance;
    tft.fillScreen(TFT_BLACK);
    tft.print("TRANCE");
    tft.setCursor(130,10);
    tft.println(CH_Pointer);
    tft.setTextColor(blue,TFT_BLACK);
    tft.setTextSize(2);
    tft.println(Trance_Stations [CH_Pointer]);
//    Serial.println(tft.getCursorY());
break;

    case 2:

    Str = String(Lounge_Stations [CH_Pointer])+ Spc;
    serialBT.print(Str.substring(0,60));
    audio.connecttohost(Lounge_Stations[CH_Pointer].c_str());
    Sizeof = SizeofLounge;
    tft.fillScreen(TFT_BLACK);
    tft.print("LOUNGE");
    tft.setCursor(130,10);
    tft.println(CH_Pointer);
    tft.setTextColor(blue,TFT_BLACK);
    tft.setTextSize(2);
    tft.println(Lounge_Stations [CH_Pointer]);
break;

    case 3:

    Str = String(UK_Stations [CH_Pointer])+ Spc;
    serialBT.print(Str.substring(0,60));
    audio.connecttohost(UK_Stations[CH_Pointer].c_str());
    Sizeof = SizeofUK;
    tft.fillScreen(TFT_BLACK);
    tft.print("UK");
    tft.setCursor(130,10);
    tft.println(CH_Pointer);
    tft.setTextColor(blue,TFT_BLACK);
    tft.setTextSize(2);
    tft.println(UK_Stations [CH_Pointer]);
break;

    case 4:

    Str = String(Talk_Stations [CH_Pointer])+ Spc;
    serialBT.print(Str.substring(0,60));
    audio.connecttohost(Talk_Stations[CH_Pointer].c_str());
    Sizeof = SizeofTalk;
    tft.fillScreen(TFT_BLACK);
    tft.print("TALK");
    tft.setCursor(130,10);
    tft.println(CH_Pointer);
    tft.setTextColor(blue,TFT_BLACK);
    tft.setTextSize(2);
    tft.println(Talk_Stations [CH_Pointer]);   
break;

    case 5:

    Str = String(Dance_Stations [CH_Pointer])+ Spc;
    serialBT.print(Str.substring(0,60));
    audio.connecttohost(Dance_Stations[CH_Pointer].c_str());  
    Sizeof = SizeofDance;
    tft.fillScreen(TFT_BLACK);
    tft.print("DANCE");
    tft.setCursor(130,10);
    tft.println(CH_Pointer);
    tft.setTextColor(blue,TFT_BLACK);
    tft.setTextSize(2);
    tft.println(Dance_Stations [CH_Pointer]);
break;
    
    case 6:

    Str = String(Disco_Stations [CH_Pointer])+ Spc;
    serialBT.print(Str.substring(0,60));
    audio.connecttohost(Disco_Stations[CH_Pointer].c_str());  
    Sizeof = SizeofDisco;
    tft.fillScreen(TFT_BLACK);
    tft.print("DISCO");
    tft.setCursor(130,10);
    tft.println(CH_Pointer);
    tft.setTextColor(blue,TFT_BLACK);
    tft.setTextSize(2);
    tft.println(Disco_Stations [CH_Pointer]);
break;
  
  }
 
}


// 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){
  if (tft.getCursorY() < 100) {
    tft.setTextColor(TFT_WHITE,TFT_BLACK);
    tft.print(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);
}
*/

Credits

stevie135s

stevie135s

21 projects • 10 followers

Comments