|
| 1 | +#include <WiFi.h> |
| 2 | +#include <AudioFileSource.h> |
| 3 | +#include <AudioFileSourceBuffer.h> |
| 4 | +#include <AudioFileSourceICYStream.h> |
| 5 | +#include <AudioGeneratorTalkie.h> |
| 6 | +#include <AudioGeneratorMP3.h> |
| 7 | +#include <AudioOutputI2S.h> |
| 8 | +#include <AudioOutputI2SNoDAC.h> |
| 9 | +#include <TFT_eSPI.h> // Graphics and font library for ST7735 driver chip |
| 10 | +#include <SPI.h> |
| 11 | +#include <spiram-fast.h> |
| 12 | + |
| 13 | +#include "frame.h" |
| 14 | + |
| 15 | +#include "background.h" |
| 16 | +#include "Orbitron_Medium_20.h" |
| 17 | + |
| 18 | +TFT_eSPI tft = TFT_eSPI(); // Invoke library, pins defined in User_Setup.h |
| 19 | +#define TFT_GREY 0x5AEB // New colour |
| 20 | + |
| 21 | +const int pwmFreq = 5000; |
| 22 | +const int pwmResolution = 8; |
| 23 | +const int pwmLedChannelTFT = 0; |
| 24 | + |
| 25 | +const char *SSID = "WiFimodem-2A13"; |
| 26 | +const char *PASSWORD = "hornugle112b"; |
| 27 | +const int bufferSize = 16 * 1024; // buffer in byte, default 16 * 1024 = 16kb |
| 28 | +char * arrayURL[1] = { |
| 29 | + "http://192.168.1.69:8000/radio.mp3" |
| 30 | +}; |
| 31 | + |
| 32 | +String arrayStation[1] = { |
| 33 | + "Mega Shuffle" |
| 34 | +}; |
| 35 | + |
| 36 | +const int LED = 10; // GPIO LED |
| 37 | +const int BTNA = 0; // GPIO Play and Pause |
| 38 | +const int BTNB = 35; |
| 39 | +const int BTNC = 12; |
| 40 | +const int BTND = 17; |
| 41 | +// GPIO Switch Channel / Volume |
| 42 | + |
| 43 | +AudioGeneratorTalkie *talkie; |
| 44 | +AudioGeneratorMP3 *mp3; |
| 45 | +AudioFileSourceICYStream *file; |
| 46 | +AudioFileSourceBuffer *buff; |
| 47 | +AudioOutputI2S *out; |
| 48 | + |
| 49 | +const int numCh = sizeof(arrayURL)/sizeof(char *); |
| 50 | +bool TestMode = false; |
| 51 | +uint32_t LastTime = 0; |
| 52 | +int playflag = 0; |
| 53 | +int ledflag = 0; |
| 54 | +//int btnaflag = 0; |
| 55 | +//int btnbflag = 0; |
| 56 | +float fgain = 10; //sæt gain her! lars |
| 57 | +int sflag = 0; |
| 58 | +char *URL = arrayURL[sflag]; |
| 59 | +String station = arrayStation[sflag]; |
| 60 | + |
| 61 | +int backlight[5] = {10,30,60,120,220}; |
| 62 | +byte b=2; |
| 63 | +int press1=0; |
| 64 | +int press2=0; |
| 65 | +bool inv=0; |
| 66 | + |
| 67 | +void setup() { |
| 68 | + tft.init(); |
| 69 | + tft.setRotation(0); |
| 70 | + tft.setSwapBytes(true); |
| 71 | + tft.setFreeFont(&Orbitron_Medium_20); |
| 72 | + tft.fillScreen(TFT_BLACK); |
| 73 | + tft.pushImage(0, 0, 135, 240, background); |
| 74 | + |
| 75 | + ledcSetup(pwmLedChannelTFT, pwmFreq, pwmResolution); |
| 76 | +// ledcAttachPin(TFT_BL, pwmLedChannelTFT); |
| 77 | + ledcWrite(pwmLedChannelTFT, backlight[b]); |
| 78 | + |
| 79 | + |
| 80 | + Serial.begin(115200); |
| 81 | + pinMode(LED, OUTPUT); |
| 82 | + digitalWrite(LED , HIGH); |
| 83 | + pinMode(BTNA, INPUT); |
| 84 | + pinMode(BTNB, INPUT); |
| 85 | + pinMode(BTNC, INPUT_PULLUP); |
| 86 | + pinMode(BTND, INPUT_PULLUP); |
| 87 | + |
| 88 | + |
| 89 | + |
| 90 | + |
| 91 | + |
| 92 | + |
| 93 | + tft.setCursor(14, 20); |
| 94 | + tft.println("Radio"); |
| 95 | + |
| 96 | + tft.drawLine(0,28,135,28,TFT_GREY); |
| 97 | + delay(500); |
| 98 | + delay(1000); |
| 99 | + initwifi(); |
| 100 | + |
| 101 | + for(int i=0;i<b+1;i++) |
| 102 | + tft.fillRect(108+(i*4),18,2,6,TFT_GREEN); |
| 103 | + |
| 104 | + tft.drawString("Ready ",78,44,2 ); |
| 105 | + tft.drawString(String(fgain),78,66,2 ); |
| 106 | + tft.drawString(String(arrayStation[sflag]),12,108,2); |
| 107 | + tft.setTextFont(1); |
| 108 | + tft.setCursor(8, 211, 1); |
| 109 | + tft.println(WiFi.localIP()); |
| 110 | + |
| 111 | + Serial.printf("STATUS(System) Ready \n\n"); |
| 112 | + out = new AudioOutputI2S(0, 1); // Output to builtInDAC |
| 113 | + out->SetOutputModeMono(true); |
| 114 | + out->SetGain(fgain*0.05); |
| 115 | + } |
| 116 | + |
| 117 | +float n=0; |
| 118 | + |
| 119 | +void loop() { |
| 120 | + |
| 121 | + if (playflag == 1) { |
| 122 | + tft.pushImage(50, 126, animation_width, animation_height, frame[int(n)]); |
| 123 | + n=n+0.05 ; |
| 124 | + if(int(n)==frames) |
| 125 | + n=0; } |
| 126 | + else |
| 127 | + {tft.pushImage(50, 126, animation_width, animation_height, frame[frames-1]);} |
| 128 | + |
| 129 | + |
| 130 | + static int lastms = 0; |
| 131 | + if (playflag == 0) { |
| 132 | + if (digitalRead(BTNA) == LOW) { |
| 133 | + StartPlaying(); |
| 134 | + tft.drawString("Playing! ",78,44,2); |
| 135 | + playflag = 1; |
| 136 | + |
| 137 | + } |
| 138 | + |
| 139 | + if (digitalRead(BTNB) == LOW) { |
| 140 | + sflag = (sflag + 1) % numCh; |
| 141 | + URL = arrayURL[sflag]; |
| 142 | + station = arrayStation[sflag]; |
| 143 | + |
| 144 | + tft.setTextSize(1); |
| 145 | + |
| 146 | + |
| 147 | + tft.drawString(String(station),12,108,2); |
| 148 | + delay(300); |
| 149 | + } |
| 150 | + } |
| 151 | + |
| 152 | +//lars start player |
| 153 | + |
| 154 | +if (playflag == 0) { |
| 155 | + StartPlaying(); |
| 156 | + playflag = 1; |
| 157 | + } |
| 158 | + if (playflag == 1) { |
| 159 | + if (mp3->isRunning()) { |
| 160 | + if (millis() - lastms > 1000) { |
| 161 | + lastms = millis(); |
| 162 | + Serial.printf("STATUS(Streaming) %d ms...\n", lastms); |
| 163 | + |
| 164 | + ledflag = ledflag + 1; |
| 165 | + if (ledflag > 1) { |
| 166 | + ledflag = 0; |
| 167 | + digitalWrite(LED , HIGH); |
| 168 | + |
| 169 | + } else { |
| 170 | + digitalWrite(LED , LOW); |
| 171 | + } |
| 172 | + |
| 173 | + } |
| 174 | + if (!mp3->loop()) mp3->stop(); |
| 175 | + } else { |
| 176 | + Serial.printf("MP3 done\n"); |
| 177 | + playflag = 0; |
| 178 | + |
| 179 | + digitalWrite(LED , HIGH); |
| 180 | + |
| 181 | + } |
| 182 | + if (digitalRead(BTNA) == LOW) { |
| 183 | + StopPlaying(); |
| 184 | + playflag = 0; |
| 185 | + tft.drawString("Stoped! ",78,44,2); |
| 186 | + digitalWrite(LED , HIGH); |
| 187 | + |
| 188 | + delay(200); |
| 189 | + } |
| 190 | + if (digitalRead(BTNB) == LOW) { |
| 191 | + fgain = fgain + 1.0; |
| 192 | + if (fgain > 10.0) { |
| 193 | + fgain = 1.0; |
| 194 | + } |
| 195 | + out->SetGain(fgain*0.05); |
| 196 | + tft.drawString(String(fgain),78,66,2 ); |
| 197 | + Serial.printf("STATUS(Gain) %f \n", fgain*0.05); |
| 198 | + delay(200); |
| 199 | + } |
| 200 | + } |
| 201 | + |
| 202 | + |
| 203 | + if(digitalRead(BTNC)==0){ |
| 204 | + if(press2==0) |
| 205 | + {press2=1; |
| 206 | + tft.fillRect(108,18,25,6,TFT_BLACK); |
| 207 | + |
| 208 | + b++; |
| 209 | + if(b>4) |
| 210 | + b=0; |
| 211 | + |
| 212 | + for(int i=0;i<b+1;i++) |
| 213 | + tft.fillRect(108+(i*4),18,2,6,TFT_GREEN); |
| 214 | + ledcWrite(pwmLedChannelTFT, backlight[b]);} |
| 215 | + }else press2=0; |
| 216 | + |
| 217 | + if(digitalRead(BTND)==0){ |
| 218 | + if(press1==0) |
| 219 | + {press1=1; |
| 220 | + inv=!inv; |
| 221 | + tft.invertDisplay(inv);} |
| 222 | + }else press1=0; |
| 223 | + |
| 224 | +} |
| 225 | + |
| 226 | +void StartPlaying() { |
| 227 | + file = new AudioFileSourceICYStream(URL); |
| 228 | + file->RegisterMetadataCB(MDCallback, (void*)"ICY"); |
| 229 | + buff = new AudioFileSourceBuffer(file, bufferSize); |
| 230 | + buff->RegisterStatusCB(StatusCallback, (void*)"buffer"); |
| 231 | + out = new AudioOutputI2S(0, 1); // Output to builtInDAC |
| 232 | + out->SetOutputModeMono(true); |
| 233 | + out->SetGain(fgain*0.05); |
| 234 | + mp3 = new AudioGeneratorMP3(); |
| 235 | + mp3->RegisterStatusCB(StatusCallback, (void*)"mp3"); |
| 236 | + mp3->begin(buff, out); |
| 237 | + Serial.printf("STATUS(URL) %s \n", URL); |
| 238 | + Serial.flush(); |
| 239 | +} |
| 240 | + |
| 241 | +void StopPlaying() { |
| 242 | + if (mp3) { |
| 243 | + mp3->stop(); |
| 244 | + delete mp3; |
| 245 | + mp3 = NULL; |
| 246 | + } |
| 247 | + if (buff) { |
| 248 | + buff->close(); |
| 249 | + delete buff; |
| 250 | + buff = NULL; |
| 251 | + } |
| 252 | + if (file) { |
| 253 | + file->close(); |
| 254 | + delete file; |
| 255 | + file = NULL; |
| 256 | + } |
| 257 | + Serial.printf("STATUS(Stopped)\n"); |
| 258 | + Serial.flush(); |
| 259 | +} |
| 260 | + |
| 261 | +void initwifi() { |
| 262 | + WiFi.disconnect(); |
| 263 | + WiFi.softAPdisconnect(true); |
| 264 | + WiFi.mode(WIFI_STA); |
| 265 | + WiFi.begin(SSID, PASSWORD); |
| 266 | + |
| 267 | + int i = 0; |
| 268 | + while (WiFi.status() != WL_CONNECTED) { |
| 269 | + Serial.print("STATUS(Connecting to WiFi) "); |
| 270 | + delay(1000); |
| 271 | + i = i + 1; |
| 272 | + if (i > 10) { |
| 273 | + ESP.restart(); |
| 274 | + } |
| 275 | + } |
| 276 | + Serial.println("OK"); |
| 277 | +} |
| 278 | + |
| 279 | +void MDCallback(void *cbData, const char *type, bool isUnicode, const char *string) { |
| 280 | + const char *ptr = reinterpret_cast<const char *>(cbData); |
| 281 | + (void) isUnicode; // Punt this ball for now |
| 282 | + // Note that the type and string may be in PROGMEM, so copy them to RAM for printf |
| 283 | + char s1[32], s2[64]; |
| 284 | + strncpy_P(s1, type, sizeof(s1)); |
| 285 | + s1[sizeof(s1) - 1] = 0; |
| 286 | + strncpy_P(s2, string, sizeof(s2)); |
| 287 | + s2[sizeof(s2) - 1] = 0; |
| 288 | + Serial.printf("METADATA(%s) '%s' = '%s'\n", ptr, s1, s2); |
| 289 | + |
| 290 | + |
| 291 | + |
| 292 | + Serial.flush(); |
| 293 | +} |
| 294 | + |
| 295 | +void StatusCallback(void *cbData, int code, const char *string) { |
| 296 | + const char *ptr = reinterpret_cast<const char *>(cbData); |
| 297 | + // Note that the string may be in PROGMEM, so copy it to RAM for printf |
| 298 | + char s1[64]; |
| 299 | + strncpy_P(s1, string, sizeof(s1)); |
| 300 | + s1[sizeof(s1) - 1] = 0; |
| 301 | + Serial.printf("STATUS(%s) '%d' = '%s'\n", ptr, code, s1); |
| 302 | + Serial.flush(); |
| 303 | +} |
0 commit comments