Monday, December 9, 2019

Sparkfun MP3 Shield


I have used a lot of these MP3 player shields in projects. They are super awesome and super simple to use, but I figured a small writeup was worthwhile as there are some details that aren't in the official documentation as well as some tips I have when using the shield.

The MP3 shield uses just about every pin on the Arduino. The documentation states you can use D5, D10 and A0-A5. However, I have found that for some reason when using the shield I have found neither D5 nor D10 to be usable. So typically what I do is setup a software serial using two of the analog pins:

#include <SPI.h>
#include <SdFat.h>
#include <SFEMP3Shield.h>
#include <SoftwareSerial.h>


SdFat sd;
SFEMP3Shield MP3player;

SoftwareSerial input(A0, A1); // RX, TX


void setup() {
  Serial.begin(115200);
  
  input.begin(9600);
  input.flush();

  if(!sd.begin(9, SPI_HALF_SPEED)) {
    sd.initErrorHalt();
  }
   
  if (!sd.chdir("/")) {
    sd.errorHalt("sd.chdir");
  }

  uint8_t result = MP3player.begin();

  if(result != 0) // check result, see readme for error codes.
  {
    Serial.println("error");
    Serial.print(F("Error code: "));
    Serial.print(result);
  }

  // Loudest volume for left and right
  MP3player.setVolume(0, 0);
  
  Serial.println("Ready");
}

void loop() {
  if (input.available()) {
    Serial.println("reading");
    String action = readFromSerial();
    Serial.println(action);
    input.flush();
  
    if (action == "play") {
      Serial.println("Playing"); 
      uint8_t result = MP3player.playMP3("awesome.mp3");
      delay(3000);
      Serial.println("Ready again"); 
    }
  }
}

String readFromSerial() {
  static char buffer[80];
  if (readline(input.read(), buffer, 80) > 0) 
  {
    Serial.println(buffer);    
  }
  return buffer;
}

int readline(int readch, char *buffer, int len)
{
  static int pos = 0;
  int rpos;

  if (readch > 0) {
    switch (readch) {
      case '\n': // Ignore new-lines
        break;
      case '\r': // Return on CR
        rpos = pos;
        pos = 0;  // Reset position index ready for next time
        return rpos;
      default:
        if (pos < len-1) {
          buffer[pos++] = readch;
          buffer[pos] = 0;
        }
    }
  }
  // No end of line has been found, so return -1.
  return -1;
}

No comments:

Post a Comment