Internet radio on a TTGO T-Display controlled by a Bluetooth app for Android phone
Devices and components
UDA1334A DAC module
HC-05 Bluetooth Module
ESP32 TTGO T-Screen
Software and tools
Arduino IDE
Project description
Web_RadioV10
arduino
Update to calculate the size of each URL array
1
2// UPDATED 3 SIZEOF NOW CALCULATES ELEMENTS (NOT BYTES)IN ARRAY
3// UPDATED 2 INCLUDE APP GENRES and URL SETUP ON OPENING OF APP
4// UPDATED 1 APP VERSION WITH VOLUME DISPLAY AND 60 CHAR URL
5
6// IF YOU HAVE PREVIOUS CODE VERSIONS YOU NEED TO REFLASH
7// IF YOU HAVE PREVIOUS ANDROID VERSION YOU NEED TO UNINSTALL IT
8
9#include "Arduino.h"
10#include <TFT_eSPI.h>
11#include <WiFi.h>
12#include <Audio.h> //https://github.com/schreibfaul1/ESP32-audioI2S
13#include "Trance.h"
14#include "Lounge.h"
15#include "UK.h"
16#include "Talk.h"
17#include "Dance.h"
18#include "Disco.h"
19#include <SoftwareSerial.h> // This is the ESPSoftwareserial Version https://github.com/plerup/espsoftwareserial/
20
21
22#define I2S_DOUT 25 // Preset I2S pins on the ESP32
23#define I2S_BCLK 27
24#define I2S_LRC 26
25
26SoftwareSerial serialBT;
27
28int CH_Pointer = 0;
29int OLD_Pointer = 0;
30int Volume = 15;
31int action = -1;
32int Genres = 1;
33const String Spc = " ";
34String Str = Spc;
35String Str1;
36int Sizeof;
37int SizeofTrance;
38int SizeofDance;
39int SizeofDisco;
40int SizeofLounge;
41int SizeofTalk;
42int SizeofUK;
43
44
45#define blue 0x5D9B
46#define darkred 0xA041
47
48TFT_eSPI tft = TFT_eSPI(); // Invoke Custom Library
49Audio audio;
50
51String ssid = "********";
52String password = "********";
53
54
55void setup() {
56 Serial.begin(115200);
57 int i = 0;
58 while (Dance_Stations[i] != "EOF") {
59 i++;
60 }
61 SizeofDance = i;
62 i = 0;
63 while (Disco_Stations[i] != "EOF") {
64 i++;
65 }
66 SizeofDisco = i;
67 i = 0;
68 while (Lounge_Stations[i] != "EOF") {
69 i++;
70 }
71 SizeofLounge = i;
72 i = 0;
73 while (Talk_Stations[i] != "EOF") {
74 i++;
75 }
76 SizeofTalk = i;
77 i = 0;
78 while (Trance_Stations[i] != "EOF") {
79 i++;
80 }
81 SizeofTrance = i;
82 i = 0;
83 while (UK_Stations[i] != "EOF") {
84 i++;
85 }
86 SizeofUK = i;
87 Sizeof = SizeofTrance;
88 Serial.println(SizeofDance);
89 Serial.println(SizeofDisco);
90 Serial.println(SizeofLounge);
91 Serial.println(SizeofTalk);
92 Serial.println(SizeofTrance);
93 Serial.println(SizeofUK);
94
95
96 serialBT.begin(9600,SWSERIAL_8N1,13,12,false); // Bluetooth device name
97 tft.init();
98 tft.setRotation(3);
99 tft.fillScreen(TFT_BLACK);
100 WiFi.disconnect();
101 WiFi.mode(WIFI_STA);
102 WiFi.begin(ssid.c_str(), password.c_str());
103 while (WiFi.status() != WL_CONNECTED) delay(1500);
104 audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT);
105 audio.setVolume(Volume); // 0...21
106 CH_Change();
107
108}
109
110void loop(){
111
112 action = serialBT.read();
113 if (action > 0) {
114 if (action < 7) {
115 Genres = action ;
116 CH_Pointer = 0;
117 OLD_Pointer = 0;
118 serialBT.print("1"); // Print URL
119 CH_Change();
120 }
121 else {
122 switch (action) {
123 case 8: //App request for Genres and url
124 serialBT.print(Genres);
125 serialBT.print(Str.substring(0,60)); //Send URL info to app
126
127 break;
128
129 case 11:
130 if (Volume > 0 ) {
131 Volume--;
132 audio.setVolume(Volume);
133 }
134 Str1 = String(Volume) + " ";
135 serialBT.print( Str1.substring(0,2)); // Send Volume level to phoone
136
137 break;
138
139 case 12:
140 if (Volume < 21) {
141 Volume++;
142 audio.setVolume(Volume);
143 }
144 Str1 = String(Volume) + " ";
145 serialBT.print( Str1.substring(0,2)); // Send Volume level to phoone
146
147 break;
148
149 case 13:
150 if (CH_Pointer > 0) {
151 CH_Pointer--;
152 serialBT.print("1"); // Print URL
153 }
154 else {
155 serialBT.print("0"); // Don't print URL
156 }
157
158 break;
159
160 case 14:
161 if (CH_Pointer < Sizeof) {
162 CH_Pointer++;
163 serialBT.print("1"); // Print URL
164 }
165 else {
166 serialBT.print("0"); // Don't print URL
167 }
168
169 break;
170
171 case 16 :
172 audio.pauseResume();
173 break;
174
175 }
176
177 if (OLD_Pointer != CH_Pointer) {
178 OLD_Pointer = CH_Pointer;
179 CH_Change();
180
181 }
182
183 }
184
185 }
186
187
188 audio.loop();
189
190 }
191
192void CH_Change() {
193 audio.stopSong();
194 tft.setTextColor(TFT_WHITE,TFT_BLACK);
195 tft.setTextSize(3);
196 tft.setCursor(10,10);
197 tft.print("PLEASE WAIT ");
198 tft.setCursor(10,10);
199
200
201
202 switch(Genres) {
203 case 1:
204
205 Str = String(Trance_Stations [CH_Pointer])+ Spc;
206 serialBT.print(Str.substring(0,60));
207 audio.connecttohost(Trance_Stations[CH_Pointer].c_str());
208 Sizeof = SizeofTrance;
209 tft.fillScreen(TFT_BLACK);
210 tft.print("TRANCE");
211 tft.setCursor(130,10);
212 tft.println(CH_Pointer);
213 tft.setTextColor(blue,TFT_BLACK);
214 tft.setTextSize(2);
215 tft.println(Trance_Stations [CH_Pointer]);
216// Serial.println(tft.getCursorY());
217break;
218
219 case 2:
220
221 Str = String(Lounge_Stations [CH_Pointer])+ Spc;
222 serialBT.print(Str.substring(0,60));
223 audio.connecttohost(Lounge_Stations[CH_Pointer].c_str());
224 Sizeof = SizeofLounge;
225 tft.fillScreen(TFT_BLACK);
226 tft.print("LOUNGE");
227 tft.setCursor(130,10);
228 tft.println(CH_Pointer);
229 tft.setTextColor(blue,TFT_BLACK);
230 tft.setTextSize(2);
231 tft.println(Lounge_Stations [CH_Pointer]);
232break;
233
234 case 3:
235
236 Str = String(UK_Stations [CH_Pointer])+ Spc;
237 serialBT.print(Str.substring(0,60));
238 audio.connecttohost(UK_Stations[CH_Pointer].c_str());
239 Sizeof = SizeofUK;
240 tft.fillScreen(TFT_BLACK);
241 tft.print("UK");
242 tft.setCursor(130,10);
243 tft.println(CH_Pointer);
244 tft.setTextColor(blue,TFT_BLACK);
245 tft.setTextSize(2);
246 tft.println(UK_Stations [CH_Pointer]);
247break;
248
249 case 4:
250
251 Str = String(Talk_Stations [CH_Pointer])+ Spc;
252 serialBT.print(Str.substring(0,60));
253 audio.connecttohost(Talk_Stations[CH_Pointer].c_str());
254 Sizeof = SizeofTalk;
255 tft.fillScreen(TFT_BLACK);
256 tft.print("TALK");
257 tft.setCursor(130,10);
258 tft.println(CH_Pointer);
259 tft.setTextColor(blue,TFT_BLACK);
260 tft.setTextSize(2);
261 tft.println(Talk_Stations [CH_Pointer]);
262break;
263
264 case 5:
265
266 Str = String(Dance_Stations [CH_Pointer])+ Spc;
267 serialBT.print(Str.substring(0,60));
268 audio.connecttohost(Dance_Stations[CH_Pointer].c_str());
269 Sizeof = SizeofDance;
270 tft.fillScreen(TFT_BLACK);
271 tft.print("DANCE");
272 tft.setCursor(130,10);
273 tft.println(CH_Pointer);
274 tft.setTextColor(blue,TFT_BLACK);
275 tft.setTextSize(2);
276 tft.println(Dance_Stations [CH_Pointer]);
277break;
278
279 case 6:
280
281 Str = String(Disco_Stations [CH_Pointer])+ Spc;
282 serialBT.print(Str.substring(0,60));
283 audio.connecttohost(Disco_Stations[CH_Pointer].c_str());
284 Sizeof = SizeofDisco;
285 tft.fillScreen(TFT_BLACK);
286 tft.print("DISCO");
287 tft.setCursor(130,10);
288 tft.println(CH_Pointer);
289 tft.setTextColor(blue,TFT_BLACK);
290 tft.setTextSize(2);
291 tft.println(Disco_Stations [CH_Pointer]);
292break;
293
294 }
295
296}
297
298
299// optional
300/*
301void audio_info(const char *info){
302 Serial.print("info "); Serial.println(info);
303}
304void audio_id3data(const char *info){ //id3 metadata
305 Serial.print("id3data ");Serial.println(info);
306}
307void audio_eof_mp3(const char *info){ //end of file
308 Serial.print("eof_mp3 ");Serial.println(info);
309}
310*/
311void audio_showstation(const char *info){
312 if (tft.getCursorY() < 100) {
313 tft.setTextColor(TFT_WHITE,TFT_BLACK);
314 tft.print(info);
315 }
316}
317/*
318void audio_showstreamtitle(const char *info){
319 Serial.print("streamtitle ");Serial.println(info);
320}
321void audio_bitrate(const char *info){
322 Serial.print("bitrate ");Serial.println(info);
323}
324void audio_commercial(const char *info){ //duration in sec
325 Serial.print("commercial ");Serial.println(info);
326}
327void audio_icyurl(const char *info){ //homepage
328 Serial.print("icyurl ");Serial.println(info);
329}
330void audio_lasthost(const char *info){ //stream URL played
331 Serial.print("lasthost ");Serial.println(info);
332}
333void audio_eof_speech(const char *info){
334 Serial.print("eof_speech ");Serial.println(info);
335}
336*/
337
URL_Zips
URL lists.. Unzip into the same folder as INO.. simply include EOF at the end of each list.
1inary file (no preview
Downloadable files
Circuit
Connection details
Circuit
Documentation
Note: Content and images are from: https://projecthub.arduino.cc/, with some modifications.
If you want it removed due to copyright reasons, please leave a comment. Thank you.
I want to share this article more widely so that everyone knows about Arduino and your project.