Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: Makuna/DFMiniMp3
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 1.0.7
Choose a base ref
...
head repository: Makuna/DFMiniMp3
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref

Commits on Dec 29, 2020

  1. Notify improvements (#60)

    * Notify Passed a class reference
    
    * new version
    Makuna authored Dec 29, 2020

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    e52ad95 View commit details

Commits on Jan 21, 2021

  1. fix static code checker issue as per #63 item B). (#64)

    Leave A) as is to save progmem.
    Schallbert authored Jan 21, 2021

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    81692ad View commit details

Commits on Aug 30, 2021

  1. Add support for DFPlayer modules using a MH2024K-16SS chip (#77)

    * Autoformat code
    
    * Refactor DfMp3_Packet from enum to struct
    
    * Add option to send a packet without checksum
    
    * Play finished event on MH2024K-16SS is code 0x4c
    
    * Reformat using another formatter (in vscode => vcFormat)
    
    * Replace C-style casts to their C++ equivalent
    
    * On MH2024K-16SS, the end of song USB, is 0x4b instead of 0x3c...
    
    * Use a pointer instead of a ref to make it explicit that the packet is changed
    
    * Refactor calcChecksum to use a for-loop to reduce program size (48 bytes => 36 bytes)
    
    * Use templating to reduce code and memory size
    
    * Do not init buffer to save program size.
    
    * Remove DfMp3_Packet and declare types in Chip classes
    
    * Rename field SendCheckSum
    
    * Renamed i variable with a more meaningful name (packetByte)
    
    * fix warnings
    
    * Move the generation of the packet to the Mp3Chip classes
    
    * Add missing const
    
    Co-authored-by: Maxime Chéramy <maxime@cheramy.org>
    MaximeCheramy and Maxime Chéramy authored Aug 30, 2021

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    d603f8e View commit details

Commits on Apr 9, 2022

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    b50c3bb View commit details
  2. Update Examples (#85)

    Demonstrate how to mark arguments that maybe unused
    Makuna authored Apr 9, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    145caa5 View commit details

Commits on Apr 11, 2022

  1. Refactor checksum methods (#88)

    solve the issue of multiple instances of these methods when included in several files.
    Makuna authored Apr 11, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    b63399f View commit details

Commits on Apr 13, 2022

  1. include awake command (#91)

    Makuna authored Apr 13, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    9838e6d View commit details

Commits on May 12, 2022

  1. Update README.md (#93)

    Makuna authored May 12, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    48d6ad6 View commit details

Commits on Jul 7, 2022

  1. library json (#96)

    Makuna authored Jul 7, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    c2a0435 View commit details

Commits on Oct 26, 2022

  1. Update PlayMp3.ino (#98)

    Now plays the track sequentially in a loop
    Makuna authored Oct 26, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    50e3581 View commit details

Commits on Feb 6, 2023

  1. correct casting (#105)

    Makuna authored Feb 6, 2023

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    ed18859 View commit details

Commits on Feb 8, 2023

  1. Debug Helpers (#106)

    Makuna authored Feb 8, 2023

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    32e2d89 View commit details

Commits on Feb 10, 2023

  1. inc version (#107)

    Makuna authored Feb 10, 2023

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    c8784ba View commit details

Commits on Mar 11, 2023

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    13baf94 View commit details

Commits on Mar 23, 2023

  1. Ack no wait (#112)

    * Remove Delays
    * Added com retries
    * Ack request for no response commands
    * keywords and version
    Makuna authored Mar 23, 2023

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    ab8cd57 View commit details

Commits on Mar 26, 2023

  1. Ack cleanup (#114)

    * Magic Numbers
    
    * reoganize
    
    * notifications queued
    
    * Added software version query
    
    * Added constructor that takes RX/TX pins for ESP32 and others
    
    * GetPlaySources deprecated due to conflict between data return and known Reply notification (they are the same with no context)
    
    * reset() will now wait until chip replies with online by default
    Makuna authored Mar 26, 2023

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    c1f9275 View commit details

Commits on Mar 28, 2023

  1. Debug cleanup (#116)

    * corrections
    
    * file reorg
    
    * comment cleanup
    Makuna authored Mar 28, 2023

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    71bb8f2 View commit details

Commits on May 11, 2023

  1. Improvements (#124)

    * no output on construction
    
    * Fix getFolderTrackCount
    Makuna authored May 11, 2023

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    107456d View commit details

Commits on May 12, 2023

  1. example comments (#125)

    Makuna authored May 12, 2023

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    841da44 View commit details

Commits on May 14, 2023

  1. stop spam (#126)

    spam messages for looping track complete can lock the message listening
    Makuna authored May 14, 2023

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    8e2eb04 View commit details

Commits on Jun 6, 2023

  1. Mp3 chip incongruous no ack (#130)

    * No Ack Chip model
    
    * update keywords
    Makuna authored Jun 6, 2023

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    2b866f9 View commit details

Commits on Aug 18, 2023

  1. cleanup (#136)

    Makuna authored Aug 18, 2023

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    1625086 View commit details

Commits on Aug 20, 2023

  1. Inc Version (#137)

    Makuna authored Aug 20, 2023

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    0711738 View commit details

Commits on Oct 12, 2023

  1. Ack no ack (#143)

    * initial timeout fixes
    
    * loop doesn't care about timeout
    Makuna authored Oct 12, 2023

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    841e2d1 View commit details
  2. 1.2.2 (#144)

    Makuna authored Oct 12, 2023

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    c6f4ee7 View commit details

Commits on Nov 12, 2023

  1. C_ACK_TIMEOUT (#151)

    Makuna authored Nov 12, 2023

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    5eed63f View commit details

Commits on Nov 20, 2023

  1. inc version (#152)

    Makuna authored Nov 20, 2023

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    9e0720c View commit details

Commits on Feb 6, 2024

  1. Notification class (#159)

    Notification class is optional
    Notification class members can be non-static
    Examples updated to demonstrate different ways to use the new model
    Makuna authored Feb 6, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    bd27c22 View commit details
11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
# DFPlayer Mini mp3

[![Join the chat at https://gitter.im/DFMiniMp3/Lobby](https://badges.gitter.im/DFMiniMp3/Lobby.svg)](https://gitter.im/DFMiniMp3/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)

[![Donate](https://img.shields.io/badge/paypal-donate-yellow.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=6AA97KE54UJR4)

Library for the DFPlayer Mini Mp3 module
Arduino DFPlayer Mini Mp3 module library

This library allows your Arduino project to control the DFPlayer Mini MP3 module. It supports both hardware serial and software serial. It was designed to fit in the smallest Arduino hardware by consuming less code and memory space than other libraries.

Please read the product link before connecting your module, it will save you alot of time and effort.
[DFRobot's DFPlayer Mini Mp3](http://www.dfrobot.com/wiki/index.php/DFPlayer_Mini_SKU:DFR0299)

For quick questions and support:
* [Try the new Github Discussions](https://github.com/Makuna/DFMiniMp3/discussions)
* Or jump on Gitter
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/DFMiniMp3/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)

For bugs, make sure there isn't an active issue and then create one.

## Documentation
[See Wiki](https://github.com/Makuna/DFMiniMp3/wiki)

131 changes: 83 additions & 48 deletions examples/PlayAdvertisements/PlayAdvertisements.ino
Original file line number Diff line number Diff line change
@@ -7,66 +7,88 @@
// sd:/01/001.mp3 - the song to play, the longer the better
// sd:/advert/0001.mp3 - the advertisement to interrupt the song, keep it short

#include <SoftwareSerial.h>
#include <DFMiniMp3.h>

// implement a notification class,
// implement a static notification class,
// its member methods will get called
//
class Mp3Notify
{
public:
static void PrintlnSourceAction(DfMp3_PlaySources source, const char* action)
{
if (source & DfMp3_PlaySources_Sd)
// required type
typedef void TargetType;

// required method even though it doesn't do anything
static void SetTarget(TargetType*)
{
Serial.print("SD Card, ");
}
if (source & DfMp3_PlaySources_Usb)

static void PrintlnSourceAction(DfMp3_PlaySources source, const char* action)
{
Serial.print("USB Disk, ");
if (source & DfMp3_PlaySources_Sd)
{
Serial.print("SD Card, ");
}
if (source & DfMp3_PlaySources_Usb)
{
Serial.print("USB Disk, ");
}
if (source & DfMp3_PlaySources_Flash)
{
Serial.print("Flash, ");
}
Serial.println(action);
}
if (source & DfMp3_PlaySources_Flash)

// required method
static void OnError(uint16_t errorCode)
{
Serial.print("Flash, ");
// see DfMp3_Error for code meaning
Serial.println();
Serial.print("Com Error ");
Serial.println(errorCode);
}

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

// required method
static void OnPlaySourceOnline(DfMp3_PlaySources source)
{
PrintlnSourceAction(source, "online");
}

// required method
static void OnPlaySourceInserted(DfMp3_PlaySources source)
{
PrintlnSourceAction(source, "inserted");
}

// required method
static void OnPlaySourceRemoved(DfMp3_PlaySources source)
{
PrintlnSourceAction(source, "removed");
}
Serial.println(action);
}
static void OnError(uint16_t errorCode)
{
// see DfMp3_Error for code meaning
Serial.println();
Serial.print("Com Error ");
Serial.println(errorCode);
}
static void OnPlayFinished(DfMp3_PlaySources source, uint16_t track)
{
Serial.print("Play finished for #");
Serial.println(track);
}
static void OnPlaySourceOnline(DfMp3_PlaySources source)
{
PrintlnSourceAction(source, "online");
}
static void OnPlaySourceInserted(DfMp3_PlaySources source)
{
PrintlnSourceAction(source, "inserted");
}
static void OnPlaySourceRemoved(DfMp3_PlaySources source)
{
PrintlnSourceAction(source, "removed");
}
};

// instance a DFMiniMp3 object,
// defined with the above notification class and the hardware serial class
// define a handy type using serial and our notify class
//
typedef DFMiniMp3<HardwareSerial, Mp3Notify> DfMp3;

// instance a DfMp3 object,
//
DFMiniMp3<HardwareSerial, Mp3Notify> mp3(Serial1);
DfMp3 dfmp3(Serial1);

// Some arduino boards only have one hardware serial port, so a software serial port is needed instead.
// comment out the above definition and uncomment these lines
// comment out the above definitions and use these
//SoftwareSerial secondarySerial(10, 11); // RX, TX
//DFMiniMp3<SoftwareSerial, Mp3Notify> mp3(secondarySerial);
//typedef DFMiniMp3<SoftwareSerial, Mp3Notify> DfMp3;
// DfMp3 dfmp3(secondarySerial);


uint32_t lastAdvert; // track time for last advertisement

@@ -76,17 +98,30 @@ void setup()

Serial.println("initializing...");

mp3.begin();
uint16_t volume = mp3.getVolume();
dfmp3.begin();
// for boards that support hardware arbitrary pins
// dfmp3.begin(10, 11); // RX, TX

// during development, it's a good practice to put the module
// into a known state by calling reset().
// You may hear popping when starting and you can remove this
// call to reset() once your project is finalized
dfmp3.reset();

uint16_t version = dfmp3.getSoftwareVersion();
Serial.print("version ");
Serial.println(version);

uint16_t volume = dfmp3.getVolume();
Serial.print("volume was ");
Serial.println(volume);
mp3.setVolume(24);
volume = mp3.getVolume();
dfmp3.setVolume(24);
volume = dfmp3.getVolume();
Serial.print(" and changed to ");
Serial.println(volume);

Serial.println("track 1 from folder 1");
mp3.playFolderTrack(1, 1); // sd:/01/001.mp3
dfmp3.playFolderTrack(1, 1); // sd:/01/001.mp3

lastAdvert = millis();
}
@@ -98,8 +133,8 @@ void loop()
{
// interrupt the song and play the advertisement, it will
// return to the song when its done playing automatically
mp3.playAdvertisement(1); // sd:/advert/0001.mp3
dfmp3.playAdvertisement(1); // sd:/advert/0001.mp3
lastAdvert = now;
}
mp3.loop();
dfmp3.loop();
}
235 changes: 147 additions & 88 deletions examples/PlayMp3/PlayMp3.ino
Original file line number Diff line number Diff line change
@@ -8,114 +8,173 @@
// sd:/mp3/0002.mp3
// sd:/mp3/0003.mp3

#include <SoftwareSerial.h>
#include <DFMiniMp3.h>

// implement a notification class,
// its member methods will get called
// forward declare the sketches managing class, just the name
//
class Mp3Notify
class Mp3Manager;

// define a handy type using hardware serial and our notify class wrapper
//
typedef DFMiniMp3<HardwareSerial, DfMp3Callback<Mp3Manager>> DfMp3;

// Some arduino boards only have one hardware serial port,
// so a software serial port is needed instead.
// use this instead to define the DFMiniMp3
//SoftwareSerial secondarySerial(10, 11); // RX, TX
//typedef DFMiniMp3<SoftwareSerial, DfMp3Callback<Mp3Manager>> DfMp3;

// implement the sketches managing class,
// this is the authors class doing what funtionality the author wants
// it must implement the methods as defined below and these member
// methods will get called by the Mp3 class for ayncrounous notifications
//
class Mp3Manager
{
public:
static void PrintlnSourceAction(DfMp3_PlaySources source, const char* action)
{
if (source & DfMp3_PlaySources_Sd)
Mp3Manager() :
_dfmp3(Serial1, this) // NOTE: passing this object as the notification target
// _dfmp3(secondarySerial, this); // for software serial
{
Serial.print("SD Card, ");
}
if (source & DfMp3_PlaySources_Usb)

~Mp3Manager()
{
Serial.print("USB Disk, ");
}
if (source & DfMp3_PlaySources_Flash)

// not required but common practice
// as _dfmp3.begin() must get called
//
void begin()
{
_dfmp3.begin();
// for boards that support hardware arbitrary pins
// _dfmp3.begin(10, 11); // RX, TX

// during development, it's a good practice to put the module
// into a known state by calling reset().
// You may hear popping when starting and you can remove this
// call to reset() once your project is finalized
_dfmp3.reset();

// some example things you might want to do
uint16_t version = _dfmp3.getSoftwareVersion();
Serial.print("version ");
Serial.println(version);

uint16_t volume = _dfmp3.getVolume();
Serial.print("volume ");
Serial.println(volume);
_dfmp3.setVolume(24);

uint16_t count = _dfmp3.getTotalTrackCount(DfMp3_PlaySource_Sd);
Serial.print("files ");
Serial.println(count);

Serial.println("starting...");

// start the first track playing
_dfmp3.playMp3FolderTrack(1); // sd:/mp3/0001.mp3
}

// not required but common practice
// as _dfmp3.loop() must get called
//
void loop()
{
Serial.print("Flash, ");
_dfmp3.loop();
}
Serial.println(action);
}
static void OnError(uint16_t errorCode)
{
// see DfMp3_Error for code meaning
Serial.println();
Serial.print("Com Error ");
Serial.println(errorCode);
}
static void OnPlayFinished(DfMp3_PlaySources source, uint16_t track)
{
Serial.print("Play finished for #");
Serial.println(track);
}
static void OnPlaySourceOnline(DfMp3_PlaySources source)
{
PrintlnSourceAction(source, "online");
}
static void OnPlaySourceInserted(DfMp3_PlaySources source)
{
PrintlnSourceAction(source, "inserted");
}
static void OnPlaySourceRemoved(DfMp3_PlaySources source)
{
PrintlnSourceAction(source, "removed");
}
};

// instance a DFMiniMp3 object,
// defined with the above notification class and the hardware serial class
//
DFMiniMp3<HardwareSerial, Mp3Notify> mp3(Serial1);
// required method
void OnError(uint16_t errorCode)
{
// see DfMp3_Error for code meaning
Serial.println();
Serial.print("Com Error ");
Serial.println(errorCode);
}

// Some arduino boards only have one hardware serial port, so a software serial port is needed instead.
// comment out the above definition and uncomment these lines
//SoftwareSerial secondarySerial(10, 11); // RX, TX
//DFMiniMp3<SoftwareSerial, Mp3Notify> mp3(secondarySerial);
// required method
void OnPlayFinished([[maybe_unused]] DfMp3_PlaySources source, uint16_t track)
{
Serial.print("Play finished for #");
Serial.println(track);

// start next track
track += 1;
// this example will just start back over with 1 after track 3
if (track > 3)
{
track = 1;
}
_dfmp3.playMp3FolderTrack(track); // sd:/mp3/0001.mp3, sd:/mp3/0002.mp3, sd:/mp3/0003.mp3
}

// required method
void OnPlaySourceOnline(DfMp3_PlaySources source)
{
PrintlnSourceAction(source, "online");
}

// required method
void OnPlaySourceInserted(DfMp3_PlaySources source)
{
PrintlnSourceAction(source, "inserted");
}

// required method
void OnPlaySourceRemoved(DfMp3_PlaySources source)
{
PrintlnSourceAction(source, "removed");
}

protected:
// sketch specific example member, not required
void PrintlnSourceAction(DfMp3_PlaySources source, const char* action)
{
if (source & DfMp3_PlaySources_Sd)
{
Serial.print("SD Card, ");
}
if (source & DfMp3_PlaySources_Usb)
{
Serial.print("USB Disk, ");
}
if (source & DfMp3_PlaySources_Flash)
{
Serial.print("Flash, ");
}
Serial.println(action);
}

DfMp3 _dfmp3;
};

void setup()
Mp3Manager mp3; // instance your class per your design

void setup()
{
Serial.begin(115200);

Serial.println("initializing...");

mp3.begin();

uint16_t volume = mp3.getVolume();
Serial.print("volume ");
Serial.println(volume);
mp3.setVolume(24);

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

Serial.println("starting...");
Serial.begin(115200);
Serial.println("initializing...");

mp3.begin();
}

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

while ((millis() - start) < msWait)
{
// calling mp3.loop() periodically allows for notifications
// to be handled without interrupts
mp3.loop();
delay(1);
}
uint32_t start = millis();

while ((millis() - start) < msWait)
{
// if you have loops with delays, its important to
// call dfmp3.loop() periodically so it allows for notifications
// to be handled without interrupts
mp3.loop();
delay(1);
}
}

void loop()
void loop()
{
Serial.println("track 1");
mp3.playMp3FolderTrack(1); // sd:/mp3/0001.mp3

waitMilliseconds(5000);

Serial.println("track 2");
mp3.playMp3FolderTrack(2); // sd:/mp3/0002.mp3

waitMilliseconds(5000);

Serial.println("track 3");
mp3.playMp3FolderTrack(3); // sd:/mp3/0002.mp3

waitMilliseconds(5000);
waitMilliseconds(100);
}
89 changes: 27 additions & 62 deletions examples/PlayRandom/PlayRandom.ino
Original file line number Diff line number Diff line change
@@ -2,99 +2,64 @@
//
// it expects the sd card to contain some mp3 files

#include <SoftwareSerial.h>
#include <DFMiniMp3.h>

// implement a notification class,
// its member methods will get called
// define a handy type using hardware serial with no notifications
//
class Mp3Notify
{
public:
static void PrintlnSourceAction(DfMp3_PlaySources source, const char* action)
{
if (source & DfMp3_PlaySources_Sd)
{
Serial.print("SD Card, ");
}
if (source & DfMp3_PlaySources_Usb)
{
Serial.print("USB Disk, ");
}
if (source & DfMp3_PlaySources_Flash)
{
Serial.print("Flash, ");
}
Serial.println(action);
}
static void OnError(uint16_t errorCode)
{
// see DfMp3_Error for code meaning
Serial.println();
Serial.print("Com Error ");
Serial.println(errorCode);
}
static void OnPlayFinished(DfMp3_PlaySources source, uint16_t track)
{
Serial.print("Play finished for #");
Serial.println(track);
}
static void OnPlaySourceOnline(DfMp3_PlaySources source)
{
PrintlnSourceAction(source, "online");
}
static void OnPlaySourceInserted(DfMp3_PlaySources source)
{
PrintlnSourceAction(source, "inserted");
}
static void OnPlaySourceRemoved(DfMp3_PlaySources source)
{
PrintlnSourceAction(source, "removed");
}
};
typedef DFMiniMp3<HardwareSerial> DfMp3;

// instance a DFMiniMp3 object,
// defined with the above notification class and the hardware serial class
// instance a DfMp3 object,
//
DFMiniMp3<HardwareSerial, Mp3Notify> mp3(Serial1);
DfMp3 dfmp3(Serial1);

// Some arduino boards only have one hardware serial port, so a software serial port is needed instead.
// comment out the above definition and uncomment these lines
// comment out the above definitions and use these
//SoftwareSerial secondarySerial(10, 11); // RX, TX
//DFMiniMp3<SoftwareSerial, Mp3Notify> mp3(secondarySerial);
//typedef DFMiniMp3<SoftwareSerial> DfMp3;
// DfMp3 dfmp3(secondarySerial);

void setup()
{

Serial.begin(115200);

Serial.println("initializing...");

mp3.begin();
mp3.reset();
dfmp3.begin();
// for boards that support hardware arbitrary pins
// dfmp3.begin(10, 11); // RX, TX

// during development, it's a good practice to put the module
// into a known state by calling reset().
// You may hear popping when starting and you can remove this
// call to reset() once your project is finalized
dfmp3.reset();

uint16_t version = dfmp3.getSoftwareVersion();
Serial.print("version ");
Serial.println(version);

// show some properties and set the volume
uint16_t volume = mp3.getVolume();
uint16_t volume = dfmp3.getVolume();
Serial.print("volume ");
Serial.println(volume);
mp3.setVolume(24);
dfmp3.setVolume(24);

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

uint16_t mode = mp3.getPlaybackMode();
uint16_t mode = dfmp3.getPlaybackMode();
Serial.print("playback mode ");
Serial.println(mode);

Serial.println("starting...");

mp3.playRandomTrackFromAll(); // random of all folders on sd
dfmp3.playRandomTrackFromAll(); // random of all folders on sd
}

void loop()
{
// calling mp3.loop() periodically allows for notifications
// calling dfmp3.loop() periodically allows for notifications
// to be handled without interrupts
mp3.loop();
dfmp3.loop();
}
238 changes: 238 additions & 0 deletions extras/Mp3_Ack_API_Test/Mp3_Ack_API_Test.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@


#define MP3_RX_PIN 15
#define MP3_TX_PIN 2

//#include <SoftwareSerial.h>
//SoftwareSerial Mp3Serial(MP3_RX_PIN, MP3_TX_PIN); // RX, TX
//#define Mp3SerialType SoftwareSerial

#define Mp3SerialType HardwareSerial
#define Mp3Serial Serial1

#define DebugOut Serial
#define DfMiniMp3Debug DebugOut

#include <DFMiniMp3.h>

// forward declare the notify class, just the name
//
class Mp3Notify;

// define a handy type using serial and our notify class
//
typedef DFMiniMp3<Mp3SerialType, Mp3Notify> DfMp3;

class Mp3Notify
{
public:
static void PrintlnSourceAction(DfMp3_PlaySources source, const char* action)
{
if (source & DfMp3_PlaySources_Sd)
{
DebugOut.print("SD Card, ");
}
if (source & DfMp3_PlaySources_Usb)
{
DebugOut.print("USB Disk, ");
}
if (source & DfMp3_PlaySources_Flash)
{
DebugOut.print("Flash, ");
}
DebugOut.println(action);
}
static void OnError([[maybe_unused]] DfMp3& mp3, uint16_t errorCode)
{
// see DfMp3_Error for code meaning
DebugOut.println();
DebugOut.print("Com Error ");
DebugOut.println(errorCode);
}
static void OnPlayFinished([[maybe_unused]] DfMp3& mp3, [[maybe_unused]] DfMp3_PlaySources source, uint16_t track)
{
DebugOut.print("Play finished for #");
DebugOut.println(track);
}
static void OnPlaySourceOnline([[maybe_unused]] DfMp3& mp3, DfMp3_PlaySources source)
{
PrintlnSourceAction(source, "online");
}
static void OnPlaySourceInserted([[maybe_unused]] DfMp3& mp3, DfMp3_PlaySources source)
{
PrintlnSourceAction(source, "inserted");
}
static void OnPlaySourceRemoved([[maybe_unused]] DfMp3& mp3, DfMp3_PlaySources source)
{
PrintlnSourceAction(source, "removed");
}
};


DfMp3 mp3(Mp3Serial);

uint32_t setupStart;

void setup()
{
DebugOut.begin(115200);

//mp3.begin(); // when you can't set the pins OR software serial is used
mp3.begin(MP3_RX_PIN, MP3_TX_PIN); // rx, tx

// use hardware serial Serial for MP3 playback on ESP8266
// move serial to GPIO15(TX) and GPIO13 (RX) for
// the mp3 module, we loose the debug monitor though
//Serial.swap();

// mp3.awake();
mp3.reset();


DebugOut.println("initializing...");


setupStart = millis();
}

const uint16_t c_playDelay = 1000;

void loop()
{
mp3.loop();
DebugOut.println("starting...");


uint16_t version = mp3.getSoftwareVersion();
DebugOut.print("version ");
DebugOut.println(version, HEX);

DebugOut.println("playGlobalTrack 6");
mp3.playGlobalTrack(6);
delay(c_playDelay);

DebugOut.println("playMp3FolderTrack 2");
mp3.playMp3FolderTrack(2);
delay(c_playDelay);

DebugOut.println("playFolderTrack 20, 2");
mp3.playFolderTrack(20, 2);
delay(c_playDelay);

DebugOut.println("playFolderTrack16 10, 2000");
mp3.playFolderTrack16(10, 2000);
delay(c_playDelay);

DebugOut.println("playRandomTrackFromAll");
mp3.playRandomTrackFromAll();
delay(c_playDelay);

DebugOut.println("nextTrack");
mp3.nextTrack();
delay(c_playDelay);

DebugOut.println("prevTrack");
mp3.prevTrack();
delay(c_playDelay);

uint16_t track = mp3.getCurrentTrack();
DebugOut.print("current track ");
DebugOut.println(track);

DebugOut.println("setVolume 16");
mp3.setVolume(16);

uint16_t volume = mp3.getVolume();
DebugOut.print("volume ");
DebugOut.println(volume);

DebugOut.println("increaseVolume");
mp3.increaseVolume();

DebugOut.println("decreaseVolume");
mp3.decreaseVolume();

DebugOut.println("loopGlobalTrack 6");
mp3.loopGlobalTrack(6);
delay(c_playDelay);

DebugOut.println("loopFolder 20");
mp3.loopFolder(20);
delay(c_playDelay);

DebugOut.println("setPlaybackMode 2 (single repeat)");
mp3.setPlaybackMode(DfMp3_PlaybackMode_SingleRepeat);

DfMp3_PlaybackMode mode = mp3.getPlaybackMode();
DebugOut.print("playback mode ");
DebugOut.println(mode);

DebugOut.println("setRepeatPlayAllInRoot false");
mp3.setRepeatPlayAllInRoot(false);
delay(c_playDelay);

DebugOut.println("setRepeatPlayCurrentTrack true");
mp3.setRepeatPlayCurrentTrack(true);
delay(c_playDelay);

DebugOut.println("setEq 3 (jazz)");
mp3.setEq(DfMp3_Eq_Jazz);

DfMp3_Eq eqMode = mp3.getEq();
DebugOut.print("eq mode ");
DebugOut.println(eqMode);

DebugOut.println("setPlaybackSource 2 (SD)");
mp3.setPlaybackSource(DfMp3_PlaySource_Sd);
delay(c_playDelay);

DebugOut.println("start");
mp3.start();
delay(c_playDelay);

DebugOut.println("pause");
mp3.pause();
delay(c_playDelay);

DebugOut.println("stop");
mp3.stop();
delay(c_playDelay);

DfMp3_Status status = mp3.getStatus();
DebugOut.print("status source is ");
DebugOut.print(status.source);
DebugOut.print(" and state is ");
DebugOut.println(status.state);

uint16_t count = mp3.getFolderTrackCount(10);
DebugOut.print("folder 10 files ");
DebugOut.println(count);

count = mp3.getTotalTrackCount();
DebugOut.print("total files ");
DebugOut.println(count);

count = mp3.getTotalFolderCount();
DebugOut.print("total folders ");
DebugOut.println(count);

DebugOut.println("playAdvertisement 2");
mp3.playAdvertisement(2);
delay(c_playDelay);

DebugOut.println("stopAdvertisement");
mp3.stopAdvertisement();
delay(c_playDelay);

DebugOut.println("enableDac");
mp3.enableDac();

DebugOut.println("disableDac");
mp3.disableDac();

mp3.loop();
DebugOut.println("...stopping");
DebugOut.println();
mp3.loop();
delay(2000);
}
32 changes: 32 additions & 0 deletions keywords.txt
Original file line number Diff line number Diff line change
@@ -7,17 +7,25 @@
#######################################

DFMiniMp3 KEYWORD1
DfMp3_Status KEYWORD1
DfMp3_Error KEYWORD1
DfMp3_PlaybackMode KEYWORD1
DfMp3_Eq KEYWORD1
DfMp3_PlaySource KEYWORD1
DfMp3_PlaySources KEYWORD1
DfMp3_StatusState KEYWORD1
DfMp3_StatusSource KEYWORD1
Mp3ChipOriginal KEYWORD1
Mp3ChipMH2024K16SS KEYWORD1
Mp3ChipIncongruousNoAck KEYWORD1

#######################################
# Methods and Functions (KEYWORD2)
#######################################

begin KEYWORD2
loop KEYWORD2
setComRetries KEYWORD2
getPlaySources KEYWORD2
playGlobalTrack KEYWORD2
playMp3FolderTrack KEYWORD2
@@ -40,6 +48,7 @@ setEq KEYWORD2
getEq KEYWORD2
setPlaybackSource KEYWORD2
sleep KEYWORD2
awake KEYWORD2
reset KEYWORD2
start KEYWORD2
pause KEYWORD2
@@ -77,3 +86,26 @@ DfMp3_PlaySources_Usb LITERAL1
DfMp3_PlaySources_Sd LITERAL1
DfMp3_PlaySources_Pc LITERAL1
DfMp3_PlaySources_Flash LITERAL1
DfMp3_StatusState_Idle LITERAL1
DfMp3_StatusState_Playing LITERAL1
DfMp3_StatusState_Paused LITERAL1
DfMp3_StatusState_Sleep LITERAL1
DfMp3_StatusState_Shuffling LITERAL1
DfMp3_StatusSource_General LITERAL1
DfMp3_StatusSource_Usb LITERAL1
DfMp3_StatusSource_Sd LITERAL1
DfMp3_StatusSource_Sleep LITERAL1
DfMp3_Error_Busy LITERAL1
DfMp3_Error_Sleeping LITERAL1
DfMp3_Error_SerialWrongStack LITERAL1
DfMp3_Error_CheckSumNotMatch LITERAL1
DfMp3_Error_FileIndexOut LITERAL1
DfMp3_Error_FileMismatch LITERAL1
DfMp3_Error_Advertise LITERAL1
DfMp3_Error_SdReadFail LITERAL1
DfMp3_Error_EnteredSleep LITERAL1
DfMp3_Error_RxTimeout LITERAL1
DfMp3_Error_PacketSize LITERAL1
DfMp3_Error_PacketHeader LITERAL1
DfMp3_Error_PacketChecksum LITERAL1
DfMp3_Error_General LITERAL1
14 changes: 14 additions & 0 deletions library.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "DFMiniMp3",
"keywords": "DFPlayer, MP3, Arduino",
"description": "Library for the DFPlayer Mini Mp3 module.",
"homepage": "https://github.com/Makuna/DFMiniMp3/wiki",
"repository": {
"type": "git",
"url": "https://github.com/Makuna/DFMiniMp3"
},
"version": "1.2.3",
"frameworks": "arduino",
"platforms": "*"
}

2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=DFPlayer Mini Mp3 by Makuna
version=1.0.7
version=1.2.3
author=Michael C. Miller (makuna@live.com)
maintainer=Michael C. Miller (makuna@live.com)
sentence=Library for the DFPlayer Mini Mp3 module
643 changes: 367 additions & 276 deletions src/DFMiniMp3.h

Large diffs are not rendered by default.

88 changes: 88 additions & 0 deletions src/DfMp3Callback.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*-------------------------------------------------------------------------
DFMiniMp3 library
Written by Michael C. Miller.
I invest time and resources providing this open source code,
please support me by dontating (see https://github.com/Makuna/DFMiniMp3)
-------------------------------------------------------------------------
This file is part of the Makuna/DFMiniMp3 library.
DFMiniMp3 is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
DFMiniMp3 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with DFMiniMp3. If not, see
<http://www.gnu.org/licenses/>.
-------------------------------------------------------------------------*/
#pragma once

template <class T_CALLBACK_TARGET>
class DfMp3Callback
{
public:
typedef T_CALLBACK_TARGET TargetType;

static void SetTarget(TargetType* target)
{
s_target = target;
}

~DfMp3Callback()
{
s_target = nullptr;
}

static void OnError(uint16_t errorCode)
{
if (s_target)
{
s_target->OnError(errorCode);
}
}

static void OnPlayFinished(DfMp3_PlaySources source, uint16_t track)
{
if (s_target)
{
s_target->OnPlayFinished(source, track);
}
}

static void OnPlaySourceOnline(DfMp3_PlaySources source)
{
if (s_target)
{
s_target->OnPlaySourceOnline(source);
}
}

static void OnPlaySourceInserted(DfMp3_PlaySources source)
{
if (s_target)
{
s_target->OnPlaySourceInserted(source);
}
}

static void OnPlaySourceRemoved(DfMp3_PlaySources source)
{
if (s_target)
{
s_target->OnPlaySourceRemoved(source);
}
}

protected:
static T_CALLBACK_TARGET* s_target;
};

template <class T_CALLBACK_TARGET> T_CALLBACK_TARGET* DfMp3Callback< T_CALLBACK_TARGET>::s_target = nullptr;
56 changes: 56 additions & 0 deletions src/DfMp3NoCallback.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*-------------------------------------------------------------------------
DFMiniMp3 library
Written by Michael C. Miller.
I invest time and resources providing this open source code,
please support me by dontating (see https://github.com/Makuna/DFMiniMp3)
-------------------------------------------------------------------------
This file is part of the Makuna/DFMiniMp3 library.
DFMiniMp3 is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
DFMiniMp3 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with DFMiniMp3. If not, see
<http://www.gnu.org/licenses/>.
-------------------------------------------------------------------------*/
#pragma once

class DfMp3NoCallback
{
public:
typedef void TargetType;

static void SetTarget(TargetType*)
{
}

static void OnError(uint16_t)
{
}

static void OnPlayFinished(DfMp3_PlaySources, uint16_t)
{
}

static void OnPlaySourceOnline(DfMp3_PlaySources)
{
}

static void OnPlaySourceInserted(DfMp3_PlaySources)
{
}

static void OnPlaySourceRemoved(DfMp3_PlaySources)
{
}
};
109 changes: 109 additions & 0 deletions src/DfMp3Types.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*-------------------------------------------------------------------------
DfMp3Types - API exposed support enums and structs
Written by Michael C. Miller.
I invest time and resources providing this open source code,
please support me by dontating (see https://github.com/Makuna/DFMiniMp3)
-------------------------------------------------------------------------
This file is part of the Makuna/DFMiniMp3 library.
DFMiniMp3 is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
DFMiniMp3 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with DFMiniMp3. If not, see
<http://www.gnu.org/licenses/>.
-------------------------------------------------------------------------*/

#pragma once


enum DfMp3_Error
{
// alternative meanings depending on chip
// from device
DfMp3_Error_Busy = 1, // busy busy
DfMp3_Error_Sleeping, // frame not received sleep
DfMp3_Error_SerialWrongStack, // verification error frame not received
DfMp3_Error_CheckSumNotMatch, // checksum
DfMp3_Error_FileIndexOut, // folder out of scope track out of scope
DfMp3_Error_FileMismatch, // folder not found track not found
DfMp3_Error_Advertise, // only allowed while playing advertisement not allowed
DfMp3_Error_SdReadFail, // SD card failed
DfMp3_Error_FlashReadFail, // Flash mem failed
DfMp3_Error_EnteredSleep = 10, // entered sleep
// from library
DfMp3_Error_RxTimeout = 0x81,
DfMp3_Error_PacketSize,
DfMp3_Error_PacketHeader,
DfMp3_Error_PacketChecksum,
DfMp3_Error_General = 0xff
};

enum DfMp3_PlaybackMode
{
DfMp3_PlaybackMode_Repeat,
DfMp3_PlaybackMode_FolderRepeat,
DfMp3_PlaybackMode_SingleRepeat,
DfMp3_PlaybackMode_Random
};

enum DfMp3_Eq
{
DfMp3_Eq_Normal,
DfMp3_Eq_Pop,
DfMp3_Eq_Rock,
DfMp3_Eq_Jazz,
DfMp3_Eq_Classic,
DfMp3_Eq_Bass
};

enum DfMp3_PlaySource // value - only one can be set
{
DfMp3_PlaySource_Usb = 1,
DfMp3_PlaySource_Sd,
DfMp3_PlaySource_Aux,
DfMp3_PlaySource_Sleep,
DfMp3_PlaySource_Flash
};

enum DfMp3_PlaySources // bitfield - more than one can be set
{
DfMp3_PlaySources_Usb = 0x01,
DfMp3_PlaySources_Sd = 0x02,
DfMp3_PlaySources_Pc = 0x04,
DfMp3_PlaySources_Flash = 0x08,
};

enum DfMp3_StatusState
{
DfMp3_StatusState_Idle = 0x00,
DfMp3_StatusState_Playing = 0x01,
DfMp3_StatusState_Paused = 0x02,
DfMp3_StatusState_Sleep = 0x08, // note, some chips use DfMp3_StatusSource_Sleep
DfMp3_StatusState_Shuffling = 0x11, // not documented, but discovered
};

enum DfMp3_StatusSource
{
DfMp3_StatusSource_General = 0x00,
DfMp3_StatusSource_Usb = 0x01,
DfMp3_StatusSource_Sd = 0x02,
DfMp3_StatusSource_Sleep = 0x10,
};

struct DfMp3_Status
{
DfMp3_StatusSource source;
DfMp3_StatusState state;
};

57 changes: 57 additions & 0 deletions src/Mp3ChipBase.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*-------------------------------------------------------------------------
Mp3ChipBase - base class to T_CHIP_VARIANT template features
Written by Michael C. Miller.
I invest time and resources providing this open source code,
please support me by dontating (see https://github.com/Makuna/DFMiniMp3)
-------------------------------------------------------------------------
This file is part of the Makuna/DFMiniMp3 library.
DFMiniMp3 is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
DFMiniMp3 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with DFMiniMp3. If not, see
<http://www.gnu.org/licenses/>.
-------------------------------------------------------------------------*/

#pragma once


class Mp3ChipBase
{
private:
static uint16_t calcChecksum(const Mp3_Packet_WithCheckSum& packet)
{
uint16_t sum = 0xFFFF;
for (const uint8_t* packetByte = &(packet.version); packetByte != &(packet.hiByteCheckSum); packetByte++)
{
sum -= *packetByte;
}
return sum + 1;
}

public:
static void setChecksum(Mp3_Packet_WithCheckSum* out)
{
uint16_t sum = calcChecksum(*out);

out->hiByteCheckSum = (sum >> 8);
out->lowByteCheckSum = (sum & 0xff);
}

static bool validateChecksum(const Mp3_Packet_WithCheckSum& in)
{
uint16_t sum = calcChecksum(in);
return (sum == ((static_cast<uint16_t>(in.hiByteCheckSum) << 8) | in.lowByteCheckSum));
}
};
58 changes: 58 additions & 0 deletions src/Mp3ChipIncongruousNoAck.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*-------------------------------------------------------------------------
Mp3ChipIncongruousNoAck - chip class for T_CHIP_VARIANT template features
Written by Michael C. Miller.
I invest time and resources providing this open source code,
please support me by dontating (see https://github.com/Makuna/DFMiniMp3)
-------------------------------------------------------------------------
This file is part of the Makuna/DFMiniMp3 library.
DFMiniMp3 is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
DFMiniMp3 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with DFMiniMp3. If not, see
<http://www.gnu.org/licenses/>.
-------------------------------------------------------------------------*/
#pragma once


class Mp3ChipIncongruousNoAck : public Mp3ChipBase
{
public:
static const bool SendCheckSum = true;

typedef Mp3_Packet_WithCheckSum SendPacket;
typedef Mp3_Packet_WithCheckSum ReceptionPacket;

static const SendPacket generatePacket(uint8_t command, uint16_t arg, bool requestAck = false)
{
SendPacket packet = {
Mp3_PacketStartCode,
Mp3_PacketVersion,
6, // size, remaining bytes not including end code
command,
requestAck,
static_cast<uint8_t>(arg >> 8),
static_cast<uint8_t>(arg & 0x00ff),
0, // checksum calculated below
0, // checksum calculated below
Mp3_PacketEndCode };
setChecksum(&packet);
return packet;
}

static bool commandSupportsAck(uint8_t command)
{
return (command > Mp3_Commands_Requests);
}
};
55 changes: 55 additions & 0 deletions src/Mp3ChipMH2024K16SS.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*-------------------------------------------------------------------------
Mp3ChipMH2024K16SS - chip class for T_CHIP_VARIANT template features
Written by Michael C. Miller.
I invest time and resources providing this open source code,
please support me by dontating (see https://github.com/Makuna/DFMiniMp3)
-------------------------------------------------------------------------
This file is part of the Makuna/DFMiniMp3 library.
DFMiniMp3 is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
DFMiniMp3 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with DFMiniMp3. If not, see
<http://www.gnu.org/licenses/>.
-------------------------------------------------------------------------*/


#pragma once

class Mp3ChipMH2024K16SS : public Mp3ChipBase
{
public:
static const bool SendCheckSum = false;

typedef Mp3_Packet_WithoutCheckSum SendPacket;
typedef Mp3_Packet_WithCheckSum ReceptionPacket;

static const SendPacket generatePacket(uint8_t command, uint16_t arg, bool requestAck = false)
{
return {
Mp3_PacketStartCode,
Mp3_PacketVersion,
6, // size: of what? without checksum this doesn't make sense
command,
requestAck,
static_cast<uint8_t>(arg >> 8),
static_cast<uint8_t>(arg & 0x00ff),
Mp3_PacketEndCode };
}

static bool commandSupportsAck([[maybe_unused]] uint8_t command)
{
return true;
}
};
58 changes: 58 additions & 0 deletions src/Mp3ChipOriginal.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*-------------------------------------------------------------------------
Mp3ChipOriginal - chip class for T_CHIP_VARIANT template features
Written by Michael C. Miller.
I invest time and resources providing this open source code,
please support me by dontating (see https://github.com/Makuna/DFMiniMp3)
-------------------------------------------------------------------------
This file is part of the Makuna/DFMiniMp3 library.
DFMiniMp3 is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
DFMiniMp3 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with DFMiniMp3. If not, see
<http://www.gnu.org/licenses/>.
-------------------------------------------------------------------------*/
#pragma once


class Mp3ChipOriginal : public Mp3ChipBase
{
public:
static const bool SendCheckSum = true;

typedef Mp3_Packet_WithCheckSum SendPacket;
typedef Mp3_Packet_WithCheckSum ReceptionPacket;

static const SendPacket generatePacket(uint8_t command, uint16_t arg, bool requestAck = false)
{
SendPacket packet = {
Mp3_PacketStartCode,
Mp3_PacketVersion,
6, // size, remaining bytes not including end code
command,
requestAck,
static_cast<uint8_t>(arg >> 8),
static_cast<uint8_t>(arg & 0x00ff),
0, // checksum calculated below
0, // checksum calculated below
Mp3_PacketEndCode };
setChecksum(&packet);
return packet;
}

static bool commandSupportsAck([[maybe_unused]] uint8_t command)
{
return true;
}
};
133 changes: 133 additions & 0 deletions src/internal/Mp3Packet.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/*-------------------------------------------------------------------------
Mp3Packet - packet specific enums and structures
Written by Michael C. Miller.
I invest time and resources providing this open source code,
please support me by dontating (see https://github.com/Makuna/DFMiniMp3)
-------------------------------------------------------------------------
This file is part of the Makuna/DFMiniMp3 library.
DFMiniMp3 is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
DFMiniMp3 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with DFMiniMp3. If not, see
<http://www.gnu.org/licenses/>.
-------------------------------------------------------------------------*/

#pragma once

enum Mp3_Commands
{
Mp3_Commands_None = 0x00,
Mp3_Commands_PlayNextTrack = 0x01,
Mp3_Commands_PlayPrevTrack = 0x02,
Mp3_Commands_PlayGlobalTrack = 0x03,
Mp3_Commands_IncVolume = 0x04,
Mp3_Commands_DecVolume = 0x05,
Mp3_Commands_SetVolume = 0x06,
Mp3_Commands_SetEq = 0x07,
Mp3_Commands_LoopGlobalTrack = 0x08,
Mp3_Commands_SetPlaybackMode = 0x08,
Mp3_Commands_SetPlaybackSource = 0x09,
Mp3_Commands_Sleep = 0x0a,
Mp3_Commands_Awake = 0x0b,
Mp3_Commands_Reset = 0x0c,
Mp3_Commands_Start = 0x0d,
Mp3_Commands_Pause = 0x0e,
Mp3_Commands_PlayFolderTrack = 0x0f,
Mp3_Commands_RepeatPlayInRoot = 0x11,
Mp3_Commands_PlayMp3FolderTrack = 0x12,
Mp3_Commands_PlayAdvertTrack = 0x13,
Mp3_Commands_PlayFolderTrack16 = 0x14,
Mp3_Commands_StopAdvert = 0x15,
Mp3_Commands_Stop = 0x16,
Mp3_Commands_LoopInFolder = 0x17,
Mp3_Commands_PlayRandmomGlobalTrack = 0x18,
Mp3_Commands_RepeatPlayCurrentTrack = 0x19,
Mp3_Commands_SetDacInactive = 0x1a,
Mp3_Commands_Requests = 0x30, // after this is all request, before all actions
Mp3_Commands_GetPlaySources = 0x3f, // deprecated due to conflict with replies
Mp3_Commands_GetStatus = 0x42,
Mp3_Commands_GetVolume = 0x43,
Mp3_Commands_GetEq = 0x44,
Mp3_Commands_GetPlaybackMode = 0x45,
Mp3_Commands_GetSoftwareVersion = 0x46,
Mp3_Commands_GetUsbTrackCount = 0x47,
Mp3_Commands_GetSdTrackCount = 0x48,
Mp3_Commands_GetFlashTrackCount = 0x49,
Mp3_Commands_GetUsbCurrentTrack = 0x4b,
Mp3_Commands_GetSdCurrentTrack = 0x4c,
Mp3_Commands_GetFlashCurrentTrack = 0x4d,
Mp3_Commands_GetFolderTrackCount = 0x4e,
Mp3_Commands_GetTotalFolderCount = 0x4f,
};


enum Mp3_Replies
{
Mp3_Replies_PlaySource_Inserted = 0x3a,
Mp3_Replies_PlaySource_Removed = 0x3b,
Mp3_Replies_TrackFinished_Usb = 0x3c,
Mp3_Replies_TrackFinished_Sd = 0x3d,
Mp3_Replies_TrackFinished_Flash = 0x3e,
Mp3_Replies_PlaySource_Online = 0x3f,
Mp3_Replies_Error = 0x40,
Mp3_Replies_Ack = 0x41,
};

const uint8_t Mp3_PacketStartCode = 0x7e;
const uint8_t Mp3_PacketVersion = 0xff;
const uint8_t Mp3_PacketEndCode = 0xef;

// 7E FF 06 0F 00 01 01 xx xx EF
// 0 -> 7E is start code
// 1 -> FF is version
// 2 -> 06 is length
// 3 -> 0F is command
// 4 -> 00 is no receive
// 5~6 -> 01 01 is argument
// 7~8 -> checksum = 0 - ( FF+06+0F+00+01+01 )
// 9 -> EF is end code
struct Mp3_Packet_WithCheckSum
{
uint8_t startCode;
uint8_t version;
uint8_t length;
uint8_t command;
uint8_t requestAck;
uint8_t hiByteArgument;
uint8_t lowByteArgument;
uint8_t hiByteCheckSum;
uint8_t lowByteCheckSum;
uint8_t endCode;
};

// 7E FF 06 0F 00 01 01 EF
// 0 -> 7E is start code
// 1 -> FF is version
// 2 -> 06 is length
// 3 -> 0F is command
// 4 -> 00 is no receive
// 5~6 -> 01 01 is argument
// 7 -> EF is end code
struct Mp3_Packet_WithoutCheckSum
{
uint8_t startCode;
uint8_t version;
uint8_t length;
uint8_t command;
uint8_t requestAck;
uint8_t hiByteArgument;
uint8_t lowByteArgument;
uint8_t endCode;
};
132 changes: 132 additions & 0 deletions src/internal/queueSimple.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/*-------------------------------------------------------------------------
queueSimple_t - simple vector queue, as not all Arduino have stl types available
Written by Michael C. Miller.
I invest time and resources providing this open source code,
please support me by dontating (see https://github.com/Makuna/DFMiniMp3)
-------------------------------------------------------------------------
This file is part of the Makuna/DFMiniMp3 library.
DFMiniMp3 is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
DFMiniMp3 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with DFMiniMp3. If not, see
<http://www.gnu.org/licenses/>.
-------------------------------------------------------------------------*/
#pragma once

template <class T_ITEM> class queueSimple_t
{
public:
queueSimple_t(uint8_t length) :
_queue(nullptr),
_length(0),
_front(0),
_back(0)
{
enlarge(length);
}

~queueSimple_t()
{
delete[] _queue;
_queue = nullptr;
}

void Enqueue(const T_ITEM& item)
{
//Serial.print("Enqueue (");
//item.printReply();
//Serial.print(") front(");
//Serial.print(_front);
//Serial.print(") back(");
//Serial.print(_back);
//Serial.println(")");

uint8_t newBack = _back + 1;
if (newBack >= _length)
{
newBack = 0;
}

if (newBack == _front)
{
// no space left, enlarge
enlarge(_length + 2);
newBack = _back + 1;
}
_queue[_back] = item;
_back = newBack;
}

bool Dequeue(T_ITEM* item)
{
if (_front == _back)
{
*item = {};
return false;
}

*item = _queue[_front];
_front++;
if (_front >= _length)
{
_front = 0;
}

return true;
}

private:
T_ITEM* _queue;
uint8_t _length;
uint8_t _front; // location of removing present items
uint8_t _back; // location of appending new items

void enlarge(uint8_t newLength)
{
#ifdef DfMiniMp3Debug
// only debug output after construction
if (_queue)
{
DfMiniMp3Debug.print("Notifications Queue Enlarged from ");
DfMiniMp3Debug.print(_length);
DfMiniMp3Debug.print(" to ");
DfMiniMp3Debug.println(newLength);
}
#endif
if (newLength <= _length)
{
return;
}

// allocate new vector of items
T_ITEM* queueNew = new T_ITEM[newLength];
uint8_t backNew = 0;

// copy items from old queue vector to new one
T_ITEM* item = queueNew;
while (Dequeue(item))
{
backNew++;
item++;
}

// cleanup and use new queue
delete[] _queue;
_queue = queueNew;
_length = newLength;
_front = 0;
_back = backNew;
}
};