Umschalten zwischen webradio und bluetooth audio

Hi zusammen,

ich habe ein PCM5102-Modul an einen ESP32 angeschlossen.

Plan ist (für den Urlaiub) wie bereits in einem anderen Post beschrieben, ein Webradio zu bauen.
Der Sketch für das Webradio ist nun nahezu fertig und funktioniert, Juhu!

Nun wollte ich noch einbauen, dass man (nach Drücken eines Buttons am Pin 19) umschalten kann auf Bluetooth Audio... und da hängts nun wieder: Immer wenn der Button gedrückt wird, bekommt mein ESP32 ne Panik-Attacke (Absturz).

Ich fang mal so an:

Folgender Sketch funktioniert wunderbar (ich kann mein Handy per Bluetooth verbinden und höre dann den Sound am LineOut des PCM5102)

#include "Audio.h"
#include "BluetoothA2DPSink.h"
#include <Wire.h> 

#define BUTTON_PIN  19

BluetoothA2DPSink a2dp_sink;
Audio audio;

#define I2S_DOUT      25
#define I2S_BCLK      27
#define I2S_LRC       26

void setup() {
  Wire.begin(); 
  i2s_pin_config_t my_pin_config = {
      .bck_io_num = 27,
      .ws_io_num = 26,
      .data_out_num = 25,
      .data_in_num = I2S_PIN_NO_CHANGE
  };
  
  a2dp_sink.set_pin_config(my_pin_config);
  a2dp_sink.start("MyMusic");  

  audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT);
  audio.setVolume(21); 
}


void loop() {
  audio.loop();
}

Aber wenn ich ne Combie aus Webradio und Bluetooth machen will, klappts ned (hier ne stark vereinfachte Version des Sketchs):

#include "WiFi.h"
#include "Audio.h"
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
#include "BluetoothA2DPSink.h"
#include "Button2.h"

#define BUTTON_PIN  19
#define I2S_DOUT      25
#define I2S_BCLK      27
#define I2S_LRC       26

BluetoothA2DPSink a2dp_sink;
Audio audio;
Button2 button = Button2(BUTTON_PIN);

uint8_t conn_mode=0; // 0 = Webradio, 1 = Bluetooth-Audio
char ssid[50] = "MEINE_SSID";
char password[50] = "MEIN_PW";

void setup() {
  Wire.begin();    // begin Wire(I2C)
  Serial.begin(115200);

  pinMode(BUTTON_PIN, INPUT_PULLUP);
  button.setPressedHandler(pressed);

  i2s_pin_config_t my_pin_config = {
      .bck_io_num = 27,
      .ws_io_num = 26,
      .data_out_num = 25,
      .data_in_num = I2S_PIN_NO_CHANGE
  };
  
  a2dp_sink.set_pin_config(my_pin_config);

  // a2dp_sink.start("MyMusic");  Muss ich hier noch auskommentieren, sonst geht das Webradio nicht

  audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT);
  audio.setVolume(21); // 0...21

  WiFi_conn();
  senderEinstellen(); 
}

void WiFi_conn() {
  WiFi.disconnect();
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
  }
}

void senderEinstellen() {
  audio.connecttohost("http://streams.radiobob.de/bob-live/mp3-192/mediaplayer");
}

void loop()
{
  button.loop();
  audio.loop();
}

void pressed(Button2& btn) {
    if (conn_mode == 0) {
      conn_mode = 1;
      WiFi.disconnect();
      a2dp_sink.start("Webradio - Bluetooth"); 
    } else {
      conn_mode = 0;
      WiFi_conn();
    }
}

Das Webradio startet korrekt und ich bekomm Sound.
Aber: Sobald ich den Button drücken, bekomm ich diesen Fehler hier:

E (7469) I2S: register I2S object to platform failed
Guru Meditation Error: Core 0 panic'ed (StoreProhibited). Exception was unhandled.

Core 0 register dump:
PC : 0x40090fa8 PS : 0x00060730 A0 : 0x8014cc57 A1 : 0x3fffb520
A2 : 0x00000000 A3 : 0x00000000 A4 : 0x00000130 A5 : 0x00000000
A6 : 0x3fff9254 A7 : 0x00000013 A8 : 0x80154fc0 A9 : 0x3fffb4f0
A10 : 0x3ffcb15c A11 : 0x00000130 A12 : 0x3ffcb158 A13 : 0x3ffc6d44
A14 : 0x00002aa6 A15 : 0x00000000 SAR : 0x0000001e EXCCAUSE: 0x0000001d
EXCVADDR: 0x00000000 LBEG : 0x40090fa8 LEND : 0x40090fb3 LCOUNT : 0x00000012

Backtrace:0x40090fa5:0x3fffb5200x4014cc54:0x3fffb530 0x40131b91:0x3fffb550 0x401483fb:0x3fffb570

Könnt ihr mich erleuchten?

LG Daniel

Update:

Wenn ich diese Zeile hier hinzufüge, stürzt der ESP zumindest schon mal nicht mehr ab:

WiFi.mode(WIFI_OFF);


void pressed(Button2& btn) {
    Serial.println("pressed");
    if (conn_mode == 0) {
      conn_mode = 1;
      Serial.println("Bluetooth connect!");
      WiFi.disconnect();
      WiFi.mode(WIFI_OFF); // NEU!
       // Pins für Bluetooth Audio konfigurieren
      i2s_pin_config_t my_pin_config = {
          .bck_io_num = 27,
          .ws_io_num = 26,
          .data_out_num = 25,
          .data_in_num = I2S_PIN_NO_CHANGE
      };
      
      a2dp_sink.set_pin_config(my_pin_config);
      a2dp_sink.start("MyMusic"); 
    } else {
      conn_mode = 0;
      Serial.println("WiFi connect!");
      a2dp_sink.stop(); 
      WiFi_conn();
    }
}

Der BluetoothPort wird mir dann zwar am Handy angezeigt, aber das verbinden klappt nicht...

1 Like

Stimmt, den gibts ja auch noch... :upside_down_face:

1 Like

Hi, ich habe exakt das gleiche Vorhaben. Ein Webradio (läuft), welches durch drücken eines Knopfes in den BT-Modus wechseln sollte. Einzeln, wie bei dir auch, kein Problem. Erst durch Kombination der beiden Funktionen habe ich dieses Phänomen. Ursache ist anscheinend die Zeile "Audio audio;" am Anfang. Kommentiere ich diese aus, kann ich mich mit Bluetooth verbinden und auch umschalten zum Webradio. Natürlich dann ohne Ton, aufgrund der kommentierten Zeile. Ich würde mir das jetzt irgendwie so erklären, dass die 3 I2S-Ports irgendwie doppelt registriert werden und es dann zum Crash kommt. Hast du dafür eigentlich am Ende ne Lösung gefunden?

Hi,

ich hab am Ende ne quick and dirty Lösung gewählt: Wenn man den Knopf drückt, wird ne boolean Variable "Bluetooth" (Preferences also NVS Speicher) auf true gesetzt und dann ein esp.restart() ausgelöst.

Beim Neustart wird die Variable immer überprüft und steht in dem Fall dann auf true was ein Betreiben im Bluetooth Audio Modus zur Folge hat. Drückt man den Knopf nochmal wird die Variable wieder auf false gesetzt und wieder ein Neustart gemacht. Damit bin ich dann wieder im webradio modus.

Ist nicht die eleganteste Lösung aber funktioniert für mich gut

Lg Daniel

Hi,

danke für die schnelle Antwort. Als Lösung finde ich das ganz gut. Hauptsache es läuft am Ende. Ich steig da jetzt irgendwie nicht richtig durch, wie ich ne Variable in den NVS schreibe. Könntest du die entsprechende Zeile vielleicht mal rumschicken.

Viele Grüße
Jan

Hi,

kein Thema, wenn ich heute Abend zu Hause bin, poste ich hier einfach den gesamten Quellcode rein. Bis denn.

LG Daniel

Du meinst bestimmt Kombi von Kombination.

:rofl:

Jetzt merk ichs erst!
Nene ich mein schon dich :laughing:

Hi @jabred

hier mein kompletter Code (alle die es besser können, werft die Steine JETZT :wink:
Ich geh schon mal in Deckung.

Ich habe ein 4-zeiliges LiquidCrystal Display verwendet und einen Temperatur-/Luftfeuchtigkeitssensor, weil ich das auch noch auf dem Display haben wollte
Außerdem gibt es zwei Regler: Links zum Sender blättern (Drehen) und Wählen (Drücken).
Rechts zum Lautstärke regeln (Drehen) und Anzeigemodus ändern (Drücken):

Der entscheidende Part (Umschalten zwischen webradio und bluethooth audio) läuft über die Variable "conn_mode".

Da das hier kein Vorzeigeprojekt sollten werde, hab ich den Code jetzt nicht sonderlich gut aufgeräumt, kann durchaus sein, dass das noch bissl durcheinander ist und die ein oder andere Variable gar nicht (mehr) in Verwendung ist.

Das Radio funktioniert für mich so aber ideal.

#include <Preferences.h>
#include "Arduino.h"
#include "WiFi.h"
#include <WebServer.h>
#include "Audio.h"
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
#include "AiEsp32RotaryEncoder.h"
#include <SHT21.h> 
#include <time.h>
#include "BluetoothA2DPSink.h"
#include "Button2.h"

// ++++++++++++++++++++++++++++ Verdrahtung:
// ############# LCD-Display + GY-21 Sensor (SHT21):
// SDA: 21
// SCL: 22

// ############# Button zum Umschalten zwischen webradio und bluetooth audio
#define BUTTON_PIN  19

// ############# Drehgeber 1 (EC11) - Sender umschalten (Drehen) und Sender wählen (Drücken)
// Button-Pins: Ein Pin direkt auf GND, der andere auf GPIO 33 und über einen 10k zusätzlich auf 5V
// PotiPins: Von Oben gesehen: Links auf GPIO34, Mitte auf GND, Rechts auf GPIO 35
#define ROTARY_ENCODER_1_BUTTON_PIN 33
#define ROTARY_ENCODER_1_A_PIN 34
#define ROTARY_ENCODER_1_B_PIN 35
#define ROTARY_ENCODER_1_VCC_PIN -1
#define ROTARY_ENCODER_1_STEPS 4 

// ############# Drehgeber 2 (EC11) - Lautstärke wählen (Drehen) und Display-Modus umschalten (Drücken)
// Button-Pins: Ein Pin direkt auf GND, der andere auf GPIO 14 und über einen 10k zusätzlich auf 5V
// PotiPins: Von Oben gesehen: Links auf GPIO18, Mitte auf GND, Rechts auf GPIO 4
#define ROTARY_ENCODER_2_BUTTON_PIN 14
#define ROTARY_ENCODER_2_A_PIN 18
#define ROTARY_ENCODER_2_B_PIN 4
#define ROTARY_ENCODER_2_VCC_PIN -1
#define ROTARY_ENCODER_2_STEPS 4 

// Digital I/O used
#define I2S_DOUT      25
#define I2S_BCLK      27
#define I2S_LRC       26

// ++++++++++++++++++++++++++++ Initialisieren
BluetoothA2DPSink a2dp_sink;
WebServer server(80); // Server der App
LiquidCrystal_I2C lcd(0x27,20,4); 
Preferences pref; 
AiEsp32RotaryEncoder rotaryEncoder = AiEsp32RotaryEncoder(ROTARY_ENCODER_1_A_PIN, ROTARY_ENCODER_1_B_PIN, ROTARY_ENCODER_1_BUTTON_PIN, ROTARY_ENCODER_1_VCC_PIN, ROTARY_ENCODER_1_STEPS);
AiEsp32RotaryEncoder rotaryEncoder2 = AiEsp32RotaryEncoder(ROTARY_ENCODER_2_A_PIN, ROTARY_ENCODER_2_B_PIN, ROTARY_ENCODER_2_BUTTON_PIN, ROTARY_ENCODER_2_VCC_PIN, ROTARY_ENCODER_2_STEPS);
Audio audio;
SHT21 sht; 
Button2 button = Button2(BUTTON_PIN);

tm timeinfo;
time_t now;

// +++++++++++++++++++++++++++++++++++++++++++ Variablen
#define WIFI_TIMEOUT_MS 20000 // So lange wird versucht, neu mit Wifi zu verbinden, wenn die Verbindung mal verloren geht (in keepWiFiAlive())
const char* NTP_SERVER = "de.pool.ntp.org";
const char* TZ_INFO    = "CET-1CEST-2,M3.5.0/02:00:00,M10.5.0/03:00:00";  // Hier kann man die Zeitzonen nachschauen (https://remotemonitoringsystems.ca/time-zone-abbreviations.php)

// ############################################## Senderliste
//structure for station list
typedef struct {
  char * url;  //stream url
  char * name; //stations name
} Station;

#define STATIONS 13
Station stationlist[STATIONS] PROGMEM = {
{"http://streams.radiobob.de/bob-live/mp3-192/mediaplayer","Bob Livestream"},
{"http://streams.radiobob.de/bob-classicrock/mp3-192/mediaplayer ","Bob Classic Rock"},
{"http://streams.radiobob.de/bob-alternative/mp3-192/mediaplayer","Bob Alternative"},
{"http://streams.radiobob.de/bob-hartesaite/mp3-192/mediaplayer","Bob Harte Saite"},
{"http://streams.radiobob.de/bob-bestofrock/mp3-192/mediaplayer","Bob Best of Rock"},
{"https://streams.radiobob.de/70errock/mp3-192/mediaplayer/","Bob 70er"},
{"http://streams.radiobob.de/bob-80srock/mp3-192/mediaplayer","Bob 80er"},
{"http://streams.radiobob.de/bob-90srock/mp3-192/mediaplayer","Bob 90er"},
{"http://streams.radiobob.de/bob-metal/mp3-192/mediaplayer","Bob Metal"},
{"http://streams.radiobob.de/bob-grunge/mp3-192/mediaplayer","Bob Grunge"},
{"http://streams.radiobob.de/bob-livemusic/mp3-192/mediaplayer","Bob Festival"},
{"http://streams.radiobob.de/southernrock/mp3-192/mediaplayer","Bob Southern Rock"},
{"http://streams.radiobob.de/progrock/mp3-192/mediaplayer/","Bob ProgRock"}};

// Über die Index-Seite kann man initial seine WLAN-Zugangsdaten eingeben, wenn man sich über den AP / 192.168.4.1 verbindet
#include "index.h"

// Anzeige
uint8_t displayMode = 1; 
// displayMode 1 = Sendername, Songtitel, Datum und Uhrzeit werden angezeigt
// displayMode 0 = Songtitel, Luftfeuchtigkeit, Temperatur und Datum/Uhrzeit werden angezeigt
uint8_t setMode = 0;
uint32_t lastdispchange = 0;
uint32_t lastvolchange = 0;  // Zeitpunkt der letzten Lautstärkeänderung
uint32_t lasttimecheck = 0;
String titleinfo = "";
String titleinfo_old = "";
uint16_t currentHour = 0;
uint16_t currentMinute = 0;
uint16_t currentSecond = 0;
uint16_t monthDay = 0;
uint16_t currentMonth = 0;
uint16_t currentYear = 0;
char currentDate[20];
unsigned long connTimer;
bool wifi_conn_success=false;


uint8_t conn_mode=0; // 0 = Webradio, 1 = Bluetooth-Audio
uint8_t volume = 5;
uint8_t curStation = 0;
uint8_t actStation = 0;   //index for current station in station list used for streaming 
uint32_t lastchange = 0;  // Zeitpunkt der letzten Sender- oder Volume-Änderung

// Luftfeuchtigkeit / Temperatur
float temp;  
float humidity;

char ssid[50]; // WLAN-SSID, wird vom Benutzer über die App gefüllt
char password[50]; // WLAN-Passwort, wird vom Benutzer über die App gefüllt

// Interrupt für Sender-Regler
void IRAM_ATTR readEncoderISR()
{
  rotaryEncoder.readEncoder_ISR();
}

//interrupt für Volume-Regler / Display-Umschalter
void IRAM_ATTR readEncoder2ISR()
{
  rotaryEncoder2.readEncoder_ISR();
}

// ++++++++++++++++++++++++++++++++++++++++ WiFi-Verbindung aufrechterhalten
void keepWiFiAlive(void * parameters) {
  for (;;) {
    if (wifi_conn_success) {
      // Nur wenn die manuell gestartete, erste Verbindung geklappt hat, wieder neu verbinden
      // Denn wenn diese schon nicht geklappt hat, hat es auch keinen Wert, nochmal zu versuchen.
      if (WiFi.status() == WL_CONNECTED) {
        //Wifi ist immer noch verbunden
        vTaskDelay(10000 / portTICK_PERIOD_MS);
        continue;
      }
      Serial.println("WiFi-Verbindungsversuch....!");
      WiFi.begin(ssid, password);
      unsigned long startAttemptTime=millis();
      while (WiFi.status() != WL_CONNECTED && millis() - startAttemptTime < WIFI_TIMEOUT_MS) {
        vTaskDelay(500 / portTICK_PERIOD_MS);
      }
      
      if (WiFi.status() != WL_CONNECTED) {
        vTaskDelay(300000 / portTICK_PERIOD_MS);
        continue;
      } else {
        continue;
      }
    } else {
      vTaskDelay(10000 / portTICK_PERIOD_MS);
      continue;
    }
  }
}


void setup() {
  Wire.begin();    // begin Wire(I2C)
  Serial.begin(115200);

  // WiFi-Verbindung aufrechterhalten
  xTaskCreatePinnedToCore(
    keepWiFiAlive,
    "Keep Wifi Alive",
    5000,
    NULL,
    2,
    NULL,
    0
  );

  pinMode(BUTTON_PIN, INPUT_PULLUP);
  
  button.setPressedHandler(pressed);
  
  i2s_pin_config_t my_pin_config = {
      .bck_io_num = 27,
      .ws_io_num = 26,
      .data_out_num = 25,
      .data_in_num = I2S_PIN_NO_CHANGE
  };
  
  a2dp_sink.set_pin_config(my_pin_config);

  loadEinstellungen();
  
  // +++++++++++++++++++++++++++++++++ Audio-Objekt aufbauen
  audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT);

  // NTP-Server und Zeitzone setzen
  configTime(0, 0, NTP_SERVER);
  setenv("TZ", TZ_INFO, 1);

  pinMode(34, INPUT);
  pinMode(35, INPUT);
  pinMode(14, INPUT_PULLUP);
  pinMode(18, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
  
  // ++++++++++++++++++++++++++++++++++ Display initialisieren
  
  lcd.init();
  // Print a message to the LCD.
  lcd.backlight();
  lcd.clear();

  if (conn_mode == 0) {

   // Webradio-Modus
    // +++++++++++++++++++++++++++++++++ WiFi verbinden
    lcd.setCursor(0,0);
    lcd.print("Webradio");
    WiFi_conn();

    // +++++++++++++++++++++++++++++++++ Drehgeber initialisieren
    //start rotary encoder instance
    rotaryEncoder.begin();
    rotaryEncoder.setup(readEncoderISR);
    rotaryEncoder.setBoundaries(0, STATIONS, true);
    rotaryEncoder.disableAcceleration();

    server.on("/", display_root);
    server.on("/set", [](){
      strcpy(ssid, server.arg("ssid").c_str());
      strcpy(password, server.arg("pass").c_str());
  
      pref.begin("wr_settings", false);
        pref.putString("ssid", server.arg("ssid"));
        pref.putString("password", server.arg("pass"));
      pref.end();
      WiFi_conn();
      server.send(200, "text/html", "<html><body>Die Zugangsdaten wurden gespeichert. Verbindungsaufbau wird versucht...</body></html>");
    });
    
    server.begin();
    
    senderEinstellen(curStation);
  } else {
    // Bluetooth-Audio-Modus
    showTemp_bluetooth();
    // Pins für Bluetooth Audio konfigurieren
    i2s_pin_config_t my_pin_config = {
        .bck_io_num = 27,
        .ws_io_num = 26,
        .data_out_num = 25,
        .data_in_num = I2S_PIN_NO_CHANGE
    };
    
    a2dp_sink.set_pin_config(my_pin_config);
    a2dp_sink.start("MyMusic"); 
  }
  
  rotaryEncoder2.begin();
  rotaryEncoder2.setup(readEncoder2ISR);
  rotaryEncoder2.setBoundaries(0, 12, false);
  rotaryEncoder2.disableAcceleration();

  set_volume();

}


void loop()
{
  if (conn_mode==0) {
    String sendername = String(stationlist[curStation].name);
    server.handleClient();
    
    // Prüfen, ob an Regler eins geschraubt/gedrückt wird
    rotary_loop();
  }

  if (millis()-lasttimecheck > 1000) {
    get_rtc_time();
    lasttimecheck = millis();
    refresh_time();
  }
  
  button.loop();
  audio.loop();
  rotary_loop2();


  if (millis()-lastvolchange > 3000) {
    setMode = 0;
  }

  if (lastdispchange==0 || (millis()-lastdispchange > 5000)) {
    Serial.println("Drin in Display-Schleife!");
    if (displayMode==0) {
      // Immer wenn sich der Titel ändert, wird die Temperatur refreshed...
      showTemp();
    } else {
      if (conn_mode==0) {
        if (titleinfo !="" && titleinfo!="www.radiobob.de") {
          showTitle();
        } else {
          showStation();
        } 
      } else {
        showTemp_bluetooth();
      }
    }
    lastdispchange = millis();
  }
  
  
}

// RotaryEncoder 1: 
// Sender durchblättern (Drehen) und wählen (Drücken)
void rotary_loop()
{
  //dont do anything unless value changed
  if (rotaryEncoder.encoderChanged())
  {
    uint16_t v = rotaryEncoder.readEncoder();
    Serial.printf("Station: %i\n",v);
    //set new currtent station and show its name
    if (v < STATIONS) {
      curStation = v;
      showStation();
      lastchange = millis();
    }
  }
  //if no change happened within 10s set active station as current station
  if ((lastchange > 0) && ((millis()-lastchange) > 10000) && displayMode==1){
    curStation = actStation;
    lastchange = 0;
    //showStation();
    lcd.clear();
    showTitle();
  }
  //react on rotary encoder switch
  if (rotaryEncoder.isEncoderButtonClicked())
  {
    //set current station as active station and start streaming
    actStation = curStation;
    Serial.printf("Active station %s\n",stationlist[actStation].name);
    senderEinstellen(actStation);
    //startUrl();
    //call show station to display the speaker symbol
    //showStation();
    showTitle();
  }
}

// RotaryEncoder 2
// Standard beim Drehen: Volume einstellen
// Drücken = Umschalten des Anzeigemodus

void rotary_loop2()
{
  //dont do anything unless value changed
  if (rotaryEncoder2.encoderChanged())
  {
    lastdispchange=millis();
    set_volume();
  }

  //react on rotary encoder switch
  if (rotaryEncoder2.isEncoderButtonClicked())
  {
    if (displayMode == 0) {
      displayMode = 1;
    } else {
      displayMode = 0;
    }
    // Damit sofort umgeschaltet wird....
    lastdispchange=0;
  }
}

void WiFi_conn() {
  
  wifi_conn_success=true;
  
  WiFi.disconnect();
  WiFi.mode(WIFI_AP_STA);
  WiFi.softAP("webradio", "123456789");


  Serial.println("Verbinden mit folgenden Zugangsdaten:");
  Serial.print("SSID:");Serial.println(ssid);
  Serial.print("Passwort:");Serial.println(password);

  WiFi.begin(ssid, password);
  
  int i = 0;
  // Nur wenn wir noch nicht verbunden sind, wird jetzt neu verbunden
  unsigned long pause = 10000;
  connTimer = millis();
  while (WiFi.status() != WL_CONNECTED && (millis() - connTimer < pause)) {
    //while (WiFi.status() != WL_CONNECTED && connTimer < connCancel){
    Serial.print(".");
    i++;
    delay(500);
  }
  
  if (WiFi.status() != WL_CONNECTED) {
    WiFi.disconnect();
    WiFi.softAP("webradio", "123456789");
    IPAddress IP = WiFi.softAPIP();
    Serial.print("AP IP address: ");
    Serial.println(IP);
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Kein WLAN");
    wifi_conn_success=false;
  }
}

void display_root() {
  const char * httpType PROGMEM = "text/html";
  //server.send(200, "text/html", "");
  server.send_P(200,  httpType, indexPage);
}

void loadEinstellungen() {
   // Zuletzt eingestellten Sendern ermitteln und dann direkt laden
  pref.begin("wr_settings", false);
    curStation = pref.getUInt("curStation", 0);
    conn_mode = pref.getUInt("conn_mode", 0);
    strcpy(ssid, pref.getString("ssid").c_str());
    strcpy(password, pref.getString("password").c_str());
  pref.end();

}


void senderEinstellen(int selectedStation) {
  Serial.println("Sender wird eingestellt am Display");
  audio.connecttohost(stationlist[selectedStation].url);
  //lcd.setCursor(0,0);
  //lcd.print(stationlist[selectedStation].name);
  // Sender speichern, dass dieser beim neuen Einschalten des Radios wieder gewählt wird
  pref.begin("wr_settings", false);
    pref.putUInt("curStation", selectedStation);  
  pref.end();
}



void set_dispmode() {
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Anzeigemodus");
  if (displayMode == 0) {
    displayMode = 1;
    lcd.setCursor(0,1);
    lcd.print("Sender / Titel");
  } else {
    displayMode = 0;
    lcd.setCursor(0,1);
    lcd.print("Datum / Temp / Luft");
  }
}

void set_volume() {
  uint16_t v = rotaryEncoder2.readEncoder();
  Serial.print("Encoder-Position:");Serial.println(v);
  volume = map(v, 0, 12, 0, 12);
  Serial.print("Volume:");Serial.println(volume);
  audio.setVolume(volume);
  show_volume();
  lastchange = millis();
}


void show_volume() {
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Volume: ");
  lcd.print(volume);
}

void showStation() {
  // Display aktualisieren
  lcd.clear();
  if (curStation == actStation) {
    lcd.home();
    lcd.print(char(1));
  }
  lcd.setCursor(2,0);
  String name = String(stationlist[curStation].name);
  if (name.length() < 20)
    lcd.print(name);
  else {
    uint8_t p = name.lastIndexOf(" ",20); //if name does not fit, split line on space
    lcd.print(name.substring(0,p));
    lcd.setCursor(0,1);
    lcd.print(name.substring(p+1,p+21));
  }

}

void showTitle() {
  // Display aktualisieren

  if (titleinfo_old != titleinfo) lcd.clear();
  
  // Sender anzeigen
  lcd.setCursor(0,0);
  // Sender anzeigen
  String name = String(stationlist[curStation].name);
  lcd.print(name);
  
  lcd.setCursor(0,1);
  if (titleinfo.length() < 21)
    lcd.print(titleinfo);
  else {
    uint8_t p = titleinfo.lastIndexOf(" ",20); //if name does not fit, split line on space
    lcd.print(titleinfo.substring(0,p));
    lcd.setCursor(0,2);
    lcd.print(titleinfo.substring(p+1,p+21));
  }
  titleinfo_old=titleinfo;
}



void refresh_time() {
  lcd.setCursor(0,3);
  lcd.print(currentDate);
}

void showTemp() {
  // Temperatur / Luftfeuchtigkeit oben, Uhrzeit unten
  temp = sht.getTemperature();  // get temp from SHT 
  humidity = sht.getHumidity(); // get temp from SHT
  if (titleinfo_old != titleinfo) lcd.clear();
  lcd.setCursor(0,0);
  if (titleinfo_old != titleinfo) lcd.clear();
  if (titleinfo.length() < 21)
    lcd.print(titleinfo);
  else {
    uint8_t p = titleinfo.lastIndexOf(" ",20); //if name does not fit, split line on space
    lcd.print(titleinfo.substring(0,p));
    lcd.setCursor(0,1);
    lcd.print(titleinfo.substring(p+1,p+21));
  }
  titleinfo_old=titleinfo;

  lcd.setCursor(0,2);
  lcd.print(temp);
  lcd.print(" C ");
  lcd.print(humidity);
  lcd.print(" % ");
  //lcd.setCursor(0,1);
  //lcd.print(currentDate);
}

void showTemp_bluetooth() {
  // Temperatur / Luftfeuchtigkeit oben, Uhrzeit unten
  temp = sht.getTemperature();  // get temp from SHT 
  humidity = sht.getHumidity(); // get temp from SHT
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Bluetooth Audio");
  lcd.setCursor(0,2);
  lcd.print(temp);
  lcd.print(" C ");
  lcd.print(humidity);
  lcd.print(" % ");
  //lcd.setCursor(0,1);
  //lcd.print(currentDate);
}

void audio_showstreamtitle(const char *info){
    Serial.print("streamtitle ");Serial.println(info);
    titleinfo = info;
}

bool get_rtc_time() {
  time(&now);
  localtime_r(&now, &timeinfo);

  currentHour = timeinfo.tm_hour;
  currentMinute = timeinfo.tm_min;
  currentSecond = timeinfo.tm_sec;
  monthDay = timeinfo.tm_mday;
  currentMonth = timeinfo.tm_mon+1;
  currentYear = timeinfo.tm_year+1900;
  sprintf(currentDate, "%02d.%02d.%d %02d:%02d:%02d", monthDay, currentMonth, currentYear , currentHour, currentMinute, currentSecond);
  return true;
}

void scrollText(int row, String message, int delayTime, int lcdColumns) {
  for (int i=0; i < lcdColumns; i++) {
    message = " " + message;  
  } 
  message = message + " "; 
  for (int pos = 0; pos < message.length(); pos++) {
    lcd.setCursor(0, row);
    lcd.print(message.substring(pos, pos + lcdColumns));
    delay(delayTime);
  }
}

void pressed(Button2& btn) {
    if (conn_mode == 0) {
      Serial.println("Umschalten auf Bluetooth");
      pref.begin("wr_settings", false);
        pref.putUInt("conn_mode", 1);
      pref.end();
     
    } else {
      Serial.println("Umschalten auf webradio");
      pref.begin("wr_settings", false);
        pref.putUInt("conn_mode", 0);
      pref.end();
    }

    ESP.restart();
}

In der letzten Funktion void pressed() wird der Modus gesetzt und dann ein Neustart angestoßen.
Wenn du noch Fragen hast, meld dich gerne.

Sorry für das bescheidene Handy-Foto :wink:

Hier ne Ansicht des Displays:

grafik

Hi Daniel,

vielen Dank für deinen Code. Sieht doch alles top aus. Ich werde mal versuchen das Umschalten zwischen Radio/BT bei mir zu implementieren.

Viele Grüße
Jan

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.