pschatzmann / arduino-audio-tools

Arduino Audio Tools (a powerful Audio library not only for Arduino)
GNU General Public License v3.0
1.48k stars 232 forks source link

Need help with playing a mp3 from sd #1745

Closed Semtexmagix closed 1 day ago

Semtexmagix commented 1 day ago

Problem Description

Hello everyone, I have an AI Thinker ESP32 A1S board with version 2.2 A417. So far, I have written a small program that works. However, when I try to play a sound from the SD card, either the sketch is too large or I get other compilation errors. Can someone help me and add the last missing function? When I press button 3, a sound from the SD card should play. That's all I need!

Device Description

AI Thinker ESP32 A1S board with version 2.2 A417

Sketch

#include <Arduino.h> 
#include <WiFi.h>
#include <WebServer.h>
#include <SD_MMC.h> // Verwende die SD_MMC-Bibliothek
#include <time.h> // Für die Zeitfunktion

// Definiere die Pins für die Tasten
#define BUTTON_KEY3 19

// WLAN-Zugangsdaten
const char* ssid = "xxx";          // Ersetze mit deinem WLAN-Namen
const char* password = "xxx";  // Ersetze mit deinem WLAN-Passwort

WebServer server(80); // Erstelle einen Webserver, der auf Port 80 hört

// Variablen zur Speicherung der Statusausgaben
String output = "";

// Funktion zum Erhalten des aktuellen Zeitstempels
String getTimestamp() {
    struct tm timeinfo;
    if (!getLocalTime(&timeinfo)) {
        return "Error"; // Gibt "Error" zurück, wenn die Zeit nicht abgerufen werden kann
    }
    char buffer[16];
    strftime(buffer, sizeof(buffer), "%H:%M:%S", &timeinfo);
    return String(buffer);
}

// Funktion zum Auflisten der Dateien auf der SD-Karte
String listFiles() {
    String fileList = "";
    File root = SD_MMC.open("/");
    File file = root.openNextFile();

    while (file) {
        fileList += String(file.name()) + "\n";
        file = root.openNextFile();
    }
    if (fileList.length() == 0) {
        fileList = "Keine Dateien gefunden.";
    }
    return fileList;
}

// Funktion zum Lesen des Inhalts einer Datei
String readFile(String filename) {
    File file = SD_MMC.open("/" + filename, FILE_READ);
    if (!file) {
        return "Datei konnte nicht geöffnet werden.";
    }

    String fileContent = "";
    while (file.available()) {
        fileContent += char(file.read());
    }
    file.close();
    return fileContent;
}

void handleRoot() {
    // HTML-Inhalt für die Webseite
    String html = "<html><body><h1>Serieller Monitor</h1>"
                  "<pre id='status'>" + output + "</pre>"
                  "<h2>Dateien auf der SD-Karte</h2>"
                  "<pre id='filelist'>" + listFiles() + "</pre>"
                  "<form action='/readfile' method='GET'>"
                  "Dateiname: <input type='text' name='filename'>"
                  "<input type='submit' value='Datei lesen'>"
                  "</form>"
                  "<script>"
                  "setInterval(function() {"
                  "  fetch('/status')"
                  "    .then(response => response.text())"
                  "    .then(data => { document.getElementById('status').innerText = data; });"
                  "}, 1000);" // Aktualisiere alle 1 Sekunde
                  "</script>"
                  "</body></html>";
    server.send(200, "text/html", html); // Sende die HTML-Seite zurück
}

void handleStatus() {
    server.send(200, "text/plain", output); // Sende den aktuellen Status als Plain Text
}

void handleFileRead() {
    if (server.hasArg("filename")) {
        String filename = server.arg("filename");
        String content = readFile(filename);
        server.send(200, "text/plain", content); // Sende den Dateinhalt als Plain Text
    } else {
        server.send(400, "text/plain", "Fehlender Dateiname."); // Fehler, falls kein Dateiname angegeben wurde
    }
}

void setup() {
    Serial.begin(115200); // Initialisiere die serielle Kommunikation

    // Setze die Button-Pins als Eingänge
    pinMode(BUTTON_KEY3, INPUT_PULLUP);

    // Verbinde mit dem WLAN
    WiFi.begin(ssid, password);
    Serial.print("Verbinde mit WLAN...");

    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }

    Serial.println();
    Serial.print("Verbunden mit WLAN! IP-Adresse: ");
    Serial.println(WiFi.localIP()); // Zeige die lokale IP-Adresse an

    // Zeit synchronisieren
    configTime(3600 * 2, 0, "pool.ntp.org", "time.nist.gov"); // UTC+2 für Sommerzeit

    // Warten, bis die Zeit synchronisiert ist
    delay(1000); // Kurze Verzögerung, um sicherzustellen, dass die Zeit abgerufen werden kann

    // Jetzt den Output mit Zeitstempel aktualisieren
    output += getTimestamp() + " - Verbunden mit WLAN! IP-Adresse: " + WiFi.localIP().toString() + "\n";

    // Definiere die Routen für den Webserver
    server.on("/", handleRoot);        // Handle root URL
    server.on("/status", handleStatus); // Handle status URL
    server.on("/readfile", handleFileRead); // Handle Datei lesen

    // Starte den Server
    server.begin();
    Serial.println("Webserver gestartet. Port: 80");
    output += getTimestamp() + " - Webserver gestartet. Port: 80\n";

    // SD-Karte im MMC-Modus initialisieren
    Serial.println("Starte SD-Karteninitialisierung...");
    output += getTimestamp() + " - Starte SD-Karteninitialisierung...\n";

    if (!SD_MMC.begin()) {
        Serial.println("SD-Karte konnte nicht initialisiert werden!");
        output += getTimestamp() + " - SD-Karte konnte nicht initialisiert werden!\n";
        while (true); // Halte die Ausführung an
    }

    Serial.println("SD-Karte erfolgreich initialisiert!");
    output += getTimestamp() + " - SD-Karte erfolgreich initialisiert!\n";

    // Teste das Schreiben einer Datei auf die SD-Karte
    Serial.println("Versuche, eine Testdatei zu schreiben...");
    output += getTimestamp() + " - Versuche, eine Testdatei zu schreiben...\n";

    File file = SD_MMC.open("/test.txt", FILE_WRITE);
    if (file) {
        file.println("Hallo von der SD-Karte!"); // Schreibe etwas in die Datei
        file.close(); // Schließe die Datei
        Serial.println("Datei erfolgreich geschrieben.");
        output += getTimestamp() + " - Datei erfolgreich geschrieben.\n";
    } else {
        Serial.println("Fehler beim Öffnen der Datei zum Schreiben.");
        output += getTimestamp() + " - Fehler beim Öffnen der Datei zum Schreiben.\n";
    }
}

void loop() {
    // Temporärer Output-String
    String newOutput = ""; 

    // Überprüfe die Tasten mit Entprellung
    static unsigned long lastPressTime = 0; // Zeit des letzten Tastendrucks
    unsigned long currentTime = millis(); // Aktuelle Zeit

    if (currentTime - lastPressTime > 200) { // Warte 200 ms zwischen den Tastendrücken
        if (digitalRead(BUTTON_KEY3) == LOW) {
            newOutput += getTimestamp() + " - Türklingel wurde gedrückt!\n";
            lastPressTime = currentTime; // Aktualisiere die Zeit des letzten Tastendrucks
        }
    }

    // Wenn neue Ausgaben vorhanden sind, aktualisiere den globalen Output
    if (newOutput.length() > 0) {
        output += newOutput; // Füge neue Ausgaben hinzu
        Serial.println(newOutput); // Debug-Ausgabe im seriellen Monitor
    }

    // Sende den gesamten Output an die Webseite
    server.handleClient(); // Überprüfe, ob ein Client eine Anfrage gesendet hat
    delay(100); // Kurze Verzögerung, um den Loop nicht zu überlasten
}

Other Steps to Reproduce

No response

What is your development environment

Arduino

I have checked existing issues, discussions and online documentation

pschatzmann commented 1 day ago

But your sketch does not contain any logc to play any file!

Just read the documentation abaut codecs and look at the many examples that play files. Independently of the file library you can use the player or just copy the file as described in the codec wiki.

As far as your memory errors are concearned, I guess you just fogot to set a proper Partition Scheme!

Last but not least please follow this advice!

ps. Use issues only to report bugs as instructed in the Readme!