Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

All Https type stations result in "Request (URL) failed!" when use Bluetooth code #940

Open
renatoianhez opened this issue Jan 1, 2025 · 7 comments

Comments

@renatoianhez
Copy link

I finally updated the library and the ESP32-Arduino. The ESP32-Arduino version I was using was 2.0.11. I did this after a fresh installation of Arduino IDE 2.3.4. It compiled normally and worked as expected.
However, all the stations whose address was "Https" resulted in "Request (URL) failed!".
The code is:

#include <ESP_I2S.h>
#include <wav_header.h>
#include <Arduino.h>
#include <TFT_eSPI.h> // Biblioteca da tela
#include <SPI.h> // SPI
#include <WiFiMulti.h> // Pra mais de um local de WiFi
#include "Audio.h" // Biblioteca do audio
#include "examples/320 x 240/Free_Font_Demo/Free_Fonts.h" // Fontes
#include "BluetoothA2DPSink.h" // Para o Bluetooth
#include <HTTPClient.h>

#define canalPraCima  0   // 0 nos antigos - 15 nos Wrover - Botoes para mudar a estacao
#define canalPraBaixo 4
#define I2S_DOUT      25  // Pinos do audio I2S
#define I2S_BCLK      27
#define I2S_LRCK      26
#define modoAparelho  34  // Chave seletora radio-bluetooth

bool mudouEstacao;
int radioTocando;
char* tituloBT;
char* artistaBT;
char* albumBT;

TFT_eSPI tela = TFT_eSPI(); // ATENCAO os pinos da tela sao definidos na biblioteca
Audio audio;
I2SClass i2s;
BluetoothA2DPSink a2dp_sink(i2s);
WiFiMulti outrosWiFi;
HTTPClient http;
bool connected = true;

//Radios e enderecos
String conteudoBaixado;
String tudo[120];
String nomeRadio[30];
String tipoRadio[30];
String cidadeRadio[30];
String urlRadio[30];
String endTudo = "https://gist.githubusercontent.com/renatoianhez/4b5726d5ef32ad0a24fa3db6521989d6/raw";
int indice = 0;

void baixaDados(const String& urlDado, int maxTokens, String* tokens) {
  http.begin(urlDado);
  int httpCode = http.GET();
  if (httpCode == HTTP_CODE_OK) {
    conteudoBaixado = http.getString();
    Serial.println("Arquivo de dados das radios baixado com sucesso");
  }
  else {
    Serial.printf("Falha ao baixar o arquivo. Código de erro HTTP: %d\n", httpCode);
  }
  http.end();
  int startIndex = 0;
  int endIndex = 0;
  int tokenIndex = 0;
  while (endIndex >= 0 && tokenIndex < maxTokens) {
    endIndex = conteudoBaixado.indexOf('\n', startIndex);
    if (endIndex >= 0) {
      tokens[tokenIndex] = conteudoBaixado.substring(startIndex, endIndex);
      startIndex = endIndex + 1;
    } else {
      tokens[tokenIndex] = conteudoBaixado.substring(startIndex);
    }
    tokenIndex++;
  }
}

void sobeCanal() {
  // Se apertar o botao pra subir uma estacao:
  radioTocando = radioTocando + 1;          // incrementa o indice
  tela.fillScreen(TFT_BLACK);
  tela.setTextColor(TFT_RED, TFT_WHITE);
  tela.setCursor(0, 0, 4);
  tela.println("Sintonizando!");
  delay(1000); // uma pausa pra largar o botao
  if (radioTocando > 29) {     // Testa se passou da ultima estacao da lista
    radioTocando = 0;         // se sim vai pra primeira da playlist
  }
}

void desceCanal() {
  radioTocando = radioTocando - 1;        // decrementa o indice
  tela.fillScreen(TFT_BLACK);
  tela.setCursor(0, 0, 4);
  tela.setTextColor(TFT_RED, TFT_WHITE);
  tela.println("Sintonizando!");
  delay(1000); // uma pausa pra largar o botao
  if (radioTocando < 0) {     // Testa se passou pra baixo da primeira da lista
    radioTocando = 29;      // se sim vai pra ultima da playlist
  }
}

void mudouEstacaoMesmo() {
  tela.setFreeFont(FF5);
  tela.fillScreen(TFT_BLACK);
  tela.fillRect(0, 0, 160, 28, TFT_WHITE);
  int centro = 77 - (11 * ((nomeRadio[radioTocando].length())) / 2);
  tela.setCursor(centro, 18);
  tela.setTextColor(TFT_BLUE); //texto azul
  tela.println(nomeRadio[radioTocando]); // nome da radio centralizado
  tela.setTextFont(2);
  tela.setCursor(0, 30);
  tela.setTextColor(TFT_ORANGE);
  tela.println(cidadeRadio[radioTocando]);
  tela.setCursor(0, 45, 2);
  tela.setTextColor(TFT_YELLOW);
  tela.println(tipoRadio[radioTocando]);
  audio.connecttohost(urlRadio[radioTocando].c_str());
  delay(500);
}
void audio_info(const char *info) {
  Serial.print("info        ");
  Serial.println(info);
}

void audio_showstreamtitle(const char *titulo) { // Pra mostrar o nome da musica e cantor
  tela.setCursor(0, 60, 2);
  tela.setTextColor(TFT_CYAN, TFT_BLACK);
  tela.println("Tocando agora:");
  tela.setCursor(0, 75, 2);
  tela.println("                                                                                    "); //Pra limpar
  tela.setCursor(0, 75, 2);
  tela.println(titulo);
}

void avrc_metadata_callback(uint8_t id, const uint8_t *text) {
  Serial.printf("==> AVRC metadata rsp: attribute id 0x%x, %s\n", id, text);
  tela.setFreeFont(FF5);
  tela.fillScreen(TFT_BLACK);
  tela.fillRect(0, 0, 160, 28, TFT_WHITE);
  tela.setCursor(28, 18);
  tela.setTextColor(TFT_BLUE); //texto azul
  tela.println("BLUETOOTH");
  tela.setTextFont(2);
  tela.setCursor(0, 30);
  switch (id) {
    case ESP_AVRC_MD_ATTR_TITLE:
      tituloBT = (char*) text;
      break;
    case ESP_AVRC_MD_ATTR_ARTIST:
      artistaBT = (char*) text;
      break;
    case ESP_AVRC_MD_ATTR_ALBUM:
      albumBT = (char*) text;
      break;
  }
  tela.setTextColor(TFT_ORANGE);
  tela.println("Conectado a: ");
  tela.println(a2dp_sink.get_peer_name());
  tela.setTextColor(TFT_PINK);
  tela.println(tituloBT);
  tela.setTextColor(TFT_YELLOW);
  tela.println(artistaBT);
  tela.setTextColor(TFT_LIGHTGREY);
  tela.println(albumBT);
}

void setup() {
  pinMode(canalPraCima, INPUT_PULLUP); // Modo dos botoes
  pinMode(canalPraBaixo, INPUT_PULLUP);
  pinMode(modoAparelho, INPUT);
  Serial.begin(115200); // inicia o serial
  tela.init(); // Inicia o display
  tela.setRotation(1); // Modo paisagem
  tela.invertDisplay(1); // Necessario para acertar as cores

  if (digitalRead(modoAparelho)) {
    radioTocando = random(0, 30); // Sorteia e primeira estacao
    mudouEstacao = true;
    WiFi.mode(WIFI_STA);
    outrosWiFi.addAP("Renato", "abacatequecaiudope"); // Dados do WiFi local
    //outrosWiFi.addAP("xxx", "xxx");
    //outrosWiFi.addAP("xxx","xxx");
    outrosWiFi.run();
    if (WiFi.status() != WL_CONNECTED) {
      WiFi.disconnect(true);
      outrosWiFi.run();
    }
    audio.setPinout(I2S_BCLK, I2S_LRCK, I2S_DOUT); // Configura o audio
    audio.setVolume(16); // volume vai de zero a 21
    audio.setConnectionTimeout(4000, 8000); // Garante a conexao as estacoes
    audio.setTone(0, 6, 4); // Equalizador grave - medio - agudo (-40 a 6)
    // audio.setBufsize(0, 4000000);
    // audio.forceMono(true); // Força o mono
    // audio.setBalance(0); // Balanco estereo direito - esquerdo (-16 a 16)
    baixaDados(endTudo, 120, tudo); // Baixa dados das radios
    for (int j = 0; j < 120; j = j + 4) { // Separa os dados
      nomeRadio[indice] = tudo[j];
      tipoRadio[indice] = tudo[(j + 1)];
      cidadeRadio[indice] = tudo[(j + 2)];
      urlRadio[indice] = tudo[(j + 3)];
      indice++;
    }
  }
  else {
   i2s.setPins(I2S_BCLK, I2S_LRCK, I2S_DOUT);
    if (!i2s.begin(I2S_MODE_STD, 44100, I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO, I2S_STD_SLOT_BOTH)) {
      Serial.println("Failed to initialize I2S!");
      while (1); // do nothing
    }
    a2dp_sink.set_avrc_metadata_callback(avrc_metadata_callback);
    a2dp_sink.set_auto_reconnect(true);
    a2dp_sink.start("BTRadio");
  }
}

void loop() {
  if (digitalRead(modoAparelho)) {
    audio.loop();
    vTaskDelay(20);
    if (digitalRead(canalPraCima) == LOW) {//Se apertar o botao pra subir a estacao
      sobeCanal();
      mudouEstacao = true;   // Avisa la que mudou de estacao!
    }
    if (digitalRead(canalPraBaixo) == LOW) {//Se apertar o botao para descer a estacao:
      desceCanal();
      mudouEstacao = true;  //Avisa la que mudou de estacao tambem!
    }
    if (mudouEstacao) {     //Se a estacao mudou, atualiza o LCD e o terminal
      mudouEstacaoMesmo();
      mudouEstacao = false; // Mantem a estacao que esta tocando
    }
  }
}

I did an experiment by removing the "Bluetooth" part of the project and they started working again.
The code was as follows:

#include <Arduino.h>
#include <TFT_eSPI.h>                                      // Biblioteca da tela
#include <SPI.h>                                           // SPI
#include <WiFiMulti.h>                                     // Pra mais de um local de WiFi
#include "Audio.h"                                         // Biblioteca do audio
#include "examples/320 x 240/Free_Font_Demo/Free_Fonts.h"  // Fontes
#include <HTTPClient.h>

#define canalPraCima 0  // 0 nos antigos - 15 nos Wrover - Botoes para mudar a estacao
#define canalPraBaixo 4
#define I2S_DOUT 25  // Pinos do audio I2S
#define I2S_BCLK 27
#define I2S_LRCK 26

bool mudouEstacao;
int radioTocando;
char* tituloBT;
char* artistaBT;
char* albumBT;

TFT_eSPI tela = TFT_eSPI();  // ATENCAO os pinos da tela sao definidos na biblioteca
Audio audio;
WiFiMulti outrosWiFi;
HTTPClient http;
bool connected = true;

//Radios e enderecos
String conteudoBaixado;
String tudo[120];
String nomeRadio[30];
String tipoRadio[30];
String cidadeRadio[30];
String urlRadio[30];
String endTudo = "https://gist.githubusercontent.com/renatoianhez/4b5726d5ef32ad0a24fa3db6521989d6/raw";
int indice = 0;

void baixaDados(const String& urlDado, int maxTokens, String* tokens) {
  http.begin(urlDado);
  int httpCode = http.GET();
  if (httpCode == HTTP_CODE_OK) {
    conteudoBaixado = http.getString();
    Serial.println("Arquivo de dados das radios baixado com sucesso");
  } else {
    Serial.printf("Falha ao baixar o arquivo. Código de erro HTTP: %d\n", httpCode);
  }
  http.end();
  int startIndex = 0;
  int endIndex = 0;
  int tokenIndex = 0;
  while (endIndex >= 0 && tokenIndex < maxTokens) {
    endIndex = conteudoBaixado.indexOf('\n', startIndex);
    if (endIndex >= 0) {
      tokens[tokenIndex] = conteudoBaixado.substring(startIndex, endIndex);
      startIndex = endIndex + 1;
    } else {
      tokens[tokenIndex] = conteudoBaixado.substring(startIndex);
    }
    tokenIndex++;
  }
}

void sobeCanal() {
  // Se apertar o botao pra subir uma estacao:
  radioTocando = radioTocando + 1;  // incrementa o indice
  tela.fillScreen(TFT_BLACK);
  tela.setTextColor(TFT_RED, TFT_WHITE);
  tela.setCursor(0, 0, 4);
  tela.println("Sintonizando!");
  delay(1000);              // uma pausa pra largar o botao
  if (radioTocando > 29) {  // Testa se passou da ultima estacao da lista
    radioTocando = 0;       // se sim vai pra primeira da playlist
  }
}

void desceCanal() {
  radioTocando = radioTocando - 1;  // decrementa o indice
  tela.fillScreen(TFT_BLACK);
  tela.setCursor(0, 0, 4);
  tela.setTextColor(TFT_RED, TFT_WHITE);
  tela.println("Sintonizando!");
  delay(1000);             // uma pausa pra largar o botao
  if (radioTocando < 0) {  // Testa se passou pra baixo da primeira da lista
    radioTocando = 29;     // se sim vai pra ultima da playlist
  }
}

void mudouEstacaoMesmo() {
  tela.setFreeFont(FF5);
  tela.fillScreen(TFT_BLACK);
  tela.fillRect(0, 0, 160, 28, TFT_WHITE);
  int centro = 77 - (11 * ((nomeRadio[radioTocando].length())) / 2);
  tela.setCursor(centro, 18);
  tela.setTextColor(TFT_BLUE);            //texto azul
  tela.println(nomeRadio[radioTocando]);  // nome da radio centralizado
  tela.setTextFont(2);
  tela.setCursor(0, 30);
  tela.setTextColor(TFT_ORANGE);
  tela.println(cidadeRadio[radioTocando]);
  tela.setCursor(0, 45, 2);
  tela.setTextColor(TFT_YELLOW);
  tela.println(tipoRadio[radioTocando]);
  audio.connecttohost(urlRadio[radioTocando].c_str());
  delay(500);
}
void audio_info(const char* info) {
  Serial.print("info        ");
  Serial.println(info);
}

void audio_showstreamtitle(const char* titulo) {  // Pra mostrar o nome da musica e cantor
  tela.setCursor(0, 60, 2);
  tela.setTextColor(TFT_CYAN, TFT_BLACK);
  tela.println("Tocando agora:");
  tela.setCursor(0, 75, 2);
  tela.println("                                                                                    ");  //Pra limpar
  tela.setCursor(0, 75, 2);
  tela.println(titulo);
}

void setup() {
  pinMode(canalPraCima, INPUT_PULLUP);  // Modo dos botoes
  pinMode(canalPraBaixo, INPUT_PULLUP);
  Serial.begin(115200);          // inicia o serial
  tela.init();                   // Inicia o display
  tela.setRotation(1);           // Modo paisagem
  tela.invertDisplay(1);         // Necessario para acertar as cores
  radioTocando = random(0, 30);  // Sorteia e primeira estacao
  mudouEstacao = true;
  WiFi.mode(WIFI_STA);
  outrosWiFi.addAP("Renato", "abacatequecaiudope");  // Dados do WiFi local
  //outrosWiFi.addAP("xxx", "xxx");
  //outrosWiFi.addAP("xxx","xxx");
  outrosWiFi.run();
  if (WiFi.status() != WL_CONNECTED) {
    WiFi.disconnect(true);
    outrosWiFi.run();
  }
  audio.setPinout(I2S_BCLK, I2S_LRCK, I2S_DOUT);  // Configura o audio
  audio.setVolume(16);                            // volume vai de zero a 21
  audio.setConnectionTimeout(4000, 8000);         // Garante a conexao as estacoes
  audio.setTone(0, 6, 4);                         // Equalizador grave - medio - agudo (-40 a 6)
  // audio.setBufsize(0, 4000000);
  // audio.forceMono(true); // Força o mono
  // audio.setBalance(0); // Balanco estereo direito - esquerdo (-16 a 16)
  baixaDados(endTudo, 120, tudo);        // Baixa dados das radios
  for (int j = 0; j < 120; j = j + 4) {  // Separa os dados
    nomeRadio[indice] = tudo[j];
    tipoRadio[indice] = tudo[(j + 1)];
    cidadeRadio[indice] = tudo[(j + 2)];
    urlRadio[indice] = tudo[(j + 3)];
    indice++;
  }
}

void loop() {
  audio.loop();
  vTaskDelay(20);
  if (digitalRead(canalPraCima) == LOW) {  //Se apertar o botao pra subir a estacao
    sobeCanal();
    mudouEstacao = true;  // Avisa la que mudou de estacao!
  }
  if (digitalRead(canalPraBaixo) == LOW) {  //Se apertar o botao para descer a estacao:
    desceCanal();
    mudouEstacao = true;  //Avisa la que mudou de estacao tambem!
  }
  if (mudouEstacao) {  //Se a estacao mudou, atualiza o LCD e o terminal
    mudouEstacaoMesmo();
    mudouEstacao = false;  // Mantem a estacao que esta tocando
  }
}

I imagine that the "Bluetooth" portion of the code does not interfere with the internet connection via WiFi, since the "Http" addresses (without the "s") work. What could be interfering with Https? Or is it the size of the code that leaves little memory for these addresses?

@renatoianhez renatoianhez changed the title All Https type stations result in "Request (URL) failed!" when All Https type stations result in "Request (URL) failed!" when use Bluetooth code Jan 1, 2025
@renatoianhez
Copy link
Author

I removed all the "s" from the addresses. Some stations don't support this, like Tonic Ska Radio. Others redirect to the Https: address.

info        connect to: "streaming.educadorafm.ba.gov.br" on port 80 path "/stream-01"
info        Connection has been established in 61 ms, free Heap: 35680 bytes
info        redirect to new host "https://streaming.educadorafm.ba.gov.br/stream-01"
info        buffers freed, free Heap: 35884 bytes
info        connect to: "streaming.educadorafm.ba.gov.br" on port 443 path "/stream-01"
info        Request https://streaming.educadorafm.ba.gov.br/stream-01 failed!

@schreibfaul1
Copy link
Owner

schreibfaul1 commented Jan 4, 2025

I think it will be a memory problem, encrypted connections need up to ~50KBytes additional RAM. If you are using Arduino as a component you can tell "mbedtls" in menuconfig to use the PSRAM.

image

@renatoianhez
Copy link
Author

Oh, thanks! I've never been able to use Platformio, something in my attempts to install it and in my head doesn't work properly with it. It's like they say here in Brazil: 'our saints didn't cross'. I'll try one more time!

@schreibfaul1
Copy link
Owner

I have updated my template. https://github.com/schreibfaul1/ESP32_Arduino_ESPIDF
This should not be a problem,
Install Git and VSCode, then load the PlatformIO extension and then insert the link in "Clone repository".

@renatoianhez
Copy link
Author

renatoianhez commented Jan 5, 2025

I believe I solved it without needing Platformio (I ran into library issues again): there seems to be a dispute for memory between WiFi and Bluetooth. Well, since my device has a 'radio mode' and a 'bluetooth mode', I freed the memory supposedly allocated for Bluetooth when in radio (WiFi) mode, and vice versa:

void setup() {
  pinMode(canalPraCima, INPUT_PULLUP);  // Buttons mode
  pinMode(canalPraBaixo, INPUT_PULLUP);
  pinMode(modoAparelho, INPUT);
  Serial.begin(115200);  
  tela.init();            // display
  tela.setRotation(1);   
  tela.invertDisplay(0); 

  if (digitalRead(modoAparelho)) { // If in radio mode
    esp_bt_controller_mem_release(ESP_BT_MODE_BTDM);  // memory allocated for Bluetooth
    radioTocando = random(0, 30);  
    mudouEstacao = true;
    WiFi.disconnect();  // 
    WiFi.mode(WIFI_STA);
    outrosWiFi.addAP("SSID", "passw"); 
    //outrosWiFi.addAP("xxx", "xxx");
    //outrosWiFi.addAP("xxx","xxx");
    while (outrosWiFi.run() != WL_CONNECTED) delay(1500);  
    audio.setPinout(I2S_BCLK, I2S_LRCK, I2S_DOUT);     
    audio.setVolume(16);                                  
    audio.setConnectionTimeout(3000, 7200);          
    audio.setTone(0, 6, 4);                                
    // audio.setBufsize(0, 4000000);
    // audio.forceMono(true); // Força o mono
    // audio.setBalance(0); // Balanco estereo direito - esquerdo (-16 a 16)
    baixaDados(endTudo, 120, tudo);        
    for (int j = 0; j < 120; j = j + 4) { 
      nomeRadio[indice] = tudo[j];
      tipoRadio[indice] = tudo[(j + 1)];
      cidadeRadio[indice] = tudo[(j + 2)];
      urlRadio[indice] = tudo[(j + 3)];
      indice++;
    }
  } else {  //If in Bluetooth mode
    WiFi.disconnect();
    WiFi.mode(WIFI_OFF);
    i2s.setPins(I2S_BCLK, I2S_LRCK, I2S_DOUT);
    if (!i2s.begin(I2S_MODE_STD, 44100, I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO, I2S_STD_SLOT_BOTH)) {
      Serial.println("Failed to initialize I2S!");
      while (1)
        ;  // do nothing
    }
    a2dp_sink.set_avrc_metadata_callback(avrc_metadata_callback);
    a2dp_sink.set_auto_reconnect(true);
    a2dp_sink.start("BTRadio");
  }
}

All stations now work normally with all libraries updated! Thank you very much!

@renatoianhez
Copy link
Author

I ran some tests using a function from the ESP32 API to measure the amount of SRAM released when doing esp_bt_controller_mem_release(ESP_BT_MODE_BTDM), and, on average, it released 36KB. It seems to be enough for HTTPS streams to work properly.

@schreibfaul1
Copy link
Owner

Sounds good, good luck with your project!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants