JQ8400 MP3 Player Arduino Library
A simple library to control a JQ8400 MP3 Player Module from an Arduino.
|
Public Member Functions | |
JQ8400_Serial (Stream &_Stream) | |
Create JQ8400 object with a given serial object to communicate to the JQ8400. More... | |
void | play () |
Start playing the current file, if paused the playing is resumed. More... | |
void | restart () |
Restart the current track from the beginning. | |
void | pause () |
Pause the current file. More... | |
void | stop () |
Stop the current playing (if any). | |
void | fastForward (uint16_t seconds=5) |
Fast Forward by a number of seconds (default 5). | |
void | rewind (uint16_t seconds=5) |
Rewind by a number of seconds (default 5). | |
void | next () |
Play the next file. | |
void | prev () |
Play the previous file. | |
void | nextFolder () |
Play the next folder. | |
void | prevFolder () |
Play the previous folder. | |
void | playFileByIndexNumber (uint16_t fileNumber) |
Play a specific file based on it's FAT index number. More... | |
void | interjectFileByIndexNumber (uint16_t fileNumber) |
Interject the currently playing file (if any) with the given FAT index number file. More... | |
void | playFileNumberInFolderNumber (uint16_t folderNumber, uint16_t fileNumber) |
Play a specific file in a specific folder based on the name of those folder and file. More... | |
void | playInFolderNumber (uint16_t folderNumber) |
Play the first (?) file in a specific folder 00 to 99. More... | |
void | seekFileByIndexNumber (uint16_t fileNumber) |
Seek to a specific file based on it's FAT index number. More... | |
void | abLoopPlay (uint16_t secondsStart, uint16_t secondsEnd) |
A-B Loop for the file currently playing. More... | |
void | abLoopClear () |
Use this to break a currently running A-B loop. More... | |
void | volumeUp () |
Increase the volume by 1 (volume ranges 0 to 30). More... | |
void | volumeDn () |
Decrease the volume by 1 (volume ranges 0 to 30). More... | |
void | setVolume (byte volumeFrom0To30) |
Set the volume to a specific level (0 to 30). More... | |
void | setEqualizer (byte equalizerMode) |
Set the equalizer to one of 6 preset modes. More... | |
void | setLoopMode (byte loopMode) |
Set the looping mode. More... | |
void | setSource (byte source) |
Set the source to read mp3 data from. More... | |
uint8_t | getSource () |
Return the currently selected source. More... | |
uint8_t | sourceAvailable (uint8_t source) |
Return boolean indicating if the given source is available (can be selected using setSource() ) More... | |
void | sleep () |
Put the device to sleep. More... | |
void | reset () |
Reset the device (softly). More... | |
byte | getStatus () |
Get the status from the device. More... | |
uint8_t | busy () |
Return if the device is busy (playing) or not. More... | |
byte | getVolume () |
Get the current volume level. More... | |
byte | getEqualizer () |
Get the equalizer mode. More... | |
byte | getLoopMode () |
Get loop mode. More... | |
uint16_t | countFiles () |
Count the number of files on the current media. More... | |
uint16_t | currentFileIndexNumber () |
For the currently playing (or paused, or file that would be played next if stopped) file, return the file's FAT index number. More... | |
uint16_t | currentFilePositionInSeconds () |
For the currently playing or paused file, return the current position in seconds. More... | |
uint16_t | currentFileLengthInSeconds () |
For the currently playing or paused file, return the total length of the file in seconds. More... | |
void | currentFileName (char *buffer, uint16_t bufferLength) |
Get the name of the "current" file. More... | |
void | playSequenceByFileNumber (uint8_t playList[], uint8_t listLength) |
Play a sequence of files, which must all exist in a folder called "ZH" and be named 00.mp3 through 99.mp3. More... | |
void | playSequenceByFileName (const char *playList[], uint8_t listLength) |
Play a sequence of files, which must all exist in a folder called "ZH" and have 2 character names. More... | |
Protected Member Functions | |
void | sendCommandData (uint8_t command, uint8_t *requestBuffer, uint8_t requestLength, uint8_t *responseBuffer, uint8_t bufferLength) |
Send a command to the JQ8400 module,. More... | |
void | sendCommand (uint8_t command, uint8_t *responseBuffer=0, uint8_t bufferLength=0) |
Send a command with no arguments and no response. More... | |
void | sendCommand (uint8_t command, uint8_t arg, uint8_t *responseBuffer=0, uint8_t bufferLength=0) |
Send a command with a single 8 bit argument and no response. More... | |
void | sendCommand (uint8_t command, uint16_t arg, uint8_t *responseBuffer=0, uint8_t bufferLength=0) |
Send a command with a 16 bit integer argument. More... | |
uint16_t | sendCommandWithUnsignedIntResponse (byte command) |
Send a command to the JQ8400 module, and get a 16 bit integer response. More... | |
uint8_t | sendCommandWithByteResponse (uint8_t command) |
Send a command to the JQ8400 module, and get an 8 bit integer response. More... | |
uint8_t | getAvailableSources () |
Return a bitmask of the available sources. More... | |
int | waitUntilAvailable (uint16_t maxWaitTime=1000) |
Blocking wait with a timeout for serial input. More... | |
Protected Attributes | |
Stream * | _Serial |
Set in the constructor, the stream (eg HardwareSerial or SoftwareSerial object) that connects us to the device. | |
uint8_t | currentVolume = 20 |
Record of current volume level (JQ8400 has no way to query) | |
uint8_t | currentEq = 0 |
Record of current equalizer (JQ8400 has no way to query) | |
uint8_t | currentLoop = 2 |
Record of current loop mode (JQ8400 has no way to query) | |
|
inline |
Create JQ8400 object with a given serial object to communicate to the JQ8400.
#include <SoftwareSerial.h> SoftwareSerial mySerial(8,9); #include <JQ8400_Serial.h> JQ8400_Serial mp3(mySerial); void setup() { mySerial.begin(9600); mp3.reset(); }
#include <JQ8400_Serial.h> JQ8400_Serial mp3(Serial); void setup() { Serial.begin(9600); mp3.reset(); }
#include <JQ8400_Serial.h> JQ8400_Serial mp3(Serial2); void setup() { Serial2.begin(9600); mp3.reset(); }
Of course, power and ground are also required, VCC on JQ8400 is 5v tolerant (but RX isn't totally, hence the resistor above). *
The TX voltage from the JQ8400 is 3.3v, you do not need to level-shift this as 3.3v will still read as high for a 5v Arduino (and is safe for a 3.3v one).
void JQ8400_Serial::abLoopClear | ( | ) |
Use this to break a currently running A-B loop.
Pause, stop, play will also break the A-B loop, this will do it without requiring any break the play will just continue through the previously set end marker without looping.
void JQ8400_Serial::abLoopPlay | ( | uint16_t | secondsStart, |
uint16_t | secondsEnd | ||
) |
A-B Loop for the file currently playing.
For the track that is already playing (and not paused) loop play between two marks defined by a start and end second.
If you want to start a file in an ab loop, start it playing and immediately issue the abLoopPlay.
mp3.playFileByIndexNumber(1); mp3.abLoopPlay(25,50);
will work, similarly if you want to resume from a pause into an ab loop
mp3.play(); mp3.abLoopPlay(25,50);
if you pause in an abLoop when you play again the abLoop is terminated.
There seems to be some sort of odd granularity with this function of the device, the first time through the ab-loop the start point is sometimes different to subsequent loops through, perhaps a second "out", that is if you specify start at 25 seconds, the first loop might start at 24, and subsequent ones at 25 (or vice-versa). In short, experimentation might be needed here.
secondsStart | Second to set as start marker. |
secondsEnd | Second to set as end marker. |
|
inline |
Return if the device is busy (playing) or not.
Just a convenience test, equivalent to getStatus() == MP3_STATUS_PLAYING
uint16_t JQ8400_Serial::countFiles | ( | ) |
Count the number of files on the current media.
uint16_t JQ8400_Serial::currentFileIndexNumber | ( | ) |
For the currently playing (or paused, or file that would be played next if stopped) file, return the file's FAT index number.
This number can be used with playFileByIndexNumber();
About The FAT Index Number
Note that the index number has nothing to do with the file name (except if you uploaded/copied them to the media in order of file name).
It is the index of the file in the drive's File Allocation Table (FAT), loosely this is usually the order in which you copied the files across, but due to operating systems that's not entirely assured.
To sort the FAT (after copying files), or view the FAT order, search for a FAT sorting utility for your operating system.
Specifically on Linux fatsort is the tool you want, but be sure to get a recent version which supports FAT-12, older ones do not.
uint16_t JQ8400_Serial::currentFileLengthInSeconds | ( | ) |
For the currently playing or paused file, return the total length of the file in seconds.
void JQ8400_Serial::currentFileName | ( | char * | buffer, |
uint16_t | bufferLength | ||
) |
Get the name of the "current" file.
The name returned is shortened significantly to 8+3 format without a dot, all caps... in other words, this isn't very useful probably.
The current file is the one that is playing, paused, or if stopped then could be next to play or last played, uncertain.
Example
char buf[12]; mp3.currentFileName(buf, sizeof(buf)); Serial.println(buf);
buffer | character buffer of 12 bytes or more (eg char buf[12] ) |
bufferLength | length of the buffer (eg 12) |
uint16_t JQ8400_Serial::currentFilePositionInSeconds | ( | ) |
For the currently playing or paused file, return the current position in seconds.
|
protected |
Return a bitmask of the available sources.
bit 0 = USB bit 1 = SD bit 2 = FLASH
byte JQ8400_Serial::getEqualizer | ( | ) |
Get the equalizer mode.
byte JQ8400_Serial::getLoopMode | ( | ) |
Get loop mode.
uint8_t JQ8400_Serial::getSource | ( | ) |
Return the currently selected source.
byte JQ8400_Serial::getStatus | ( | ) |
Get the status from the device.
byte JQ8400_Serial::getVolume | ( | ) |
Get the current volume level.
void JQ8400_Serial::interjectFileByIndexNumber | ( | uint16_t | fileNumber | ) |
Interject the currently playing file (if any) with the given FAT index number file.
Like a special announcement comes over, it interrupts the music playing, when the announcement finishes, the music continues.
About The FAT Index Number
Note that the index number has nothing to do with the file name (except if you uploaded/copied them to the media in order of file name).
It is the index of the file in the drive's File Allocation Table (FAT), loosely this is usually the order in which you copied the files across, but due to operating systems that's not entirely assured.
To sort the FAT (after copying files), or view the FAT order, search for a FAT sorting utility for your operating system.
Specifically on Linux fatsort is the tool you want, but be sure to get a recent version which supports FAT-12, older ones do not.
fileNumber | FAT index of the file to interject. |
void JQ8400_Serial::pause | ( | ) |
void JQ8400_Serial::play | ( | ) |
Start playing the current file, if paused the playing is resumed.
If stopped or playing the playing is started from beginning.
void JQ8400_Serial::playFileByIndexNumber | ( | uint16_t | fileNumber | ) |
Play a specific file based on it's FAT index number.
About The FAT Index Number
Note that the index number has nothing to do with the file name (except if you uploaded/copied them to the media in order of file name).
It is the index of the file in the drive's File Allocation Table (FAT), loosely this is usually the order in which you copied the files across, but due to operating systems that's not entirely assured.
To sort the FAT (after copying files), or view the FAT order, search for a FAT sorting utility for your operating system.
Specifically on Linux fatsort is the tool you want, but be sure to get a recent version which supports FAT-12, older ones do not.
fileNumber | FAT index of the file to play next. |
void JQ8400_Serial::playFileNumberInFolderNumber | ( | uint16_t | folderNumber, |
uint16_t | fileNumber | ||
) |
Play a specific file in a specific folder based on the name of those folder and file.
To use this function, folders must be named from 00 to 99, and the files in those folders must be named from 000.mp3 to 999.mp3
Example
The device contains the file...
/03/006.mp3
then the following code will play that file...
mp3.playFileNumberInFolderNumber(3, 6);
Note that zero padding of your folder and file names is required - "01/002.mp3" good, "1/2.mp3" bad.
folderNumber | 0 to 99 |
fileNumber | 0 to 999 |
void JQ8400_Serial::playInFolderNumber | ( | uint16_t | folderNumber | ) |
Play the first (?) file in a specific folder 00 to 99.
To use this function, folders must be named from 00 to 99.
So to play the folder "/03" use mp3.playInFolderNumber(3);
Note that zero padding of your folder and file required - "01/002.mp3" good, "1/2.mp3" bad.
folderNumber | 0 to 99 |
void JQ8400_Serial::playSequenceByFileName | ( | const char * | playList[], |
uint8_t | listLength | ||
) |
Play a sequence of files, which must all exist in a folder called "ZH" and have 2 character names.
Don't ask me why the folder must be called "ZH", that's what the JQ8400 wants.
Example
Given that the JQ8400 contains the files...
/ZH/A1.mp3 /ZH/1B.mp3 /ZH/AZ.mp3
then the following code will play them in the order 1B.mp3, A1.mp3, AZ.mp3
const char * playList[] = { "1B", "A1", "AZ" }; mp3.playSequenceByFileName(playList, sizeof(playList)/sizeof(char *));
playList | An array of the two character names (as strings). |
listLength | Number of filenames in the list. |
void JQ8400_Serial::playSequenceByFileNumber | ( | uint8_t | playList[], |
uint8_t | listLength | ||
) |
Play a sequence of files, which must all exist in a folder called "ZH" and be named 00.mp3 through 99.mp3.
Don't ask me why the folder must be called "ZH", that's what the JQ8400 wants.
Example
Given that the JQ8400 contains the files...
/ZH/01.mp3 /ZH/02.mp3 /ZH/03.mp3
then the following code will play them in the order 03.mp3, 01.mp3, 02.mp3
uint8_t playList[] = { 3, 1, 2 }; mp3.playSequenceByFileNumber(playList, sizeof(playList));
pay attention that the file names are 2 digits, "`1.mp3`" is not valid.
playList | An array of the numbers of files in the "ZH" folder. |
listLength | Number of filenames in the list. |
void JQ8400_Serial::reset | ( | ) |
Reset the device (softly).
It may be necessary in practice to actually power-cycle the device in case it gets confused or something.
So if designing a PCB/circuit including JQ8400 modules it might be worth while to include such ability (ie, power the device through a MOSFET which you can turn on/off at will).
void JQ8400_Serial::seekFileByIndexNumber | ( | uint16_t | fileNumber | ) |
Seek to a specific file based on it's FAT index number.
The file will not start playing until you issue play()
Note that any currently playing file will stop immediately.
It seems (undocumented) that seeking to a track will wake up the device's output and keep it awake until you play or stop (or it stops after playing), you may wish to issue a sleep() after seeking.
About The FAT Index Number
Note that the index number has nothing to do with the file name (except if you uploaded/copied them to the media in order of file name).
It is the index of the file in the drive's File Allocation Table (FAT), loosely this is usually the order in which you copied the files across, but due to operating systems that's not entirely assured.
To sort the FAT (after copying files), or view the FAT order, search for a FAT sorting utility for your operating system.
Specifically on Linux fatsort is the tool you want, but be sure to get a recent version which supports FAT-12, older ones do not.
fileNumber | FAT index of the file to play next. |
|
inlineprotected |
Send a command with no arguments and no response.
command | Byte value of to send as from the datasheet. |
|
inlineprotected |
Send a command with a single 8 bit argument and no response.
command | Byte value of to send as from the datasheet. |
arg | Single byte of data |
|
inlineprotected |
Send a command with a 16 bit integer argument.
command | Byte value of to send as from the datasheet. |
arg | 16 bit uint16_teger data |
|
protected |
Send a command to the JQ8400 module,.
command | Byte value of to send as from the datasheet. |
requestBuffer | Pointer to (or NULL) request data bytes. |
requestLength | Number of bytes in the request buffer. |
responseBuffer | Buffer to store a single line of response, if NULL, no response is read. Note that the response is NOT a null-terminated string, if you want that, do it yourself (and specify length-1). |
buffLength | Length of response buffer. |
|
protected |
Send a command to the JQ8400 module, and get an 8 bit integer response.
command | Byte value of to send as from the datasheet. |
|
protected |
Send a command to the JQ8400 module, and get a 16 bit integer response.
command | Byte value of to send as from the datasheet. |
void JQ8400_Serial::setEqualizer | ( | byte | equalizerMode | ) |
Set the equalizer to one of 6 preset modes.
equalizerMode | One of the following, |
void JQ8400_Serial::setLoopMode | ( | byte | loopMode | ) |
Set the looping mode.
loopMode | One of the following, |
Note that the random options are perhaps not that optimal especially with low file counts, a track playing twice back to back is not unusual, and the randomness does not anecdotally seem all that random. (NB: These random options are implemented inside the JQ8400 device itself, not in code, you could make your own randomiser and just use play by index etc...)
void JQ8400_Serial::setSource | ( | byte | source | ) |
Set the source to read mp3 data from.
Note that the datasheet calls this "drive".
source | One of the following... |
void JQ8400_Serial::setVolume | ( | byte | volumeFrom0To30 | ) |
Set the volume to a specific level (0 to 30).
volumeFrom0To30 | Level of volume to set from 0 to 30 |
void JQ8400_Serial::sleep | ( | ) |
Put the device to sleep.
This will stop all playing. When you play() again it will be from the beginning of the current track.
Note that the JQ8400 seems to automatically sleep when it stops playing except when you seek to a track (or pause).
|
inline |
Return boolean indicating if the given source is available (can be selected using setSource()
)
source | One of the following
|
void JQ8400_Serial::volumeDn | ( | ) |
Decrease the volume by 1 (volume ranges 0 to 30).
void JQ8400_Serial::volumeUp | ( | ) |
Increase the volume by 1 (volume ranges 0 to 30).
|
protected |
Blocking wait with a timeout for serial input.
maxWaitTime | Milliseconds |