Giter Site home page Giter Site logo

makuna / dfminimp3 Goto Github PK

View Code? Open in Web Editor NEW
141.0 141.0 32.0 92 KB

Arduino library for the DFPlayer Mini Mp3 module. Please refer to the Wiki for more details. Please use the GitHub Discussions ask questions as the GitHub Issues feature is used for bug tracking.

License: GNU Lesser General Public License v3.0

C++ 83.16% C 16.84%
arduino arduino-library

dfminimp3's People

Contributors

apehaenger avatar freiform avatar gitter-badger avatar makuna avatar maximecheramy avatar mrmaddin avatar oeddn avatar per1234 avatar schallbert avatar seisfeld avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dfminimp3's Issues

Releases not in sync, when is next tag?

Hi,
I'd like to use the changes done in d603f8e for a project which is intended to be built with either arduino ide or platformio.
Not sure about, but is arduino ide latest version (0.7 as per releases/tags) not containing it yet but defined 1.1.0 as per library.properties having it?
In platformio it is as per https://registry.platformio.org/libraries/makuna/DFPlayer%20Mini%20Mp3%20by%20Makuna also 1.1.0 but two years old?

TLDR: Would you kindly make a new tagged version and maybe do them to both arduino library and platformio library compatible at once?

Thanks!

getTotalFolderCount returns total number of files

I am using an Arduino Nano and DFPlayer aka MP3-TF-16P

in my setup function, I call getTotalFolderCount ();

Serial.print("Folders in SD \t"); Serial.print(mp3.getTotalFolderCount( ));Serial.print("\n");
Serial.print("Tracks in folders **\t"); Serial.print(mp3.getTotalTrackCount ( ));Serial.print("\n");
Serial.print("Tracks in folder 01\t"); Serial.print(mp3.getFolderTrackCount(1));Serial.print("\n");
Serial.print("Tracks in folder 02\t"); Serial.print(mp3.getFolderTrackCount(2));Serial.print("\n");
Serial.print("Tracks in folder 03\t"); Serial.print(mp3.getFolderTrackCount(3));Serial.print("\n");

Output is shown below:
Folders in SD 33
18:53:29.583 -> Tracks in folders ** 33
18:53:29.678 -> Tracks in folder 01 12
18:53:29.724 -> Tracks in folder 02 11
18:53:29.817 -> Tracks in folder 03 10

I think getTotalFolderCount (which inturn calls sendPacket(0x4F); ) counts the total number of tracks rather than the folders.

Has someone tried this command?

Documentation for Mp3Notify class

I cannot find documentation for the Mp3Notify class. I was hoping to use OnPlayFinished() to know when my track has completed playing.

I would like to clear my isPlaying variable when the track is done. Because there is no documentation for the Mp3Notify callbacks, I don't know if they are not working properly or if I have just assumed in error what they do.

Thank you for your time and the great library.

Track numbers above 255

Hi I am struggling to get track numbers above 255 to be returned by the player . I can call them and play them by explicite requesting but can’t seem to get the module to report back via the uint16_t getCurrentTrack(DfMp3_PlaySource source) command
or uint16_t getTotalTrackCount(DfMp3_PlaySource source)

Ay ideas ?

Invalid conversion in lib

Hello! I am attempting to run the "random" example, yet it is failing (invalid conversion from 'uint16_t {aka short unsigned int}' to 'DfMp3_PlaybackMode' [-fpermissive]).
Here is the full stack trace:

/home/fronbasal/Arduino/libraries/DFPlayer_Mini_Mp3_by_Makuna/src/DFMiniMp3.h: In instantiation of 'DfMp3_PlaybackMode DFMiniMp3<T_SERIAL_METHOD, T_NOTIFICATION_METHOD>::getPlaybackMode() [with T_SERIAL_METHOD = HardwareSerial; T_NOTIFICATION_METHOD = Mp3Notify]':
/home/fronbasal/Desktop/PlayMp3/PlayMp3.ino:81:39:   required from here
/home/fronbasal/Arduino/libraries/DFPlayer_Mini_Mp3_by_Makuna/src/DFMiniMp3.h:184:35: error: invalid conversion from 'uint16_t {aka short unsigned int}' to 'DfMp3_PlaybackMode' [-fpermissive]
         return listenForReply(0x45);
                                   ^
exit status 1
Error compiling for board NodeMCU 0.9 (ESP-12 Module).

Enum DfMp3_PlaySource should start at 1

enum DfMp3_PlaySource
{
    DfMp3_PlaySource_Usb,

should be:

enum DfMp3_PlaySource
{
    DfMp3_PlaySource_Usb = 1,

Please see specification.

Furthermore getCurrentTrack() has to take into account playsource set:

    uint16_t getCurrentTrack()
    {
        uint8_t command = 0x4c;
        
        switch (_playSource) {
          case DfMp3_PlaySource_Usb:
            command = 0x4b;
            break;
          case DfMp3_PlaySource_Sd:
            command = 0x4c;
            break;
          case DfMp3_PlaySource_Flash:
            command = 0x4d;
            break;
        }
      
        drainResponses();
        sendPacket(command);
        return listenForReply(command);
    }

Member _playSource

    DfMp3_PlaySource _playSource = DfMp3_PlaySource_Sd;

should be set in setPlaybackSource() like so:

    void setPlaybackSource(DfMp3_PlaySource source)
    {
        _playSource = source;
        sendPacket(0x09, source, 200);
    }

    DfMp3_PlaySource getPlaybackSource()
    {
        return _playSource;
    }

Detect DFPlayer brownout/crash

When a DFPlayer browns out either because of a too high volume or because of a too low supply current it goes nuts:
It starts to create a noise that sounds like a machine gun at full volume.
At the same time the player doesn't answer to serial requests anymore for some seconds. After that it resets, sends the 0x81 (129) error code and works fine again.

If the error code would be sent nearly immediately I could cut the dfplayers power supply / disable its amp (modified io pin).

getTotalFolderCount problem

Hi, i'm using a chinese mp3 module. This library work fine but i had a problem with this function 'getTotalFolderCount'...it is not reliable, in same cases returns values ​​other than the real ones. An example, i had 3 folders in root 01,02,03....function return 4 value, if i add a new folder in root, function return 5,ecc...also if i increment folder variable (for changing folder location), in same cases return a false value and notify com error. Is there a better solution for navigate in folders?

cppcheck Static Code analysis: "Medium" risk for not initializing _lastSend

Hi @Makuna, I'm using your lightweight library in one of my projects and just for fun ran a static code checker tool.
image
According to that, there is 1 medium risk item for not initializing _lastSend upon construction, fix would be easy:
Lines 396/397,

    uint32_t _lastSend{0};
    uint16_t _lastSendSpace{0};

If I had the rights on the repo, I'd create a branch and a PR myself.

There is another issue from that check that's more... ehm... individual style I believe. It is because the template class has a constructor that is not explicit. Well, that's up to your personal taste - just for completeness' sake.

correction in wiki "void playFolderTrack" section

In following lines playMp3FolderTrack(2, 13) should be replaced with playFolderTrack(2, 13).

void playFolderTrack(uint8_t folder, uint8_t track)
This will play the track from within the specific numbered folder.
An example filename would be sd:/002/013_ThisIsMyFavoriteSong.mp3, and calling playMp3FolderTrack(2, 13) would play it.

Fix/improve handling of 0x3F command/reply

listenForReply() should look like this (no "else if"):

                    case 0x3F:
                        if (replyArg & 0x02)
                        {
                            _isOnline = true;
                            T_NOTIFICATION_METHOD::OnCardOnline(replyArg);
                        }
                        if (replyArg & 0x01)
                        {
                            _isOnline = true;
                            T_NOTIFICATION_METHOD::OnUsbOnline(replyArg);
                        }
                        break;

E.g. YX5200-24SS sends 0x03 if both USB and SD are inserted. However, MH2024K-24SS sends 0x02 if both USB and SD are inserted.

Additionally some hardware replies on 0x3F request, thus proposing to add as an enhancement:

    // Does not work with all models.
    // YX5200-24SS - sends reply
    // MH2024K-24SS - sends NO reply --> results in error notification
    uint8_t queryStorageDevices()
    {
        drainResponses();
        sendPacket(0x3f);
        return listenForReply(0x3f);
    }

This comes in handy whenever both uC and DFPlayer are powered on in parallel. In these cases you mostly miss the announcement 0x3F messages because the uC needs longer too initialize.
Otherwise you can only reset the DFPlayer to collect the 0x3F messages causing some ugly click noises.

Improve getTotalTrackCount taking into account USB and SD

Introduce different methods for USB and SD:

    uint16_t getTotalTrackCountUsb()
    {
        drainResponses();
        sendPacket(0x47);
        uint16_t result = listenForReply(0x47);
        return result;
    }

    uint16_t getTotalTrackCountSd()
    {
        drainResponses();
        sendPacket(0x48);
        uint16_t result = listenForReply(0x48);
        return result;
    }

For backwards-compatibility implement getTotalTrackCount() based on PlaybackSource set invoking one or the other. Please also see #37.

What does void loop() do, what's its purpose?

Hi Makuna
Thank you for this library. Very helpful.
I'm unclear what the purpose of void loop() is. What do you mean "this will service the DFMiniMP3"?
It doesn't seem to matter that I didn't include it in my sketch. But I'm wondering if I need to?

cheers
Carl

Examples may show compiler error message when using Warnings set to ALL in IDE

The notification class implemented in the examples, often doesn't use the arguments in the methods and will generate a compiler error if the IDE has warnings set to ALL.

The examples should be updated to demonstrate an appropriate way to suppress these "warnings" for those who actually use the Warnings set to ALL.

While the latest compilers can use the [[maybe_unused]] like

  static void OnPlayFinished([[maybe_unused]] DfMp3& mp3, [[maybe_unused]] DfMp3_PlaySources source, uint16_t track)
  {
    Serial.print("Play finished for #");
    Serial.println(track);  
  }

this is only available on the latest compilers. The old school way of using (void)argument should work on older compilers also like

  static void OnPlayFinished(DfMp3& mp3, DfMp3_PlaySources source, uint16_t track)
  {
    (void)mp3; // unused
    (void)source; // unused
    Serial.print("Play finished for #");
    Serial.println(track);  
  }

Request: LoopFolder 0x17

Hi Makuna,
i'm using your nice libary for a children player. Now i've got the problem that the loop folder command (0x17 ) is not yet supported. Am I missing something or would it be possible to add this to the library.

Thank you

Greetings Iramoo

Com Error 3

Hello,
I am using a DFPlayer HM-247A (GD3200B) module and
when I run my sketch I have this error and I cannot get the total number of tracks, while playing a file is working fine .

Thanks for your help.

initializing...

Com Error 3
status : 0
nb de fichier : 0
nb de fichier dans le dossier 1 : 3

Nothing is read after nextTrack ()

Hello,
When I use the nextTrack() method, once the new MP3 is finished, nothing happens.
How do I get the next MP3 to play automatically?

thank you so much
Greg

HardwareSerial not working

The compiler output is "Serial1 was not declared in this scope". I don't see where Serial1 was instantiated. Have you gotten the hardware serial version to work?

Seems related to this Pass Serial by Reference

why i would like to get hardwareserial working: i have an issue with softwareserial and bluetooth with nrf52. I've posted my issue here. I'm hoping that the hardware serial will help with this. The issue is if i play a track 10 times in a row, then at random times the command seems to be ignored.

double invocation of OnPlayFinished()

First I thought there is something wrong when I discovered that the Method is called twice after my File teminated to play.
Then I read the documentation where it is clearly discribed that it can happen. I could have saved some time if I would have read it earlier. As always :-).
But now there is my question:
In the Callback method I start playing a new song and I increment a counter. As this method is called twice, the song is started twice. And my counter counts double.
Do you have any solution how one can find out if this is a Double invocation or not, so that I can return immediately?
Thank you.

"Card Online" instead of playing

Hi,

I have a problem with my module... When I play a file, instead of playing the file, I receive a notification "Card Online"... I tried many SD Cards and I read somewhere that it exists a firmware upgrade of the DFR0299, so I made it. Each time I make it before restarting the uC and putting a SDCard with sounds, it works. But if I unplug/replug the 5V, Impossible.

Do you have an idea ?
Thanks 😊

Error after looping a few times

running on ESP8166 using software serial

After a couple of repeat plays of the same track i get:
17:08:21.896 -> Com Error 255
17:08:29.527 ->
17:08:29.527 -> Play finished for #40
17:08:37.174 ->
17:08:37.174 -> Play finished for #40
17:08:44.823 ->
17:08:44.823 -> Play finished for #40

playback continues but it seems to get stuck in the notification class and doesn't keep the main loop running

DfMp3_Error_RxTimeout on any get method

I use arduino nano and try to get, for example, initial volume. The code is as follows:

SoftwareSerial secondarySerial(10, 11);
DFMiniMp3<SoftwareSerial, Mp3Notify> mp3(secondarySerial);

void setup() {
    Serial.begin(9600);
    Serial.println("Initializing...");
    mp3.begin();
    mp3.reset();
    Serial.println(String("Initial volume = ") + mp3.getVolume());
}

Output:

02:02:56:730 -> Initializing...
02:03:07:444 ->
Com Error 129
Initial volume = 0

The only mention of this error I've found is #19 where is said that it is likely wiring problem. I've made connections as shown by link in readme. I've tried different arduino pins for SoftwareSerial and different DFMP3 modules.

Reference:

reference

My wiring:

wiring1
wiring2

Request for comments: Remove SerialMethod Template?

Hey,
the template coding is kind of nice, however I feel like it's keeping me from properly injecting an instance of the DfMiniMp3 class into another class, since I'd have to carry around the same template just for the sake of it. I can't just do the following:

class PlaybackController {
  private:
     DfMiniMp3 & mp3player;
}

Since the usage of the Serial is mostly "begin", "timeout" and then the properties of "stream", what if instead of using the templated serial class, we re-write to accepting an instance of "Stream", which would then have to be pre-instantiated?

I see that this would be a breaking change, but still hope to hear your thoughts?

Pro:

  • easier passing of class references
  • less dependencies or required knowledge in the interface

con

  • additional step to setup the serial port
  • breaking change
template<class T_NOTIFICATION_METHOD> class DFMiniMp3
{
public:
    DFMiniMp3(Stream & serial) :
        _serial(serial),
        _lastSendSpace(c_msSendSpace),
        _isOnline(true)
    {

Please Add enableLoop and disableLoop

Hi, thanks for your great library, I used a number of additional features in my project, glad that these additions could go into the main repository.

// CUSTOM
    void enableLoop() {
	sendPacket(0x19, 0x00);
    }

    void disableLoop() {
	sendPacket(0x19, 0x01);
    }
// END CUSTOM

Thank you very much

SD Card Not Insterd + Power UP bug

I can't speak English

change sendPacket function

    void sendPacket(uint8_t command, uint16_t arg = 0, uint16_t sendSpaceNeeded = c_msSendSpace)
    {
        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 };

        setChecksum(out);

    Serial.print("_lastSend : ");
    Serial.print(_lastSend);
    Serial.print(", _lastSendSpace : ");
    Serial.print(_lastSendSpace);
    Serial.print(", end : ");
    Serial.print((millis() - _lastSend));
    Serial.print(", _isOnline : ");
    Serial.println(_isOnline);
        // wait for spacing since last send
        while (((millis() - _lastSend) < _lastSendSpace) || !_isOnline)
        {
            // check for event messages from the device while
            // we wait
            loop();
            delay(1);
    Serial.print("_lastSend : ");
    Serial.print(_lastSend);
    Serial.print(", _lastSendSpace : ");
    Serial.print(_lastSendSpace);
    Serial.print(", end : ");
    Serial.print((millis() - _lastSend));
    Serial.print(", _isOnline : ");
    Serial.println(_isOnline);
        }

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

        _lastSend = millis();
    }

log

Com Error 1 // 1. SD Card Not Insertd + PowerUP
Card inserted 2 // 2. SD Card Instert
//3. looped sendPacket
_lastSend : 925, _lastSendSpace : 600, end : 2503, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2504, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2509, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2514, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2520, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2526, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2532, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2537, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2543, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2549, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2555, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2560, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2566, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2572, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2577, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2583, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2589, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2595, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2600, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2606, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2612, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2618, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2623, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2629, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2635, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2640, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2646, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2652, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2658, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2663, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2669, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2675, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2681, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2686, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2692, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2698, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2703, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2709, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2715, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2721, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2726, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2732, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2738, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2744, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2749, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2755, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2761, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2767, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2772, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2778, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2784, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2789, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2795, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2801, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2807, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2812, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2818, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2824, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2830, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2835, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2841, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2847, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2852, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2858, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2864, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2870, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2875, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2881, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2887, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2893, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2898, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2904, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2910, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2915, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2921, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2927, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2933, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2938, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2944, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2950, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2956, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2961, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2967, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2973, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2978, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2984, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2990, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 2996, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3001, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3007, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3013, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3019, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3024, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3030, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3036, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3042, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3047, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3053, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3059, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3064, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3070, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3076, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3082, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3087, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3093, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3099, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3105, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3110, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3116, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3122, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3127, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3133, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3139, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3145, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3150, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3156, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3162, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3168, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3173, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3179, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3185, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3190, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3196, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3202, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3208, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3213, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3219, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3225, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3231, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3236, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3242, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3248, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3253, _isOnline : 0
_lastSend : 925, _lastSendSpace : 600, end : 3259, _isOnline : 0

example source

#include <DFMiniMp3.h>

int nMP3Index = 1;
bool isStoped = false;
bool isInsertSD = true;

long long nInsertedTime = 0;

class Mp3Notify
{
  public:
    static void OnError(uint16_t errorCode)
    {
      // see DfMp3_Error for code meaning
      Serial.println();
      Serial.print("Com Error ");
      Serial.println(errorCode);
      isInsertSD = false;
    }

    static void OnPlayFinished(uint16_t globalTrack)
    {
      Serial.println();
      Serial.print("Play finished for #");
      Serial.println(globalTrack);
      isStoped = true;
    }

    static void OnCardOnline(uint16_t code)
    {
      Serial.println();
      Serial.print("Card online ");
      Serial.println(code);
      isInsertSD = true;
      nInsertedTime = millis();
    }

    static void OnUsbOnline(uint16_t code)
    {
      Serial.println();
      Serial.print("USB Disk online ");
      Serial.println(code);
    }

    static void OnCardInserted(uint16_t code)
    {
      Serial.println();
      Serial.print("Card inserted ");
      Serial.println(code);
      isInsertSD = true;
      nInsertedTime = millis();
    }

    static void OnUsbInserted(uint16_t code)
    {
      Serial.println();
      Serial.print("USB Disk inserted ");
      Serial.println(code);
    }

    static void OnCardRemoved(uint16_t code)
    {
      Serial.println();
      Serial.print("Card removed ");
      Serial.println(code);
      isInsertSD = false;
    }

    static void OnUsbRemoved(uint16_t code)
    {
      Serial.println();
      Serial.print("USB Disk removed ");
      Serial.println(code);
    }
};

DFMiniMp3<HardwareSerial, Mp3Notify> mp3(Serial2);

void waitMilliseconds(uint16_t msWait)
{
  uint32_t start = millis();

  while ((millis() - start) < msWait)
  {
    mp3.loop();
    delay(1);
  }
}

void setup()
{
  Serial.begin(115200);
  Serial2.begin(9600, SERIAL_8N1, 16, 17);

  mp3.begin();
  mp3.reset();

  waitMilliseconds(100);

  if (!isInsertSD) {
    while (!isInsertSD) {
      waitMilliseconds(10);
    }

    mp3.reset();

    waitMilliseconds(10);
  }
  mp3.setVolume(5);
  
  uint16_t volume = mp3.getVolume();
  Serial.println(volume);
  Serial.println("getVolume END");


  uint16_t count = mp3.getTotalTrackCount();
  Serial.print("files ");
  Serial.println(count);
}

void loop()
{
  waitMilliseconds(1000);

  if (isInsertSD && (nInsertedTime != 0 || isStoped)) {
    Serial.print("MP3Index: ");
    Serial.println(nMP3Index);
    mp3.playMp3FolderTrack(nMP3Index++);
    isStoped = (isStoped) ? !isStoped : isStoped;
    nInsertedTime = 0;
    if (nMP3Index > 100)
      nMP3Index = 1;
  }
}

change listenForReply function

    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 0x3d: // micro sd
                    case 0x3c: // usb
                        T_NOTIFICATION_METHOD::OnPlayFinished(replyArg);
                        break;

                    case 0x3F:
                        if (replyArg & 0x02)
                        {
                            _isOnline = true;
                            T_NOTIFICATION_METHOD::OnCardOnline(replyArg);
                        }
                        else if (replyArg & 0x01)
                        {
                            _isOnline = true;
                            T_NOTIFICATION_METHOD::OnUsbOnline(replyArg);
                        }
                        break;

                    case 0x3A:
                        if (replyArg & 0x02)
                        {
                            _isOnline = true;
                            T_NOTIFICATION_METHOD::OnCardInserted(replyArg);
                        }
                        else if (replyArg & 0x01)
                        {
                            _isOnline = true;
                            T_NOTIFICATION_METHOD::OnUsbInserted(replyArg);
                        }
                        break;

                    case 0x3B:
                        if (replyArg & 0x02)
                        {
                            T_NOTIFICATION_METHOD::OnCardRemoved(replyArg);
                        }
                        else if (replyArg & 0x01)
                        {
                            T_NOTIFICATION_METHOD::OnUsbRemoved(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;
    }

How to play next song on OnPlayFinished?

I am wondering if there's a way to call next() or any other playback method from a notification callback. All methods of T_NOTIFICATION_METHOD are declared static and can't access outside state.
The only way I could imagine is to change the API so that each of the static callbacks gets a reference passed. Some kind of context it could use to trigger additional logic.

Am I missing currently available possibilities with the API?

Thanks.

Suggestion: Add Mp3Notify.h to source

The Mp3Notify class from the examples is likely used by most as is. Suggest adding it to the source as Mp3Notify.h to provide a default implementation "out of the box".

Updated example reports error

When I verified your recently updated example * on my UNO I got the error
'Serial1' was not declared in this scope. Presumably a very basic error on my part, as I have little C/C++ know how. Can you advise please?

'''

  • It's the 128 line sketch, starting with

// this example will play a track and then
// every five seconds play another track

and ending with

void loop()
{
waitMilliseconds(100);
}
'''

Suggestion: Add serial speed as parameter to .begin()

Hey @Makuna do you think its possible to make the serial speed a parameter to .begin()? I know the chip is fixed to 9600 but for debugging purposes and to support other chips with different speed but similar interface it would be helpful. Currently the speed change needs to be done directly in DFMiniMp3.h but doing mp3.begin(2400); or whatever would be nice.

I forgot to mention, it would be nice if it were optional with 9600 as default. So it would not break existing sketches.

The example sketches need SoftwareSerial-usage hints

The examples currently fail to compile for an Arduino Uno due to it only having one hardware serial port, leading to this error:

'Serial1' was not declared in this scope

I recommend replacing the line referencing "Serial1" in the examples with the following set of lines:

DFMiniMp3<HardwareSerial, Mp3Notify> mp3(Serial1); // If this line fails to compile, try replacing it the two with the two lines below. This comes up because some arduino boards only have one hardware serial port, so a software serial port is needed instead.
//SoftwareSerial secondarySerial(10, 11); // RX, TX
//DFMiniMp3<SoftwareSerial, Mp3Notify> mp3(secondarySerial);

get current track filename ?

Hi,

Thanks a lot for this usefull library !

Is it possible to get the track playing file name (and then extract the text in the filename to get "myMusic" from filename 0001_myMusic.mp3 ) ?

Could be very cool

Controlling two DFMiniMp3 Boards?

Hi,
is it possible to control two boards with one Arduino with this library?
I tried this with the original library of the DF Boards, but it doesn't work :-(
Robert

make DFMiniMp3 compilable in platformio (change private and public order)

Hi @Makuna ,

I have an hopefully easy request to you regarding your great library.

Can you please change the order of the public and private declarations.
It would make the Library compilable in straight forward compilers.

in the current setup the compiler complaints that it does not know the private variables when being used in the public area - Since they are declared further down...

most c compilers (I'm using platform) are dumb like this to enable fast processing.

SOLUTION:
if you would first declare your private section and later declare the public stuff, it would know the private components.
(I've already tested it in my project.)

With this solution all developers could easily use your library with any compiler.

Thanks in advance
Jens

Play from spiffs?

Can i play mp3 in spiffs file, because i dont need micro sd just for 200 kb data

How repeat current track?

Hi :-)
Please, can you show us how to write, in an Arduino sketch, the right code to repeat current track?
I'm not a programmer and don't understand the line from DFMiniMp3.h void setRepeatPlayCurrentTrack(bool repeat)

Thanks

Massimo

( DFPLayer with chip MH2024K-16SS )

Endless loop in listenForReply

When I call mp3Player.getFolderTrackCount(folder); for a folder value which is not valid. I get a response on T_NOTIFICATION_METHOD::OnError(replyArg); which is good but then the programm loops endless in the function uint16_t listenForReply(uint8_t command) because there is a condition } while (command != 0); which never can changes because the variable command never gets changed and is not 0 from the beginning.

Without properly knowing it I first thought it should be } while (replyCommand != 0);. It also eventually terminates but takes quite long until replyCommand becomes 0.

Does it make sense to directly exit in case on any notification?

Wake up after sleep with setPlaybackSource

Not exactly an issue but I've read your note in the wiki that says the only way you know how to wake up is using reset()

Note: currently the only way to wake up the module that I know of is with reset(); but this is a slow process and may cause click noises in the audio output.

I learned from this library that you can initiate a wake up by setting the play source to SD. In our case it can be done by calling:

setPlaybackSource(DfMp3_PlaySource_Sd);

I tried it and it worked. It seems to reset the player but it's quick and does not have a click noise that you noted.

Not sure if this is the best approach but it worked for me. Just thought you should know.

faulty package at platform IO

I installed the library via PlatformIO (https://registry.platformio.org/libraries/makuna/DFPlayer%20Mini%20Mp3%20by%20Makuna, using makuna/DFPlayer Mini Mp3 by Makuna@^1.2.0) and had to realize that it's not the current version of the code. I found it from the fact that the function void begin(int8_t rxPin, int8_t txPin, unsigned long baud = 9600) was missing.

I don't know how you do the deployment to there, but maybe you should double check.
For now I use the source from the github release (in that tar.gz it's still correct) in the projects lib folder.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.