2014-09-23 84 views
0

我正在用Arduino,Mp3播放器和LED矩陣構建一個花式鬧鐘,以顯示時間並作爲柔和的喚醒燈。我打算在完成後讓這個項目可以訪問和開源。我希望Arduino隨機選擇SD卡上的mp3文件並播放,直到歌曲結束,然後再選擇另一個,直到按下停止按鈕。但是我有一個隨機文件選擇的麻煩:SD上的Arduino隨機文件:rewindDirectory

,擁有一樣東西並不需要太多的內存我想了個辦法做選擇:

  1. 的MP3文件出現在的根文件夾在初始化期間使用File::openNextFile()對SD進行計數,直到它返回空對象。 - >int n_files
  2. 在1和n_files之間選擇一個隨機數。 - >int rand_song
  3. 使用File::openNextFile()的循環打開rand_song文件,直到到達所需的文件(可能效率不高,但不管它是否需要幾秒鐘都沒關係)。 - >File chosen_rand
  4. chosen_rand.name()的名字改爲musicPlayer.startPlayingFile(),讓歌曲播放。
  5. 回到1)如果歌曲結束時達到

所以第一個問題,你覺得是有意義的做這種方式?

然後,我做了上述算法的工作實現,缺少第4點(請參閱Code1)。但是當我添加startPlaying()時,會出現問題:在選擇rand_song文件的函數的兩次調用之間,即使調用File::rewindDirectory()(參見代碼2),該位置也會保留。

這引出了我的第二個問題,使用File,SDFile::rewindDirectory在一起的正確方法是什麼?

我已經嘗試了幾個關閉文件的事情(因爲顯然當時只有一個必須打開)(請參閱Code3)。但總是相同的,它是爲第一個文件工作的,但由於倒帶不起作用,它從文件夾的中間開始,然後打到文件夾的末尾。

我希望我足夠準確,我不會錯過讓它工作的基本要素。

void setup() 
{ ... intializations done before 
    // Count the number of files 
    File folder = SD.open(music_folder); 
    n_files = countMP3File(folder); 
    folder.close(); 
    Serial.print("Number of MP3 files: "); Serial.println(n_files); 
} 

int countMP3File(File dir) 
{ 
    int counter = 0; 
    while(true) 
    { 
    File entry = dir.openNextFile(); 
    if (! entry) 
    { 
     dir.rewindDirectory(); 
     break; 
    } 
    Serial.println(entry.name()); 
    if(strstr(entry.name(), extansion) != NULL) 
     counter++; 

    entry.close(); 
    } 
    Serial.println("----------------"); 
    return counter; 
} 

File selectFileN(int number, File dir) 
{ 
    int counter = 0; 
    File return_entry; 
    while(true) 
    { 
    File entry = dir.openNextFile(); 
    if (! entry) 
    { 
     Serial.println("Last file reached"); 
     dir.rewindDirectory(); 
     break; 
    } 
    Serial.println(entry.name()); 
    if(strstr(entry.name(), extansion) != NULL) 
     counter++; 
    if(counter==number) 
    { 
     return_entry = entry; 
     dir.rewindDirectory(); 
     break; 
    } 
    entry.close(); 
    } 
    return return_entry; 
} 

代碼1(工作)

void loop() 
{ 
    int i, rand_song; 
    File folder = SD.open(music_folder); 
    File chosen_rand; 
    rand_song = random(0, n_files)+1; 
    Serial.print("Random number: "); Serial.println(rand_song); 
    chosen_rand = selectFileN(rand_song, folder); 
    if(chosen_rand) 
    Serial.print("Random file name: "); Serial.println(chosen_rand.name()); 
    folder.close(); 
    chosen_rand.close(); 
    Serial.print("playingMusic= "); Serial.println(musicPlayer.playingMusic); 
    Serial.println(); 
    Serial.println(); 
    delay(200); 
} 

代碼2(不工作)

void loop() 
{ 
    int i, rand_song; 
    File folder = SD.open(music_folder); 
    File chosen_rand; 
    rand_song = random(0, n_files)+1; 
    Serial.print("Random number: "); Serial.println(rand_song); 
    chosen_rand = selectFileN(rand_song, folder); 
    if(chosen_rand) 
    Serial.print("Random file name: "); Serial.println(chosen_rand.name()); 

    //Added code here 
    if(!musicPlayer.startPlayingFile(chosen_rand.name())) 
    { 
    Serial.println("Could not open mp3 file"); 
    } 
    else Serial.println("Stated playing!"); 
    //End added code 

    folder.close(); 
    chosen_rand.close(); 
    Serial.print("playingMusic= "); Serial.println(musicPlayer.playingMusic); 
    Serial.println(); 
    Serial.println(); 

    //Added code here 
    delay(2000); 
    musicPlayer.stopPlaying(); 
    //End added code 

    delay(200); 
} 

CODE3(不工作)

void loop() 
{ 
    int i, rand_song; 
    File folder = SD.open(music_folder); 
    File chosen_rand; 
    rand_song = random(0, n_files)+1; 
    Serial.print("Random number: "); Serial.println(rand_song); 
    chosen_rand = selectFileN(rand_song, folder); 
    if(chosen_rand) 
    Serial.print("Random file name: "); Serial.println(chosen_rand.name()); 

    //Added code to close file before playing it 
    char * namefile = (char*)malloc(15); 
    strcpy(namefile, chosen_rand.name()); 
    folder.close(); 
    chosen_rand.close();  
    //End added code 

    if(!musicPlayer.startPlayingFile(chosen_rand.name())) 
    { 
    Serial.println("Could not open mp3 file"); 
    } 
    else Serial.println("Stated playing!"); 

    free(namefile); 
    Serial.print("playingMusic= "); Serial.println(musicPlayer.playingMusic); 
    Serial.println(); 
    Serial.println(); 

    delay(2000); 
    musicPlayer.stopPlaying(); 

    delay(200); 
} 

回答

0

好吧,我發現了這個問題。由於只有一個SD卡的File應該一次打開,當音樂播放器打開該文件時,rewindDirectory失敗(我認爲,糾正我,如果我錯了,但我的測試讓我相信)。所以修復很簡單,只需在musicPlayer關閉文件之後放置rewindDirectory,這是一個很好的選擇,就在我選擇隨機文件的函數之前。

因此,這裏的工作循環:

void loop() 
{ 
    int i, rand_song; 
    File folder = SD.open(music_folder); 
    File random_file; 
    rand_song = random(0, n_files)+1; 
    Serial.print("Random number: "); Serial.println(rand_song); 
    folder.rewindDirectory(); 
    random_file = selectFileN(rand_song, folder); 
    folder.close(); 
    if(!musicPlayer.startPlayingFile(random_file.name())) 
    { 
    Serial.println("Could not open mp3 file"); 
    } 
    else Serial.println("Stated playing!"); 
    random_file.close(); 

    Serial.print("playingMusic= "); Serial.println(musicPlayer.playingMusic); 
    Serial.println(); 
    Serial.println(); 

    delay(2000); 
    musicPlayer.stopPlaying(); 
    delay(200); 
}