ESP32 Port inkl. Webinterface


#61

Zeig mal bitte den Code, wie du die Lib initialisierst und nutzt, vielleicht kann man dann erkennen was da schief läuft.


#62

Hi Christopher,

Coooollllll…

ich versuche alle Komponenten in ein Rohr zupacken und led streifen drumherum zu wickeln, um die Schatten zu vermeiden…für den Schatten des NFC readers:

werde versuchen einen runden Aufkleber von innen zu kleben, somit habe ich einen runden Schatten, der gleichzeitig als Positionierungs-Kennzeichnung für figuren/Karten/Chips dient.


#63

Also mein Code sieht wie folgt aus (nur der Teil der Preferences betrifft daher im setup() die Punkte am Anfang und am Ende).
Ich hatte zwischenzeitlich auch schon vor jedem lesen preferences.begin() und danach preferences.end() gesetzt, mit dem selben Ergebnis das immer das Password sowohl in ssid als auch pw gedpeichert werden.
Hatte dann auch noch zusätzlich für ssid und pw unterschiedliche Namespace verwendet mit immer noch selbem Ergebnis.

#include <Preferences.h>

//EEPROM Speicher *NVS*
Preferences preferences;

=======================

void handleSetup(){
  server.send ( 200, "text/html", SetupPage() );
  if (server.args() > 0 ) { // Arguments were received
    for ( uint8_t i = 0; i < server.args(); i++ ) {
      
      Serial.print("Vom Server wurde folgendes empfangen: "); // Hier stimmt die Zuordnung zu dem was von der Website kommt
      Serial.print(server.argName(i)); // Zeigt das Argument, also ob es um ssid oder pw handelt
      Serial.print("=");
      Serial.println(server.arg(i)); //Zeigt den jeweils Empfangenen String also die ssid oder das pw
      
      if(server.argName(i) == "ssid" ){
        Serial.print("Speichere SSID: ");
        Serial.println(server.arg(i));
        preferences.putString("SSID", server.arg(i));
   
      }
        
      else if(server.argName(i) == "pw"){
        Serial.print("Speichere PW: ");
        Serial.println(server.arg(i));
        preferences.putString("PW", server.arg(i));

      }


      
       
      }
     preferences.end();
    }
}

===============================
void setup(){........

  preferences.begin("my-wifi",false); // my-wifi = Namespace; false = Lesen und Schreiben erlaubt
  ssid = preferences.getString("SSID").c_str();
  password = preferences.getString("PW").c_str();


  // Connect to Wi-Fi network with SSID and password
  Serial.print("Connecting to SSID ");
  Serial.print(ssid);
  Serial.print(" with teh following PW:  ");
  Serial.println(password);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    timeout--;
    if(!timeout){
      
      //Eigenständiger AP
      const char* ssid_AP     = "TonUINO-Access-Point";
      WiFi.softAP(ssid_AP);
      IPAddress IP = WiFi.softAPIP();
      Serial.println("");
      Serial.print("Access Point gestartet da Zugang zu WLAN nicht möglich; IP Addresse: ");
      Serial.println(IP);
      server.on("/", handleSetup);                // INI wifimanager Index Webseite senden
      server.on("/restart", handleRestart);  
      server.begin();
      while(1)server.handleClient();
      
    }
  }

.......}


#64

Guten Tag,

ich bin sehr interessiert und finde das Projekt mit dem esp32 super, gibt es schon ein Schaltplan ? oder welche Pin ihr benutzt?

viele Grüße in die Runde


#65

Aktuell laufen ja hier zwei verschiedene Ansätze, einmal mit dem VS1053 als MP3 Decoder, der dann auch zum Onlinradio hören oder W-LAN Speaker u.Ä. benutzt werden kann und mein Ansatz, der weiterhin den DFPlayer benutzt.

und


#66

Danke Christopher für die schnelle Antwort,

ah ok danke für die Info, ich habe aktuell ESP32 mit dem DFPlayer und das RFID Modul. Die Belegung vom Nano kann ich ja nich eins zu eins übernehmen. Hast du eventuell die Belegung?


#67

Der ist jetzt nicht schön aber Ich hoffe es reicht :wink:
Belegung RC522:

  • SDA -> 21
  • SCK -> 18
  • MOSI -> 23
  • MISO -> 19
  • IRQ -> nicht benutzt
  • GND -> GND
  • RST -> 22
  • 3V3 -> 3V3


#68

Das schöne beim ESP32 ist ja, dass man die Pins nahezu beliebig anschließen kann.

Gewisse Kombinationen sind besser (weil schneller) aber grundsätzlich ist es für unsere Anwendung gr hier egal.


#69

…für mich macht der Port zum ESP32 nur in Verbindung mit dem VS1053 Sinn. Damit auch Streams abgespielt werden können (KiraKa z.B.)

Nur wegen dem bespielen der MP3s… wäre mir zu wenig für zu viel Aufwand…


#70

Stimmt schon dass das viel Spielerei ist die man eventuell selten nutzt aber das hier machen wir ja eh nur zum Spaß :wink:

Habe eben mal ein bisschen gestöbert auf der Seite von VLSI und diesen Kandidaten gefunden " VS1005"
http://www.vlsi.fi/en/products/vs1005.html

Das Ding ist der Hammer der kann Musikalisch so ziemlich alles. Ist leider aber nicht ganz billig…
https://shop.egnite.de/de/hersteller-marken/vlsi/development-boards/484/vlsi-vs1005-breakout-board?gclid=EAIaIQobChMIjtzFzryv3wIVWPhRCh1YpggaEAkYASABEgIHAfD_BwE

zumindest wenn man den nicht selbst gelötet bekommt


#71

Ist wieder lieferbar, ähnliche Maße wie mein Würfel aber nur halb so teuer


#72

So ich habe das Projekt jetzt abgeschlossen da Weihnachten vor der Tür steht und Ich die Box gestern verpackt habe damit Sie morgen unterm Baum liegen kann. Den letzten Stand habe Ich auf Github geladen

Als nächstes werde ich mich der Vs1053 Fraktion anschließen, da dies nach einiger Recherche vom Preis/Leistungs-Verhältnis am besten ist. Hatte aber noch die Idee ein einfaches Fm-Radio zu integrieren da die Chips nur 3€ kosten plus eben noch ein paar Cent für den Audio umschalt IC.

Frohe Weihnachten und schöne Feiertage.


#73

FM macht kein Sinn mehr wird ja eingestellt in absehbarer Zeit

Außerdem gibt es ja eigentlich alles als Stream

Aber schön das es mehr werden


#74

Auch wieder wahr.

Habe eben nochmal bezüglich ESP32 und MP3 Decoding gesucht, dabei habe Ich nicht nur ansätze gefunden die MP3 in Software decodieren, sondern auch das schöne Teil hier:


#75

…WTF… Unglaublich was alles auf dem kleinem Ding ist.


#76

Wie sieht es denn jetzt an der VS1053 Front aus, habt ihr euch für eines der angefangenen Projekte entschieden? Und wenn ja mit welchen Boards genau wird gearbeitet, damit der Source Code möglichst nicht angepasst werden muss?


#77

Ich arbeite mit dem Code von Mike. Finde den Ansatz mit den einzelnen Modulen und den RTOS Tasks gut. Mein Plan für die nächsten Tage:

  • vs1053 Library weiter anpassen
    • Position speichern / resume ist erledigt
    • Vor- und Zurückspulen
    • Ansage Funktion einbauen
    • aufräumen
  • KY 040 für Laustärke integrieren
    • 90 % erledigt
  • RFID Reader
    • Der Code ist ja soweit ich gesehen habe fertig
  • Funktionen von Tonuino übernehmen
    • Hier weiß ich noch nicht, wie ich vorgehen soll. Am liebsten würde ich sehr nahe am Code von Thorsten bleiben, auf der anderen Seite macht das nur begrenzt Sinn. Die letzte Position des Tracks speichere ich z.B. direkt in einer Datei auf der SD-Karte. Das würde ich eigentlich auch gerne mit den Einstellungen der Karte machen und eben nicht auf der Karte selbst.
      Was meint Ihr?
  • RGB Status LEDs
  • Standby / deep sleep
  • WebDAV Server für SD Zugriff / Webserver (der ist doch auch fertig, oder?)

Aktuell denke ich, ist die Hatdware noch nicht so kritisch. Ich habe einen Sparkfun ESP32 Thing, Adafruit feather vs1053. Beim Adafruit halte ich es für interessant, dass man ihn mit anderen fertigen Modulen stacken könnte.


#78

Bei meinem Ansatz sollte man später die eigentliche Abspielfunktion (Klasse) ohne Probleme gegen eine andere austauschen lassen ohne das man den Rest anpassen muss.

  • RFID habe ich die letzten Tage noch einmal überarbeitet, damit auch Ultra Karten benutzt werden könne und die Funktion zum Schreiben beliebig aufgerufen werden kann

  • ich habe eine CLI integriert, so dass man Admin Funktionen auch über die serielle Schnittstelle nutzen kann

  • LED würde ich als eigenen Task integrieren und per EventGroup von FreeRTOS steuern. Dann kann jeder Task einfach seinen Status an die LED melden und der Task entscheidend dann was angezeigt wird

  • Buttons fehlen noch, sollten aber bei dem aktuellen Ansatz kein Problem sein

  • um richtig Strom zu sparen muss man sich h noch einmal die komplette Schaltung ansehen (insbesondere die diversen Spannungswandler könnte man durch einen ersetzen) das benötigt aber Änderungen an der Hardware

  • Einstellungen würde ich zum Teil auf der SD Karte und zum anderen Teil im Eeprom des ESP speichern.

Alles in allem ist dies aber auch mein erstes Projekt mit einem RTOS und von daher ist die Umsetzung noch alles andere als optimal. Aber dafür gibt es dann halt irgendwann eine V2 wenn man die ersten Erfahrungen gesammelt hat.

@Christian das mit dem Position speichern/resume würde ich mir gerne mal ansehen. Ich hab mir zwar schon überlegt, wie es funktionieren müsste, bin aber noch nicht zum umsetzen gekommen.


#79

Vielen Dank für die schnellen ausführlichen Antworten.

@Christian Nachdem was Ich gelesen habe würde Ich auch hierzu tendieren.

@TheSealion Ich habe auch schon darüber nachgedacht eine komplett eigenständige Platine zu entwerfen da man hier dann auch direkt einen Verstärker (pam8403a o.ä.) integrieren kann genauso wie die LiPo Ladeschaltung und auch die Schaltregler für 3.3V und 5V nur einmal braucht.


#80

Ich habe die stop_mp3client Funktion angepasst und speichere die aktuelle Fileposition in die Datei: trackname.pos. Ich habe bisher darauf verzichtet die Sekunden zu berechnen - abhängig von der Bitrate, denke ich. Ich werde wohl noch ein wenn > 50 dann -50 hinzufügen.

--- EnRav-master\lib\VS1053\src\vs1053_ext.cpp
+++ TonieCloneESP32\lib\VS1053\src\vs1053_ext.cpp
@@ -883,11 +897,39 @@
 }
 //---------------------------------------------------------------------------------------
 void VS1053::stop_mp3client(){
+    
+    if (mp3file) {
+        String MyTmpDir;
+        ESP_LOGD(TAG, "Current File: %s", mp3file.name());
+        ESP_LOGD(TAG, "Current File position: %d", mp3file.position());
+        String MyTmpName = mp3file.name();
+        MyTmpName = MyTmpName.substring(0,MyTmpName.length() - 4) + ".pos";
+        ESP_LOGD(TAG, "Pos File: %c", MyTmpName);
+        fs::FS &fs=SD;
+        MytmpFile=fs.open(MyTmpName, FILE_WRITE);
+        if(MytmpFile.print(mp3file.position())){
+            ESP_LOGV(TAG, "Successfully saved file position");
+        } else {
+            ESP_LOGV(TAG, "Writing file position failed");
+        }
+        MytmpFile.close();
+
+
+        
+    }
+
+    stopSong();
+
     int v=read_register(SCI_VOL);
+    write_register(SCI_VOL, 0);  // Mute while stopping
+    
+    
+
+    
     mp3file.close();
     m_f_localfile=false;
     m_f_webstream=false;
-    write_register(SCI_VOL, 0);  // Mute while stopping
+    
 //    while(client.connected())
 //    {
 //        if(vs1053_info) vs1053_info("Stopping client\n"); // Stop connection to host
@@ -908,7 +950,7 @@
     String extension="/";                                 // May be like "/mp3" in "skonto.ls.lv:8002/mp3"
     String hostwoext;                                     // Host without extension and portnumber
     String headerdata="";
-    stopSong();
+    
     stop_mp3client();                                     // Disconnect if still connected
     m_f_localfile=false;
     m_f_webstream=true;
@@ -996,7 +1038,7 @@
     return false;
 }
 //---------------------------------------------------------------------------------------
-bool VS1053::connecttoSD(String sdfile){
+bool VS1053::connecttoSD(String sdfile, bool resumetrack){
 
     const uint8_t ascii[60]={
           //196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215,   ISO
@@ -1009,7 +1051,7 @@
 
     uint16_t i=0, s=0;
 
-    stopSong();
+    
     stop_mp3client();                           // Disconnect if still connected
     clientsecure.stop(); clientsecure.flush();  // release memory if allocated
     m_f_localfile=true;
@@ -1021,6 +1063,7 @@
             if(s!=0) path[i]=s;                 // found a related ASCII sign
         } i++;
     }
+
     path[i]=0;
     m_mp3title=sdfile.substring(sdfile.lastIndexOf('/') + 1, sdfile.length());
     showstreamtitle(m_mp3title.c_str(), true);
@@ -1028,12 +1071,34 @@
 
     fs::FS &fs=SD;
     mp3file=fs.open(path);
+
+    MyTmpString = "";
+    if ((resumetrack) && (fs.exists(sdfile.substring(0,sdfile.length() - 4) + ".pos")) ) {
+        ESP_LOGD(TAG, "Resuming track...");
+        MytmpFile = fs.open(sdfile.substring(0,sdfile.length() - 4) + ".pos");
+        if (MytmpFile) {
+            byte MyIndex = 0;
+            while(MytmpFile.available()) {
+                char c = MytmpFile.read();
+                MyTmpFileBuffer[MyIndex++] = c;
+                MyTmpFileBuffer[MyIndex] = '\0'; // Keep buffer NULL terminated
+            }
+            MytmpFile.close();
+        }
+        int MyVal = atoi(MyTmpFileBuffer);
+        mp3file.seek(MyVal);
+    }
+
+    
          return false;
     }
     return true;
 }
+//---------------------------------------------------------------------------------------
+
+
 //---------------------------------------------------------------------------------------
 bool VS1053::connecttospeech(String speech, String lang){
     String host="translate.google.com";
@@ -1042,7 +1107,7 @@
     m_f_webstream=false;
     m_ssl=true;
 
-    stopSong();
+    
     stop_mp3client();                           // Disconnect if still connected
     clientsecure.stop(); clientsecure.flush();  // release memory if allocated

Ja, Volume im Eeprom, oder? Gibt es etwas “fertiges” um Settings zu speichern? Ich habe ReadCardConfig und WriteCardConfig als Funktion im Kopf. Dort werden dann z.B. unter dem Dateinamen /config/UUI.con die Parameter zu der Karte gespeichert. Das hätte auch den Vorteil, dass man Änderungen am PC, per Web usw. vornehmen könnte.

Ja, würde ich auch so sehen. EventGroup ist allerdings neu für mich.

Ja, das wäre perfekt. Mir ist noch nicht so ganz klar, wie das klappt, wenn wir grundsätzliche Dinge anders machen. Z.B. das Speichern der Konfig nicht mehr auf den Karten.

Den KY-040 habe ich z.B. in dein UserInterface integriert.

Habe ich gerade in deinem neuen Code gesehen…Wenn ich/wir aber z.B. die Konfig auf der SD-Karte speichern, müssten wir dann nicht einfach nur die UUID auslesen -> prüfen ob config auf SD-Karte vorhanden. Oder würde ich dann quasi das Modul cardhandler überschreiben?

Wer würde in Deinem Konzept an die Queue vom UserInterface senden?