Thanks to your great support help, I was able to get the MP3 music player shield working well. The sd Card has 9 files labeled track001.mp3 through track009.mp3. I have a PIR connected to digital I/O pin 3. When motion is detected the music maker will select and play a random file. I noticed something unusual in that while there is no file labeled System~1/, the card attempts to play it. This causes the listener to think it stopped working although the loop is fast enough to see motion and play another file. While I can live with this, I'm curious as to where this file is coming from. With random file selection, it's possible that System~1/ will play twice in a row.
Is this a library issue or is it a sketch programming error?
Note that I was careful to set windows to view hidden files and extensions when exploring the files on the sd card.
See sketch and monitor screen capture.
thanks,
Nick
MusicMaker trys to play System~1/ file
Moderators: adafruit_support_bill, adafruit
Please be positive and constructive with your questions and comments.
- nickmart1
- Posts: 16
- Joined: Thu Apr 07, 2022 12:14 pm
MusicMaker trys to play System~1/ file
- Attachments
-
- screen shot of serial monitor
- Screenshot 2022-04-19 171532.jpg (138.36 KiB) Viewed 428 times
-
- final code_working.txt
- Working sketch
- (5.06 KiB) Downloaded 12 times
- nickmart1
- Posts: 16
- Joined: Thu Apr 07, 2022 12:14 pm
Re: MusicMaker trys to play System~1/ file
Hi again,nickmart1 wrote:Thanks to your great support help, I was able to get the MP3 music player shield working well. The sd Card has 9 files labeled track001.mp3 through track009.mp3. I have a PIR connected to digital I/O pin 3. When motion is detected the music maker will select and play a random file. I noticed something unusual in that while there is no file labeled System~1/, the card attempts to play it. This causes the listener to think it stopped working although the loop is fast enough to see motion and play another file. While I can live with this, I'm curious as to where this file is coming from. With random file selection, it's possible that System~1/ will play twice in a row.
Is this a library issue or is it a sketch programming error?
Note that I was careful to set windows to view hidden files and extensions when exploring the files on the sd card.
See sketch and monitor screen capture.
thanks,
Nick
I have not seen a reply to this issue. Any ideas why I'm seeing a file playing called System~1/? The PIR is connected to digital I/O pin 2, not pin 3.
Thanks,
Nick
- neradoc
- Posts: 542
- Joined: Wed Apr 27, 2016 2:38 pm
Re: MusicMaker trys to play System~1/ file
Hi, SYSTEM~1 is how systems that can only understand 8 characters file names (old DOS for example) show "long" character names.
I would think it is "System Volume Information", and your "chooseRandomFile" function doesn't know to ignore it.
You could change that function to test "entry.isDirectory()" and skip the entry.
Or test for files ending in "MP3" and other allowed file formats and ignore the rest.
"System Volume Information" might be completely hidden by windows, according to some results on the web, which is why you can't see it.
https://www.minitool.com/lib/system-vol ... ation.html
I would think it is "System Volume Information", and your "chooseRandomFile" function doesn't know to ignore it.
You could change that function to test "entry.isDirectory()" and skip the entry.
Or test for files ending in "MP3" and other allowed file formats and ignore the rest.
"System Volume Information" might be completely hidden by windows, according to some results on the web, which is why you can't see it.
https://www.minitool.com/lib/system-vol ... ation.html
- nickmart1
- Posts: 16
- Joined: Thu Apr 07, 2022 12:14 pm
Re: MusicMaker trys to play System~1/ file
Thanks. That makes perfect sense. I had thought changing windows to view all hidden files and extensions would reveal it.
Nick
Nick
- nickmart1
- Posts: 16
- Joined: Thu Apr 07, 2022 12:14 pm
Re: MusicMaker trys to play System~1/ file
OK,
I tried changing the SD directory from "/" to "/MP3/" and moved all the mp3 files into the subdirectory /MP3? on the SD card. The program found the files ok but now the PIR function quit working. Do I need to add the subdirectory somewhere else?
thanks,
Nick
I tried changing the SD directory from "/" to "/MP3/" and moved all the mp3 files into the subdirectory /MP3? on the SD card. The program found the files ok but now the PIR function quit working. Do I need to add the subdirectory somewhere else?
thanks,
Nick
- neradoc
- Posts: 542
- Joined: Wed Apr 27, 2016 2:38 pm
Re: MusicMaker trys to play System~1/ file
Hi, did you figure it out ?nickmart1 wrote:OK,
I tried changing the SD directory from "/" to "/MP3/" and moved all the mp3 files into the subdirectory /MP3? on the SD card. The program found the files ok but now the PIR function quit working. Do I need to add the subdirectory somewhere else?
thanks,
Nick
Without seeing your new code, maybe the issue is that the "chooseRandomFile" function returns the name of the file that you then pass to "musicPlayer.startPlayingFile".
If it takes file paths, I think you need to prefix it with the directory name. Like "/MP3/" (with dir.name). Watch the size of your outFileName buffer.
- nickmart1
- Posts: 16
- Joined: Thu Apr 07, 2022 12:14 pm
Re: MusicMaker trys to play System~1/ file
I'm not sure I understand your suggestion. I did add the following code in an attempt to get around the problem.:
[
Where do I find the outFileName buffer size? I only have 9 mp3 files.
Here is the entire code using a directory on the sd card called \MP3\ I can see the files being read in the monitor but the PIR doesn't seem to trigger the files any longer. This is weird since I didn't change this part of the code. I should see "motion detected" in the serial monitor but I don't.
I'm thinking it might be easier to abandon the subdirectory \MP3\ and simply to test for System~1 so it will not try to play. If so, can you give me a code suggestion for that?
Here is the entire code with the changes to \MP3\. Again, somehow, I broke the pir detection.
Code: Select all
if (pirState == LOW) { // we have just turned on
char fullName[20] = "/MP3/";
strcat(fullName, MP3);
(! musicPlayer.startPlayingFile(MP3));
Serial.println("Motion detected!");
// We only want to print on the output change, not state
pirState = HIGH;
}
Where do I find the outFileName buffer size? I only have 9 mp3 files.
Here is the entire code using a directory on the sd card called \MP3\ I can see the files being read in the monitor but the PIR doesn't seem to trigger the files any longer. This is weird since I didn't change this part of the code. I should see "motion detected" in the serial monitor but I don't.
I'm thinking it might be easier to abandon the subdirectory \MP3\ and simply to test for System~1 so it will not try to play. If so, can you give me a code suggestion for that?
Here is the entire code with the changes to \MP3\. Again, somehow, I broke the pir detection.
Code: Select all
// include SPI, MP3 and SD libraries
#include <SPI.h>
#include <Adafruit_VS1053.h>
#include <SD.h>
//////////////////////////////////////////////////////////////////////////////////////////////////////
// These are the pins used for the music maker shield
#define SHIELD_RESET -1 // VS1053 reset pin (unused!)
#define SHIELD_CS 7 // VS1053 chip select pin (output)
#define SHIELD_DCS 6 // VS1053 Data/command select pin (output)
// These are common pins between breakout and shield
#define CARDCS 4 // Card chip select pin
// DREQ should be an Int pin, see http://arduino.cc/en/Reference/attachInterrupt
#define DREQ 3 // VS1053 Data request, ideally an Interrupt pin
Adafruit_VS1053_FilePlayer musicPlayer =
Adafruit_VS1053_FilePlayer(SHIELD_RESET, SHIELD_CS, SHIELD_DCS, DREQ, CARDCS);
// Setup PIR sensor
int ledPin = 13; // choose the pin for the LED
int inputPin = 2; // choose the input pin (for PIR sensor)
int pirState = LOW; // we start, assuming no motion detected
int val = 0; // variable for reading the pin status
void setup() {
Serial.begin(9600); //initialize the serial monitor
pinMode(ledPin, OUTPUT); // declare LED as output
pinMode(inputPin, INPUT); // declare sensor as input
//////////////////////////////////////////////////////////////////////////////////////////////////////
uint32_t seed = 0; // Generate random seed start
for ( uint8_t i = 10 ; i ; i-- ) {
seed = ( seed << 5 ) + ( analogRead( 0 ) * 3 );
}
randomSeed( seed ); //set random seed
//
Serial.println("Adafruit VS1053 Library Test");
Serial.print("RandomSeed value = ");
Serial.println(seed);
// initialise the music player
if (! musicPlayer.begin()) { // initialise the music player
Serial.println(F("Couldn't find VS1053, do you have the right pins defined?"));
while (1);
}
Serial.println(F("VS1053 found"));
musicPlayer.sineTest(0x44, 500); // 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
}
Serial.println("SD OK!");
// list files
printDirectory(SD.open("/MP3/"), 0);
// Set volume for left, right channels. lower numbers == louder volume!
musicPlayer.setVolume(1, 1);
if (! musicPlayer.useInterrupt(VS1053_FILEPLAYER_PIN_INT))
Serial.println(F("DREQ pin is not an interrupt pin"));
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
void loop() {
// put your main code here, to run repeatedly:
char MP3[15]; // Allocate some room
File dir = SD.open("/MP3/"); //Root Directory
chooseRandomFile(dir, MP3); 6763;
dir.close();
delay(200);
// Read pirState to Start/Stop playing a file.
val = digitalRead(inputPin); // read input value
if (val == HIGH) { // check if the input is HIGH
digitalWrite(ledPin, HIGH); // turn LED ON
if (pirState == LOW) { // we have just turned on
char fullName[20] = "/MP3/";
strcat(fullName, MP3);
(! musicPlayer.startPlayingFile(MP3));
Serial.println("Motion detected!");
// We only want to print on the output change, not state
pirState = HIGH;
}
} else {
digitalWrite(ledPin, LOW); // turn LED OFF
if (pirState == HIGH) { // we have just turned off
Serial.println("Motion ended!");
// We only want to print on the output change, not state
pirState = LOW;
}
// if (! musicPlayer.startPlayingFile(MP3)) {
// Serial.println("Could not open file: ");
// Serial.println(MP3);
}
Serial.print(F("Now playing "));
Serial.println(MP3);
while (musicPlayer.playingMusic) {
delay( 1000 );
}
Serial.print("Done playing: ");
Serial.println(MP3);
Serial.println();
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// File listing helper
void printDirectory(File dir, int numTabs) {
while (true) {
File entry = dir.openNextFile();
if (! entry) {
// no more files
//Serial.println("**nomorefiles**");
break;
}
for (uint8_t i = 0; i < numTabs; i++) {
Serial.print('\t');
}
Serial.print(entry.name());
if (entry.isDirectory()) {
Serial.println("/");
printDirectory(entry, numTabs + 1);
} else {
// files have sizes, directories do not
Serial.print("\t\t");
Serial.println(entry.size(), DEC);
}
entry.close();
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// Function to select random mp3
void chooseRandomFile( File dir, char* outFileName) {
File entry, result;
int count = 1;
dir.rewindDirectory();
while ( entry = dir.openNextFile() ) {
if ( random( count ) == 0 ) {
if (result ) {
result.close();
}
result = entry;
} else {
entry.close();
}
count++;
}
strcpy(outFileName, result.name());
result.close();
}
- neradoc
- Posts: 542
- Joined: Wed Apr 27, 2016 2:38 pm
Re: MusicMaker trys to play System~1/ file
I meant increasing the buffer passed to "chooseRandomFile" so that the function would do the strcat and return the full path.
But the way you did it is fine too, except that you have a little error, you are not using fullName:
You want to change musicPlayer.startPlayingFile(MP3) to musicPlayer.startPlayingFile(fullName).
Not sure why you are not seeing serial output. What if you print the file name before trying to play it ? Check you didn't bump your sensor's connection.
I remembered I have a MusicMaker featherwing and ran your code on a feather M0, with the fix (and the pins for the M0).
The code runs and seems to do what it's supposed to do (I have no speakers connected but I see it say that it's playing for the correct duration). I made a few modifications, in particular skipping files smaller than 8kB to skip any system files that MacOS tends to leave around sometimes. (I simulated the input with a wire).
But the way you did it is fine too, except that you have a little error, you are not using fullName:
You want to change musicPlayer.startPlayingFile(MP3) to musicPlayer.startPlayingFile(fullName).
Not sure why you are not seeing serial output. What if you print the file name before trying to play it ? Check you didn't bump your sensor's connection.
I remembered I have a MusicMaker featherwing and ran your code on a feather M0, with the fix (and the pins for the M0).
The code runs and seems to do what it's supposed to do (I have no speakers connected but I see it say that it's playing for the correct duration). I made a few modifications, in particular skipping files smaller than 8kB to skip any system files that MacOS tends to leave around sometimes. (I simulated the input with a wire).
- nickmart1
- Posts: 16
- Joined: Thu Apr 07, 2022 12:14 pm
Re: MusicMaker trys to play System~1/ file
Thanks so much Neradoc. I changed to musicPlayer.startPlayingFile(fullName). That worked great. Now working and not playing System~1 file.
Nickmart1
Nickmart1
Please be positive and constructive with your questions and comments.