A great & very cheap MP3 sound module without need for a library!

I’ve whipped up a very rudimentary test sketch that allows you to test the MP3 commands via Particle.function().
You’d e.g. trigger the loop for folder 2 with this command string 0x17 2 0 (command, data low byte, data high byte) and this seems to start playing file 001.mp3 in that folder and then carries on to 002.mp3 - I’m not yet through the whole folder if it will loop back to 001.mp3 once it finishes, but it doesn’t look too bad :wink:

uint32_t msCmdReceived;

void sendCmd(int cmd, int lb, int hb, bool reply = false)
{                 // standard format for module command stream
    uint8_t buf[] = {0x7E, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEF}; 
    int16_t chksum = 0;
    int idx = 3;                    // position of first command byte

    buf[idx++] = (uint8_t)cmd;      // inject command byte in buffer
    if (reply) buf[idx++] = 0x01;   // set if reply is needed/wanted
    if (hb >= 0)                    // if there is a high byte data field
        buf[idx++] = (uint8_t)hb;   // add it to the buffer
    if (lb >= 0)                    // if there is a low byte data field
        buf[idx++] = (uint8_t)lb;   // add it to the buffer
    buf[2] = idx - 1;               // inject command length into buffer
    
    for (int i=1; i < idx; i++)     // calculate check sum for the provided data
        chksum += buf[i];
    chksum *= -1;

    buf[idx++] = (chksum >> 8);     // inject high byte of checksum before
    buf[idx++] = chksum & 0xFF;     // low byte of checksum
    buf[idx++] = 0xEF;              // place end-of-command byte

    Serial1.write(buf, idx);        // send the command to module
    for (int i = 0; i < idx; i++)   // send command as hex string to MCU 
      Serial.printf("%02X ", buf[i]);
    Serial.println();
}

int mp3Command(String para)
{
    int cmd = -1;                   
    int lb = -1;
    int hb = -1;
                                    // parse the command string
    int count = sscanf(para.c_str(), "0x%x %d %d", &cmd, &lb, &hb);

    if (count > 0 && cmd >= 0)      // if we got a well formed parameter string
      sendCmd(cmd, lb, hb, true);   // do the module talking

    msCmdReceived = millis();       // set a non-blocking delay timer

    return cmd;                     // return what command we think we received
}

void setup()
{
    Serial.begin(115200);
    Serial1.begin(9600);
    
    Particle.function("MP3", mp3Command);
}

void loop()
{
    if ((millis() - msCmdReceived > 500))
    {
        if (Serial.available())
            Serial.println();
        while(Serial1.available())
            Serial.printf("0x%02x ", Serial1.read());
        msCmdReceived = 0;
    }
}

This code also allows for shorter commands (omitting DL and/or DH).


Update:
Yup, the folder looping works just as expected.

1 Like