我正在用Arduino,Mp3播放器和LED矩陣構建一個花式鬧鐘,以顯示時間並作爲柔和的喚醒燈。我打算在完成後讓這個項目可以訪問和開源。我希望Arduino隨機選擇SD卡上的mp3文件並播放,直到歌曲結束,然後再選擇另一個,直到按下停止按鈕。但是我有一個隨機文件選擇的麻煩:SD上的Arduino隨機文件:rewindDirectory
,擁有一樣東西並不需要太多的內存我想了個辦法做選擇:
- 的MP3文件出現在的根文件夾在初始化期間使用
File::openNextFile()
對SD進行計數,直到它返回空對象。 - >int n_files
- 在1和n_files之間選擇一個隨機數。 - >
int rand_song
- 使用
File::openNextFile()
的循環打開rand_song文件,直到到達所需的文件(可能效率不高,但不管它是否需要幾秒鐘都沒關係)。 - >File chosen_rand
- 將
chosen_rand.name()
的名字改爲musicPlayer.startPlayingFile()
,讓歌曲播放。 - 回到1)如果歌曲結束時達到
所以第一個問題,你覺得是有意義的做這種方式?
然後,我做了上述算法的工作實現,缺少第4點(請參閱Code1)。但是當我添加startPlaying()
時,會出現問題:在選擇rand_song
文件的函數的兩次調用之間,即使調用File::rewindDirectory()
(參見代碼2),該位置也會保留。
這引出了我的第二個問題,使用File
,SD
和File::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);
}