adafruit music maker

hallo zusammen,

ich baue mir gerade einen mp3 Player mit einem Mega 2560 und dem music maker shield von adafruit.
Wenn ich die Musik im Hintergrund laufen lasse und das Interrupt Beispiel verwende, läuft die Loop Funktion dann weiter? Bei mir tut sie das nämlich nicht.

Oder wie ist das gemeint mit im Hintergrund laufen?

Gruß Michael

mire:
… läuft die Loop Funktion dann weiter?

Zusammen mit einem UNO: Ja! Zusammen mit einem Mega habe ich keine Erfahrungen.

Hab auf dem shield Lötbrücken schließen müssen daß es auf dem Mega funktioniert.
Sollte dann eigentlich auch im Hintergrund laufen. Hat da schon jemand Erfahrungen gesammelt?

Es schein doch im Hintergrund zu laufen.

Aber irgendwie habe ich da ein unzuverlässig funktionierendes Programm.

//mp3 player for kids

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Rotary.h>
#include <Adafruit_VS1053.h>
#include <SdFat.h>
#include <SPI.h> 


#define BREAKOUT_RESET  9      // VS1053 reset pin (output)
#define BREAKOUT_CS     10     // VS1053 chip select pin (output)
#define BREAKOUT_DCS    8      // VS1053 Data/command select pin (output)
#define SHIELD_CS     7      // VS1053 chip select pin (output)
#define SHIELD_DCS    6      // VS1053 Data/command select pin (output)
#define DREQ          3      // VS1053 Data request, ideally an Interrupt pin
#define CARDCS        4      // Card chip select pin
Adafruit_VS1053_FilePlayer musicPlayer =
    Adafruit_VS1053_FilePlayer(SHIELD_CS, SHIELD_DCS, DREQ, CARDCS);
 
// VS1053 play speed parameter
#define para_playSpeed 0x1E04

const uint8_t chipSelect = 4;
const int analogButtonsPin = A5;

SdFat sd;
SdFile file;

LiquidCrystal_I2C lcd(0x3f,16,2);     //LCD Display mit 16 Zeichen und 2 Zeilen

Rotary r = Rotary(18, 19);            //Encoder auf digitalen Eingängen

volatile int counter=1;
int lastCounter=0;
const int cMax=6;                     //Anzahl der Ordner
const int cMin=1;
char fName[]="/mp3.txt";              //Dateiname mit CSV-Datei
char vNum[16];
char* path;                           //Dateipfad für mp3.txt

byte currentFolder = 1;               //mp3 player
unsigned int currentFile = 0;
unsigned int numberOfFiles[100];

byte volumeState = 254;               // the current volume level, set to min at start

int pressedButton = 0;

#define N 2                   //2 Elemente werden gelsen
char text[N][17];             // mit je 16 Zeichen


void encoder() {                        //Interrupt Funktion für Encoder
  unsigned char result = r.process();   //Encoderwert bestimmen
  if (result) {
    if (result==16){
      if (counter > cMin) counter--;
      else counter = cMax;              //Begrenzung des Wertebereichs
    }
    if (result==32){
      if (counter < cMax) counter++;
      else counter = cMin;              //Begrenzung des Wertebereichs
    }
    Serial.println(counter);
  }
}

void setup() {
  Serial.begin(9600);
  attachInterrupt(4, encoder, CHANGE);
  attachInterrupt(5, encoder, CHANGE);
  if (!musicPlayer.begin()){
    Serial.println("VS1053 not found");
    while (1);  // don't do anything more
  }
  if (!sd.begin(chipSelect, SPI_HALF_SPEED)) {       // initialise the music player
    sd.initErrorHalt();
  }
  for (byte i = cMin; i <= cMax; i++)
  {
    numberOfFiles[i]=countFiles(i);
    Serial.println(numberOfFiles[i]-1);
  }
      // If DREQ is on an interrupt pin (on uno, #2 or #3) we can do background audio playing
  musicPlayer.useInterrupt(VS1053_FILEPLAYER_PIN_INT);  // DREQ int
  musicPlayer.sineTest(0x44, 100);                      // Make a tone to indicate VS1053 is working 
  if (!SD.begin(CARDCS)) {
    Serial.println(F("SD failed, or not present"));
    while (1);  // don't do anything more
  } 
  if (! musicPlayer.useInterrupt(VS1053_FILEPLAYER_PIN_INT))
  Serial.println(F("DREQ pin is not an interrupt pin"));
  lcd.init();
  lcd.backlight();
}

unsigned int countFiles(int index){
  int fileCount = 0;
  char dirName[8];
  sprintf(dirName,"%02i",index);
  Serial.print(dirName);
  Serial.print(" / ");
  sd.chdir(dirName);
  sd.vwd()->rewind(); 
  while (file.openNext(sd.vwd(), O_READ)) {
    if (!file.isHidden()) {
      fileCount++;
    }
    file.close();
  }  
  sd.chdir("/");
  return fileCount;
}

void readFileToVars(char* fn){
  byte i,feld;
  char c;
  sd.chdir("/");
  ifstream file(fn);
  if (!file.is_open()){
    sd.errorHalt("File open failed");
  }
  else{
  i=0;feld=0;
  while ((c = file.get()) >= 0)
  {
    switch(c){              //zeichen werden zusammengesetzt
      case '\r': break;
      case ';' : {          //Trennzeichen
        feld++;
        i=0;
        break;
      }   
    default:
      if (c>=32){
        text[feld][i]=c;
        i++;
      }
    }
  }
  }   
  file.close();
}

void displayChange(int num){
  lcd.clear();
  sprintf(vNum,"%02i",num);         //Zeichenkette wird formatiert
  path = strcat(vNum,fName);        //Pfad mit Dateiname zusammenfügen z.B. "04/mp3.txt"

  readFileToVars(path);   
 
  for (int i=0;i<N;i++)             //Text wird in N Zeilen geschrieben
  {
    lcd.setCursor(0,i);             //Zeile wählen
    lcd.print(text[i]);            //Anzeige im Display
    Serial.println(text[i]);
    for (int j=0; j<17; ++j) {text[i][j] = 0; }   //lösche alten Inhalt
  }
  
}

void loop(){
  if (counter != lastCounter){        //Aktualisiere Anzeige wenn sich Zähler ändert
    displayChange(counter);  
    lastCounter=counter;
  }
  pressedButton = getPressedButton();
  delay(100);
  if (pressedButton != 0){
    Serial.print("Taste: ");
    Serial.println(pressedButton);
      checkButtons(pressedButton);
  }
}

void checkButtons(byte buttonNum)
{
  char* playFile;
  sprintf(vNum,"%02i",counter);
  playFile=strcat(vNum,"/1.mp3");
  Serial.print(playFile);
  switch(buttonNum){              //zeichen werden zusammengesetzt
    case 1: if (! musicPlayer.startPlayingFile(playFile)) {  //"02/1.mp3"
              Serial.println("Could not open track");
              //while (1);
            }
            //break;
    case 2: break;
  }   
}


byte getPressedButton()
{
    int buttonsPinValue = analogRead(analogButtonsPin);
    byte pressedButton = 0;
    char dirName[8];
    if (buttonsPinValue < 100) pressedButton = 1;
    return pressedButton;
}

Auf der SD Karte sind Verzeichnisse von 0 bis 6.
In jedem Verzeichnis sind mp3 Dateien 1…n und jeweils eine mp3.txt die den Namen des Albums enthält, der wiederum auf einem 16/2 Display angezeigt wird. Die Auswahl der Alben funkltioniert über einen Drehencoder.
Das alles funktionierte einwandfrei, bis ich die mp3 Abspielfunktion einbaute.
Jetzt gibt es oft Fehler beim laden der SD K arte, aber nicht immer.

Mein Vermutung ist folgende:
Während der musicplayer auf die Karte zugreift kann die Text-Datei nicht gelesen werden.

Lösung:
Alle mp3.txt zu beginn in eine chr Array laden.

Kann mal jemand schauen ob meine vermutung stimmt?

In der SD-Bibliothek lese ich: "Note that currently only one file can be open at a time." Das könnte die Quelle des Problems sein.