GD3200B - Anzahl angezeigter Ordner erst nach 2.tem Auflegen der Karte richtig

Hallo,

@Volker-w:

Probiere doch mal den Abspielmodus Spezial Album von Datei 1 bis letzte Datei aus.
So habe ich mir bis dato beholfen.

Bei mir wird nach Verlassen des Adminmenues und Auflegen einer bekannten Albumkarte die Anzahl 332 angezeigt. Ich kann nur vermuten, daß das die Gesamtzahl aller Dateien
ist oder aus dem Ordner mp3. Nach einem Neustart zeigt mir die Ausgabe beim Auflegen einer Abumkarte vom Ordner 01, da wie ich annehme der Shortcut 3 durch mich zugewiesen ist und ja im Ordner 01 die Datei 001 ist.

Grundlegend bin ich also nicht der Einzige mit diesem Problem.

Gruß!

@pitpossum79 Bitte kein Leerzeichen nach dem @. Dann bekommen die Leute auch eine Benachrichtigung, daß sie erwähnt wurden. Und wenn du ein Zitat von dem User machst, kannst du das komplett sparen. Der Benutzter wird dann so oder so informiert.

Hallo,

@Bastelmatz:

Den Ordner advert habe ich nicht auf der SDKarte.

Warum nicht? Der advert Ordner gehört wie der mp3 Ordner dazu.

Hallo,

Ich hatte kurz die Hoffnung, daß es am Fehlen des advert Ordners liegt (Diskrepanz von 1),
aber selbst nach dem Aufspielen des Selben, keine Änderung.

Hallo Pitpossum79,

habe ich gerade übertprüft, und kann das nur bestätigen. Nach dem Verlassen des Admin Menus erhalte ich ebenfalls die Anzahl von 332 Dateien, beim direkten Start mit einer Karte sind es jedoch 263. Ist also nicht die Gesamtzahl der Dateien.
Bei einem zweiten System ist das Verhalten identisch.

Klingt nach dem advert Ordner. Hast du den als erstes auf die Karte kopiert?

Ein +1 würde nur helfen wenn bei jedem Auflegen einer Karte nicht die Anzahl der Titel des Ordners, sondern des Ordners mit um 1 kleineren Nummer, angezeigt würde. Wenn ich dich richtig verstehe, wird beim 2. Auflegen aber der richtige Ordner betrachtet und nicht der mit der kleineren Nummer.

Hallo Gute Laune,

Danke für den Hinweis, ich habe die SD Karte überprüft. Es ist richtig die Verzeichnisse wurden als erstes kopiert und die Anzahl der Datein in advert ist 263 sowie 332 in MP3. Hast du einen Tip was ich da noch probieren könnte um das Problem zu lösen?

Gruß
Volker

Ich habe gerade eine neue SD Karte erzeugt und die Verzeichnisse 01 bis 05 in der Reihenfolge darauf koriert, anschleißend die Ordner MP3 und advert.
Bei einem Neustart wird jetzt immer die Anzahl der Dateien aus dem zuerst kopierten Ordner angegeben, bei allen folgenden Karten dann die Anzahl der Dateien des vorher gespielten Ordner.

Noch ein Hinweis, wird zuerst mit dem Admin Menu gestartet, dann wir nach dem Verlassen die Anzahl der Dateien im MP3 Verzeichnis hier 332 angezeigt, egal welche Karte aufgelegt wird. Anschließend das Verhalten wir vor beschrieben.

Das Problem scheint hier zu sein

Es scheint als würde mp3.getFolderTrackCount nicht immer den richtigen Wert zurückgeben, sondern häufig den von dem zuvor verwendeten Ordner oder nach dem Start des TonUINO den zuerst ausgespielten.
Da es beim erneuten Auflegen der Karte funktioniert, könnte man versuchen den Befehl gleich 2 mal oder nach dem ersten Track nochmal ausführen.

Wenn ich eure Schilderungen richtig interpretiere, wird immer die Anzahl der Dateien aus dem Ordner angezeigt, der zuletzt gespielt wurde, oder!? Sprich der Parameter des Befehls (die Ordnernummer) wird ignoriert.

Bei meinen Tests war ein ähnliches Verhalten zu beobachten. Ich habe die Ordner 1-12 nacheinander ausgelesen, allerdings hat er mir immer 332 (iirc) zurückgegeben.

Für das korrekte Auslesen müsste man also die Anzahl (nochmal) NACH dem Starten des Titels auslesen oder einen Pseudo-Titel aus dem Ordner abspielen (bspw. 1s Stille, oder den Lautsprecher muten) und anschließend die Anzahl der Dateien in diesem Ordner auslesen. Das würde dann vermutlich den Workaround mit dem doppelten Auflegen der Karte vermeiden.

Hallo,

ich habe es mal mit der Unterstützung von gute_laune mit einem Delay und dem doppelten Aufruf von
numTracksInFolder = mp3.getFolderTrackCount(myFolder->folder);
an besagter Stelle versucht, ohne Erfolg.

Bevor ich den Code ins Unbenutzbare zerschiesse, behelfe ich mit den Spezial Album von bis Karten.

Schein ja aber ein mehrfach reproduzierbares Problem zu sein,
zurückzuführen auf den DFplayer mini mit GD3200B ?!

Trotzdem geniales Projekt!!!

Ein zweifaches auflegen der Karte ist ja nichts anderes als das die Anzahl der Tracks vom vorherigen Ordner übernommen wird, nur ist dieser immer noch der Gleiche. Wird ein neuer Ordner aufgerufen, ist hier wiederum die Anzahl der Dateien die des davor abgespielten, also nicht korrekt. Das Problem ist, wenn von einem Ordner mir großer Anzahl von Dateien in einen mit wenig Dateien gesprungen wird, dann kann das System sich aufhängen bei willkürlicher Auswahl der Startdatei.
Ist bei mir so bei einem Wechsel aus einem Ordner mit 165 Dateien in ein Verzeichnis mit nur 5 Dateien.

Die Verzeichnisnummer wird immer korrekt ausgelesen und auch im Album Modus abgespielt.

Das mit dem doppelten Auslesen der Anzahl von Dateien im Ordner hatte ich auch schon erfolglos versucht. Für weitere Versuche fehlen mir leider sie Programmierkenntnisse.

Trotz allem ein sehr schönes Projekt.

Das ist wohl so, ja.

@pitpossum79 hat noch ausprobiert, was passiert, wenn man am Ende von PlayFolder, wenn aus dem betroffenen Ordner abgespielt wird, noch einmal versucht mp3.getFolderTrackCount(myFolder->folder) auszuführen. Leider kam als Ergebnis nur ein Com Error 129.

Ich habe gestern auch noch ein wenig mit dem GB3200B probiert.

Bei mir war es so, dass getFolderTrackCount sich immer auf den Ordner bezog, wo aktuell ein Titel läuft. Dieser Wert hat sich nicht geändert/aktualisiert, wenn danach ein Titel aus einem anderen Ordner abgespielt wurde und man währenddessen nicht getFolderTrackCount aufruft.

Ein Fix könnte also sein, den getFolderTrackCount erst / nochmal gerade dann durchzuführen, wenn ein Titel aus dem gewünschten Ordner läuft - ggf. braucht es einen kurzen delay (500ms-2s?) nach dem Start des Titels, bis die Abfrage einen korrekten Wert zurückliefert.

1 „Gefällt mir“

Hallo,

habe heute den DFplayer mini mit MH-ET LIVE (MH2024K-24SS) Chip probiert.
(editiert: zuvor MH-ET LIVE (MH2024K-16SS)

KEINE WERBUNG!!!

KEINE WERBUNG!!!
Alles wie es soll, keinen Fehler wie beim GD3200B bzgl. Anzahl Dateien im Ordner.

Eine Anpassung im Code für den GD3200B wäre jedoch für viele andere sehr hilfreich.
Leider traue ich mir das mit meinen jetzigen Programmierkenntnissen nicht zu.
Bin jedoch gerne bereit Vorschläge unter „Anleitung“ zu probieren.

Grüße an alle die das hier möglich machen und am Leben halten!

Ich teile hier dann mal eine mögliche Lösung. @Bastelmatz und ich hatte anscheinend den selben Ansatz.
Damit der Player sicher die Dateien im richtigen Ordner zählt, muss er vorher etwas daraus abspielen. Hierfür eignet sich eine Datei mit Stille. Diese kann man zum Beispiel hier herunterladen. Die Datei muss länger sein als das im Code eingefügte delay, jedoch will man ja auch nicht unnötig Speicher belegen. Getestet wurde mit der 2 Sekunden-Datei. Diese wird dann in jedem Ordner als 000.mp3 eingefügt.

Im Code wird dann bei Start der Wiedergabe zunächst die Stille abgespielt und dann die Anzahl der Tracks im Ordner ermittelt. Wie lange der Player dazwischen braucht muss man ein wenig probieren. Je länger das Delay, desto länger dauert es bis die Wiedergabe beginnt. Ist es allerdings zu kurz, wird die Trackanzahl wieder falsch ermittelt. Am besten probiert man aus, was im eigenen Aufbau gut funktioniert.
Im Code muss dann entsprechend zu Beginn von playFolder() die Wiedergabe der Stille ergänzt werden und diese natürlich bei der Anzahl der ermittelten Tracks wieder abgezogen werden:

void playFolder() {
    Serial.println(F("== playFolder()")) ;
    disablestandbyTimer();
    knownCard = true;
    _lastTrackFinished = 0;
    mp3.playFolderTrack(myFolder->folder, 0);
    Serial.println(F("kurze Pause"));
    delay(1500);  //diese Delay so kurz wie möglich wählen
    numTracksInFolder = mp3.getFolderTrackCount(myFolder->folder) - 1;
    firstTrack = 1;
    Serial.print(numTracksInFolder);
    Serial.print(F(" Dateien & 1 Stille in Ordner "));
    Serial.println(myFolder->folder);
    ...

Vielen Dank an @Volker-W und @pitpossum79 fürs Testen.

3 „Gefällt mir“

Ich antworte mal hier, damit es im Kontext einigermaßen erhalten bleibt.

→ Die Zusammenfassung bez. GB3200B folgt unten.

.

Das ganze DFPlayer Handling ist bei mir eigentlich in den Tonuino_DFPlayer Dateien (.h und .cpp) zusammengefasst.

Da meine Software sich strukturell deutlich von der Standardversion unterscheidet, kann ich leider nicht sagen, ob und wie der nachfolgende Code dafür relevant ist.

Trotzdem folgen hier ein paar vermeintlich relevante Auszüge.

.

Zunächst ein paar Definitionen zum nachfolgenden Verständnis

	static const uint8_t largeFolders = 15; // 1-15
	static const uint8_t smallFolders = 84; // 16-99
	static const uint8_t FOLDERCODE_MP3 = 0;
	static const uint8_t FOLDERCODE_ADVERTISEMENT = 100;
	static const uint8_t TRACKNUMBER_SILENCE = 0;

	static uint16_t tracksFolderLarge[largeFolders];
	static uint8_t tracksFolderSmall[smallFolders];

.

Hier ein Auszug aus der

Tonuino_DFPlayer.cpp:

void TonuinoDFPlayer::setup(uint8_t pinBusy, bool hasChip_GB3200B, bool hasChip_MH2024_16SS)
{
	pin_Busy = pinBusy;
	hasGB3200B = hasChip_GB3200B;
	
	pinMode(pinBusy, INPUT);
	
	// DFPlayer Mini initialisieren
	mp3.begin();
	mp3.ignoreCheckSum = hasChip_MH2024_16SS;
	// Zwei Sekunden warten bis der DFPlayer Mini initialisiert ist
	delay(2000);
	
	tonuinoPlayer.pauseAndStandBy();
}
void TonuinoDFPlayer::start()
{
	if (!isPlaying())
	{
		Serial.println(F("Start player"));
		mp3.start();
		delay(800);
	}
}
uint16_t TonuinoDFPlayer::getFolderTrackCount(uint16_t folder)
{
	if (hasGB3200B)
	{
		// return count from last request
		if (folder > largeFolders)
		{
			uint8_t index = folder - largeFolders - 1;
			if (tracksFolderSmall[index] > 0)
			{
				return tracksFolderSmall[index];
			}
		}
		else
		{
			uint8_t index = folder - 1;
			if (tracksFolderLarge[index] > 0)
			{
				return tracksFolderLarge[index];
			}
		}
		playTrack(folder, TRACKNUMBER_SILENCE);
		delay(100);
		pause();
	}
	uint16_t trackCount = mp3.getFolderTrackCount(folder);
	// save track count for this folder
	if (folder > largeFolders)
	{
		uint8_t index = folder - largeFolders - 1;
		tracksFolderSmall[index] = trackCount;
	}
	else
	{
		uint8_t index = folder - 1;
		tracksFolderLarge[index] = trackCount;
	}
	return trackCount;
}
void TonuinoDFPlayer::playTrack(uint8_t folder, uint16_t track)
{
	Serial.print(F("Play track "));
	Serial.print(track);
	Serial.print(F(" from folder "));
	Serial.println(folder);
	lastStartedFolder = folder;
	lastStartedTrack = track;
	if (folder == FOLDERCODE_ADVERTISEMENT)
	{
		mp3.playAdvertisement(track);
	}
	else
	{
		activeFolder = folder;
		activeTrack = track;
		if (folder == 0 || folder == FOLDERCODE_MP3)
		{
			tonuinoPlayer.pauseAndStandBy();
			mp3.playMp3FolderTrack(track);
		}
		else
		{
			if (track > 255)
			{
				if (folder > 0 && folder <= largeFolders)
				{
					mp3.playFolderTrack16(folder, track);
				}
				else
				{
					Serial.print(F("No large file support for that folder"));
				}
			}
			else
			{
				mp3.playFolderTrack(folder, track);
			}
			delay(PLAYTRACK_DELAY);
		}
	}
}
void TonuinoDFPlayer::trackFinished()
{
	if (hasGB3200B && (lastStartedFolder == FOLDERCODE_ADVERTISEMENT))
	{
		Serial.print(F("Last started track "));
		Serial.print(lastStartedTrack);
		Serial.print(F(" in folder "));
		Serial.println(lastStartedFolder);
		lastStartedFolder = activeFolder;
		lastStartedTrack = activeTrack;
		return;
	}
	
	Serial.print(F("Active track "));
	Serial.print(activeTrack);
	Serial.print(F(" in folder "));
	Serial.print(activeFolder);
	Serial.print(F(", Current track "));
	Serial.println(tonuinoPlayer.currentTrack());
	
	// Somehow the DFPlayer finished event is raised twice
	// Ignore the second finish event 
	// (every new track would have the play track delay)
	if (millis() - timeLastFinished < PLAYTRACK_DELAY)
	{
		Serial.println(F("Finish event ignored!"));
		return;
	}
	bool isCurrentTrack = activeTrack == tonuinoPlayer.currentTrack();
	activeTrack = 0;
	if (isCurrentTrack)
	{
		tonuinoPlayer.trackFinished();
		if (tonuinoPlayer.isPlaying && musicDSLoaded)
		{
			nextTrack();
		}
	}
	timeLastFinished = millis();
}

.

Auszug aus der modifizierten

Tonuino_DFMiniMp3.h:

    void sendPacket(uint8_t command, uint16_t arg = 0, uint16_t sendSpaceNeeded = c_msSendSpace)
    {
		Serial.print("Send DFPlayer command: ");
		Serial.print(command);
		Serial.print(" with argument ");
		Serial.println(arg);
		
            uint8_t out[DfMp3_Packet_SIZE] = { 0x7E,
            0xFF,
            06,
            command,
            00,
            static_cast<uint8_t>(arg >> 8),
            static_cast<uint8_t>(arg & 0x00ff),
            00,
            00,
            0xEF };

		if (ignoreCheckSum)
		{
			out[DfMp3_Packet_HiByteCheckSum] = 0xEF;
			out[DfMp3_Packet_LowByteCheckSum] = 00;
			out[DfMp3_Packet_EndCode] = 00;
		}
		else
		{
			setChecksum(out);
		}
		
        // wait for spacing since last send
        while (((millis() - _lastSend) < _lastSendSpace))
        {
            // check for event messages from the device while
            // we wait
            loop();
            delay(1);
        }

        _lastSendSpace = sendSpaceNeeded;
        _serial.write(out, DfMp3_Packet_SIZE);

        _lastSend = millis();
    }
    uint16_t listenForReply(uint8_t command)
    {
        uint8_t replyCommand = 0;
        uint16_t replyArg = 0;

        do
        {
            if (readPacket(&replyCommand, &replyArg))
            {
                if (command != 0 && command == replyCommand)
                {
                    return replyArg;
                }
                else
                {
                    switch (replyCommand)
                    {
                    case 0x3c: // usb
                        T_NOTIFICATION_METHOD::OnPlayFinished(DfMp3_PlaySources_Usb, replyArg);
                        break;

                    case 0x3d: // micro sd
					case 0x4c:
                        T_NOTIFICATION_METHOD::OnPlayFinished(DfMp3_PlaySources_Sd, replyArg);
                        break;

                    case 0x3e: // flash
                        T_NOTIFICATION_METHOD::OnPlayFinished(DfMp3_PlaySources_Flash, replyArg);
                        break;

                    case 0x3F:
                        _isOnline = true;
                        T_NOTIFICATION_METHOD::OnPlaySourceOnline(static_cast<DfMp3_PlaySources>(replyArg));
                        break;

                    case 0x3A:
                        _isOnline = true;
                        T_NOTIFICATION_METHOD::OnPlaySourceInserted(static_cast<DfMp3_PlaySources>(replyArg));
                        break;

                    case 0x3B:
                        _isOnline = true;
                        T_NOTIFICATION_METHOD::OnPlaySourceRemoved(static_cast<DfMp3_PlaySources>(replyArg));
                        break;

                    case 0x40:
                        T_NOTIFICATION_METHOD::OnError(replyArg);
                        return 0;
                        break;

                    default:
                        // unknown/unsupported command reply
                        break;
                    }
                }
            }
            else
            {
                if (replyArg != 0)
                {
                    T_NOTIFICATION_METHOD::OnError(replyArg);
                    if (_serial.available() == 0)
                    {
                        return 0;
                    }
                }
            }
        } while (command != 0);

        return 0;
    }

.

Auszug aus der

Tonuino_MainController.cpp:

// DFPlayer Mini initialisieren
	dfPlayer.setup(pinConfig.DFPlayer_Busy, hwConfig.Chip_GB3200B, hwConfig.Chip_MH2024_16SS);
	
	// set settings
	dfPlayer.volumeMin = swConfig.VolumeMin;
	dfPlayer.volumeMax = swConfig.VolumeMax;
	dfPlayer.volumeIncrement = swConfig.VolumeIncrement;
	dfPlayer.setVolume(swConfig.VolumeInit);
	dfPlayer.setEqualizer(swConfig.Equalizer);

	[...]

	dfPlayer.start();
	// give DFPlayer some more time to init (otherwise finish event of MP3 track is not generated)
	delay(1000);
	// play startup sound
	dfPlayer.playMP3AndWait(261);

.
.
.

Anmerkungen

In meiner getFolderTrackCount() Methode habe ich noch folgende Anpassungen drin:

  • Speichern der Titelanzahl in einem Array

    • Da sich die Titelanzahl in dem Ordner während des Betriebs nicht ändert
    • Bei der nächsten Abfrage für diesen Ordner, wird dieser Wert zurückgegeben
    • Es wird nicht erneut „Stille“ abgespielt und auch kein mp3.getFolderTrackCount(folder) Aufruf
  • Da ich in meiner Software LargeFolder * unterstütze, ist das o.g. Array-Handling auf „Large“ und „Small“ folder aufgeteilt (um 84 Byte Speicherplatz zu sparen)

    • .* „Large“ Ordner sind die Ordner (0 bzw.) 1-15, wo mehr als 255 Titel enthalten sein können.
      • Um genau zu sein, können bis zu 3000 Titel in diesen Ordnern enthalten sein

.
.
.

Anpassungen für Chip GB3200B:

Wenn ich das richtig überblicke, sind folgende Anpassungen relevant:

  • Einen Titel aus genau dem Ordner abspielen, wo man die Titelanzahl mit getFolderTrackCount(folderNumber) ermitteln will.
    • Vorzugsweise einen Titel ohne echte Geräusche also „Stille“, bspw:
	playTrack(folder, TRACKNUMBER_SILENCE);
	delay(100);
	pause();
	uint16_t trackCount = mp3.getFolderTrackCount(folder);
  • Das Finish-Event für Advertisement Titel abfangen, bspw. in meinem Kontext (s.o.):
	if (hasGB3200B && (lastStartedFolder == FOLDERCODE_ADVERTISEMENT))
	{
		lastStartedFolder = activeFolder;
		lastStartedTrack = activeTrack;
		return;
	}

.
.
.

Anpassungen für Chip MH2024_16SS:

Wenn ich das richtig überblicke, sind folgende Anpassungen relevant:

  • Ausreichend Verzögerung nach dem mp3.begin() und mp3.start()
    • Afaik 1-x Sekunden, bspw.
	delay(1000);
  • Im DFMiniMP3 die Notification-Case 0x4C hinzufügen, um das FinishEvent zu erzeugen
	case 0x3d: // micro sd
	case 0x4c:
		T_NOTIFICATION_METHOD::OnPlayFinished(DfMp3_PlaySources_Sd, replyArg);
		break;

Sowie die Checksummen Prüfung ignorieren:

	uint8_t out[DfMp3_Packet_SIZE] = { 0x7E,
	0xFF,
	06,
	command,
	00,
	static_cast<uint8_t>(arg >> 8),
	static_cast<uint8_t>(arg & 0x00ff),
	00,
	00,
	0xEF };

	if (ignoreCheckSum)
	{
		out[DfMp3_Packet_HiByteCheckSum] = 0xEF;
		out[DfMp3_Packet_LowByteCheckSum] = 00;
		out[DfMp3_Packet_EndCode] = 00;
	}
	else
	{
		setChecksum(out);
	}
1 „Gefällt mir“