I am in serious need for help here. I have a rather small function that get's the number of files from within a given directory. Now, the directory name (that is the path) is stored in a char array within my main loop.
My problem is, I have no idea how to pass this char array to my function.
This is my code (it's of course just a subset but it's the part that is obviously wrong) and you can also see the complete program at the end:
In the setup() routine I define my current working directory:
char plrCurrentFolder[9];
In the main loop I want to get the number of files of a given directory (in the final program this directory name will come from an NFC tag):
String temp = "findorie";
temp.toCharArray(plrCurrentFolder, 9);
unsigned int numberOfFiles = countFiles(plrCurrentFolder);
This is the function to return the number of files:
unsigned int countFiles(File dir){
unsigned int counter = 0;
while (true){
File entry = dir.openNextFile();
if (!entry){
// no more files
break;
}
counter++;
entry.close();
}
dir.close();
return counter;
}
To be honest I have two issues with this. First, I don't really like to create a temp String variable to create the char array here as I would rather stick with the char array in itself to safe on memory and maybe this would also aid in performance (although I'm not sure about that).
Second, The way this whole thing is structured right now, it simply doesn't work. When building, the compiler correctly complains:
exit status 1
could not convert '(char*)(& plrCurrentFolder)' from 'char*' to 'SDLib::File'
Can anyone help me out and give me a code snippet how to make this work???
Kind regards to all,
Christian
--- below you may find the complete code as of now ---
/*
* Fairytale Main program
*
* This programm will read an nfc tag. It will check for a directory name and optional a filename
* and start playing this on the music maker shield.
*
* Restrictions:
* 1. All filenames mus be in the format trackXXX.mp3 - where XXX is a numbering from 001 to 999
* 2. All directory names must be exactly 8 chars long
*
*/
// make sure to change this to 0 before uploading in production as it turns on lots and lots of serial messages
#define DEBUG 1
// we only show light effects, in case this is set to 1
#define LIGHTEFFECTS 0
// we only use the nfc reader if this is set to 1
#define NFCREADER 0
//
// setup 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)
#define CLK 13 // SPI Clock, shared with SD card
#define MISO 12 // Input data, from VS1053/SD card
#define MOSI 11 // Output data, to VS1053/SD card
// 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 =
// create shield-example object!
Adafruit_VS1053_FilePlayer(SHIELD_RESET, SHIELD_CS, SHIELD_DCS, DREQ, CARDCS);
//
// setup NFC Adapter
//
#ifdef NFCREADER
/*
#include <PN532_SPI.h>
#include <PN532.h>
#include <NfcAdapter.h>
#define PN532_SCK (13) //changed from pin 2
#define PN532_MISO (12) //changed from pin 5
#define PN532_MOSI (11) //changed from pin 3
#define PN532_SS (10) //changed from 4
PN532_SPI pn532spi(SPI, PN532_SS);
NfcAdapter nfc = NfcAdapter(pn532spi);
*/
#endif
// these variables are used for the light effects
int lightValue1, lightValue2, lightValue3;
const int redPin = 7;
const int greenPin = 8;
const int bluePin = 9;
// these are timing counters for the light effects
long time=0;
int periode = 20000;
int displace = 500;
// uptime counters
unsigned int runCounter = 0;
unsigned long startUpTime = 0;
const unsigned long maxUpTime = 120000; // 1800000L; // 30 Minutes
// these are variables for the nfc card
boolean cardScanned = false; // did we already scan the card?? using this to suppress reading in the card data while it is on the reader
char cardId[16]; // the uid of the card as read in through the nfc reader
// mp3 player variables
boolean plrIsPlaying = false; // is the mp3 player already playing?
char plrCurrentFile[13]; // which track is the player playing?
char plrNextFile[13]; // which track is the player playing?
char plrPrevFile[13]; // which track is the player playing?
char plrCurrentFolder[9]; // which directory is the player playing?
uint8_t plrCurrentPosition = 0; // on which position in seconds are we in the current track?
char currentTrackFileName[] = "/system/current.txt"; // a file we might use to store the last played track
// volume control variables for the analog poti
int volumePotPin = A0; // the analog input pin that we use for the potentiometer
int sensorDrift = 7; // difference to last received sensor value that must be exceeded to activate a change in the volume
int compareValue = 0; // just a convenience variable to make comparison easier
int sensorValue = 0; // read the value from the potentiometer
int lastSensorValue = 0; // keeps the last read sensor value
uint8_t soundVolume = 0; // the sound volume is derived via a map function from the sensor value
// other button settings
int btnLinePin = A1; // pin on which the button line (4 buttons) is connected
int btnVal = 0;
// these are the prototypes for the nfc card reader
void getNfcCardData();
// these are the prototypes for the mp3 player controller
uint8_t getVolume(void); // function that returns the volume setting based on the analog read
char plrNext(void); // play next file in album
char plrPrev(void); // play previous file in album
void plrPlayTrack(char, char); // play a single track
void setupSound(void); // initializes the sound system and plays the startup sound
// these are the prototypes to work on files
void printDirectory(File, int); // print out the content of specified directory on serial console
unsigned int countFiles(File); // return the number of files in a directory passed as a File descriptor
//unsigned int countFiles(char[]); // return the number of files in a directory passed as a File descriptor
// these are the prototypes for the light effects
void fader(void);
void startuplight(void);
void highlight(int);
void flash(int);
void pulse(int);
void setup() {
#ifdef DEBUG
Serial.begin(115200);
#endif
plrCurrentFile[0] = 0; // we initialize the fiirst element of the array to 0 to later check if a current file was given.
// initialise the music player
if (! musicPlayer.begin()) { // initialise the music player
#ifdef DEBUG
Serial.println(F("Couldn't find VS1053, do you have the right pins defined?"));
#endif
while (1);
}
#ifdef DEBUG
Serial.println(F("Music Maker Shield VS1053 found"));
#endif
//musicPlayer.sineTest(0x44, 500); // Make a tone to indicate VS1053 is working
if (!SD.begin(CARDCS)) {
#ifdef DEBUG
Serial.println(F("failed to detect the SD-Card"));
#endif
while (1); // don't do anything more
}
#ifdef DEBUG
Serial.println("SD found and operational");
#endif
// set the buttons as input
pinMode(volumePotPin, INPUT);
pinMode(btnLinePin, INPUT);
// setup music maker shield and start playing startup file
setupSound();
#ifdef DEBUG
// list files
printDirectory(SD.open("/"), 0);
#endif
/*
// now as the last thing, start the nfc reader
#ifdef DEBUG
Serial.print("initializing NFC TAG reader ... ");
#endif
nfc.begin();
delay(1000); // wait some time for
*/
// check our current time, so we know when to stop
startUpTime = millis();
#ifdef DEBUG
Serial.println("we are up and running and ready to play audio");
#endif
}
//
// LL OOOOOO OOOOOO PPPPPPP
// LL OO OO OO OO PP PP
// LL OO OO OO OO PP PP
// LL OO OO OO OO PPPPPP
// LLLLLL OOOOOO OOOOOO PP
void loop() {
#ifdef LIGHTEFFECTS
// turn off all the lights. we only want to have fading lights, while the playr is active
//analogWrite(redPin, 0);
//analogWrite(greenPin, 0);
//analogWrite(bluePin, 0);
#endif
// NFC Tag reader functions
// now we only do this, when an nfc tag is present
/*
if (nfc.tagPresent()){
Serial.println("NFC tag Found!\n");
NfcTag tag = nfc.read();
Serial.print("Tag Type: ");
Serial.println(tag.getTagType());
Serial.print("UID: ");
Serial.println(tag.getUidString());
getNfcCardData();
*/
String temp = "findorie";
temp.toCharArray(plrCurrentFolder, 9);
// now let's get the number of files in the album directory
//unsigned int numberOfFiles = 0;
unsigned int numberOfFiles = countFiles(plrCurrentFolder);
#ifdef DEBUG
Serial.print("Directory ");Serial.print(plrCurrentFolder);Serial.print(" contains ");Serial.print(numberOfFiles);Serial.println(" files");
#endif
// if we did not get the current file from the tag, we are hardcoding it to track001.mp3
if ((plrCurrentFile[0] == 0)) {
temp = "track001.mp3";
temp.toCharArray(plrCurrentFile, 13);
}
#ifdef DEBUG
Serial.print("currentFolder holds: ");Serial.print(plrCurrentFolder);Serial.print(" / currentFile contains: ");Serial.print(plrCurrentFile);
#endif
temp = "/";
temp.concat(plrCurrentFolder);
temp.concat("/");
temp.concat(plrCurrentFile);
char filename[temp.length() + 1];
temp.toCharArray(filename, sizeof(filename));
Serial.print(" / filename contains: ");Serial.println(filename);
if (SD.exists(filename)) {
Serial.print(filename);Serial.println(" exists.");
// mp3 player functions playback
// Start playing a file, then we can do stuff while waiting for it to finish
if (! musicPlayer.startPlayingFile(filename)) {
#ifdef DEBUG
Serial.print("Could not open file ");Serial.println(filename);
#endif
while (1);
}
#ifdef DEBUG
Serial.print(F("Start playing "));Serial.println(filename);
#endif
while (musicPlayer.playingMusic) {
// file is now playing in the 'background' so now's a good time
// to do something else like handling LEDs or buttons :)
// play some nice light effects, if wanted
#ifdef LIGHTEFFECTS
//fader();
#endif
// volume control functions
// read the input on analog pin 0 and check if we have a change in volume.
sensorValue = analogRead(volumePotPin);
if (lastSensorValue > sensorValue) {compareValue = lastSensorValue - sensorValue;} else {compareValue = sensorValue - lastSensorValue;}
// If we have a high enough difference in the sensor reading, calculate it so we may set it on the player
if (compareValue > sensorDrift){
#ifdef DEBUG
Serial.print("changing volume: ");
#endif
soundVolume = getVolume();
musicPlayer.setVolume(soundVolume,soundVolume);
}
}
#ifdef DEBUG
Serial.println("Done playing ");Serial.println(filename);
#endif
#ifdef LIGHTEFFECTS
//startuplight();
#endif
} else {
Serial.print(filename);Serial.println(" does not exist.");
} // end of file does not exist
//} // end of tag found
} // end of loop
//
// NN NN FFFFFF CCCCCC
// NNNN NN FF CC
// NN N NN FFFF CC
// NN NNNN FF CC
// NN NN FF CCCCCC
// BELOW THIS LINE THE NFC CONTROL IS DEFINED
//
void getNfcCardData(){
/*
NfcTag tag = nfc.read();
boolean usableContent = false;
if (tag.hasNdefMessage()){
NdefMessage message = tag.getNdefMessage();
// If you have more than 1 Message then it wil cycle through them
int recordCount = message.getRecordCount();
for (int i = 0; i < recordCount; i++) {
NdefRecord record = message.getRecord(i);
int payloadLength = record.getPayloadLength();
byte payload[payloadLength];
record.getPayload(payload);
String payloadAsString = ""; // Processes the message as a string vs as a HEX value
for (int c = 0; c < payloadLength; c++) {
payloadAsString += (char)payload[c];
}
String cleanString = payloadAsString;
cleanString.remove(0,3);
#ifdef DEBUG
Serial.print("content element "); Serial.print(i); Serial.print(": "); Serial.println(cleanString);
#endif
// now populate the vars for the player
int spacePosition = cleanString.indexOf(':');
if (cleanString.charAt(spacePosition - 1) == 'A') {
String contentString = cleanString.substring(3);
#ifdef DEBUG
Serial.print("Album info: ");Serial.println(contentString);
#endif
}
if (cleanString.charAt(spacePosition - 1) == 'D') {
usableContent = true;
String contentString = cleanString.substring(3);
plrCurrentFolder = contentString;
#ifdef DEBUG
Serial.print("Directory: ");Serial.println(contentString);
#endif
}
if (cleanString.charAt(spacePosition - 1) == 'T') {
String contentString = cleanString.substring(3);
plrCurrentFile = contentString;
#ifdef DEBUG
Serial.print("Track: ");Serial.println(contentString);
#endif
}
if (cleanString.charAt(spacePosition - 1) == 'P') {
String contentString = cleanString.substring(3);
plrCurrentPosition = contentString.toInt();
#ifdef DEBUG
Serial.print("Position: ");Serial.println(contentString);
#endif
}
String uid = record.getId();
if (uid != "") {
#ifdef DEBUG
Serial.print(" ID: ");
Serial.println(uid);
#endif
}
}
if (!usableContent){
#ifdef DEBUG
Serial.println("THIS CARD DOES NOT HAVE THE NECESSARY MESSAGES FOR THE MP3 PLAYER");
#endif
}
} else { // does the card have NDEF messages?
#ifdef DEBUG
Serial.println("THIS CARD DOES NOT HAVE MESSAGES AT ALL - NOT USABLE FOR THE MP3 PLAYER");
#endif
}
*/
}
//
// MM MM PPPPPP 33333
// MMMM MMMM PP PP 33
// MM MM MM PP PP 3333
// MM MM PPPPPP 33
// MM MM PP 33333
// BELOW THIS LINE THE MP3 PLAYER CONTROL IS DEFINED
//
uint8_t getVolume(){
soundVolume = map(sensorValue, 0, 1023, 0, 100); // map the sensor value to a sound volume
#ifdef DEBUG
Serial.print("last sensor value (if any) was ");Serial.print(lastSensorValue);Serial.print(" / new sensor value is ");Serial.print(sensorValue);Serial.print(" which is a volume of ");Serial.println(soundVolume);
#endif
lastSensorValue = sensorValue;
return (soundVolume);
}
void plrPlayTrack(char dir, char file) {
String temp = "/";
temp.concat(dir);
temp.concat("/");
temp.concat(file);
char myFile[temp.length() + 1];
temp.toCharArray(myFile, sizeof(myFile));
// mp3 player functions playback
// Start playing a file, then we can do stuff while waiting for it to finish
if (! musicPlayer.startPlayingFile(myFile)) {
#ifdef DEBUG
Serial.print("Could not open file ");Serial.println(myFile);
#endif
while (1);
}
#ifdef DEBUG
Serial.print(F("Start playing "));Serial.println(myFile);
#endif
while (musicPlayer.playingMusic) {
// file is now playing in the 'background' so now's a good time
// to do something else like handling LEDs or buttons :)
#ifdef DEBUG
Serial.print(".");
#endif
#ifdef LIGHTEFFECTS
//fader();
#endif
}
#ifdef DEBUG
Serial.println("Done playing ");Serial.println(myFile);
#endif
}
char plrNext(void){
char track[12] = "track003.mp3";
#ifdef DEBUG
Serial.println("plrNext toggled");
#endif
#ifdef LIGHTEFFECTS
//pulse(bluePin);
#endif
return track;
}
char plrPrev(void){
char track[12] = "track001.mp3";
#ifdef DEBUG
Serial.println("plrPrevious toggled");
#endif
#ifdef LIGHTEFFECTS
//pulse(greenPin);
#endif
return track;
}
void setupSound(){
// This option uses a pin interrupt. No timers required! But DREQ
// must be on an interrupt pin. For Uno/Duemilanove/Diecimilla
// that's Digital #2 or #3
// See http://arduino.cc/en/Reference/attachInterrupt for other pins
// *** This method is preferred
if (! musicPlayer.useInterrupt(VS1053_FILEPLAYER_PIN_INT)) {
#ifdef DEBUG
Serial.println(F("DREQ pin is not an interrupt pin"));
#endif
while (1);
}
// Start playing a file, then we can do stuff while waiting for it to finish
if (! musicPlayer.startPlayingFile("hello.mp3")) {
#ifdef DEBUG
Serial.println("Could not open file hello.mp3");
#endif
} else {
#ifdef DEBUG
Serial.print("playing welcome file hello.mp3 ");
#endif
}
// now we play the welcome sound
startUpTime = millis();
while (musicPlayer.playingMusic) {
if (millis() - startUpTime > 500) {
#ifdef DEBUG
Serial.print(".");
#endif
startUpTime = millis();
}
// file is now playing in the 'background' so now's a good time
// to do something else like handling LEDs or buttons :)
#ifdef LIGHTEFFECTS
//startuplight();
#endif
}
#ifdef DEBUG
Serial.println(" done");
#endif
getVolume();
musicPlayer.setVolume(soundVolume,soundVolume);
}
//
// FFFFFF II LL EEEEEE
// FF II LL EE
// FFFF II LL EEEE
// FF II LL EE
// FF II LLLLLL EEEEEE
// BELOW THIS LINE THE FILE HELPER FUNCTIONS CAN BE FOUND
//
// counts the number of files in directory
//unsigned int countFiles(char dir[]){
unsigned int countFiles(File dir){
unsigned int counter = 0;
while (true){
File entry = dir.openNextFile();
if (!entry){
// no more files
break;
}
counter++;
entry.close();
}
dir.close();
return counter;
}
// store last played track
void rememberCurrentTrack(){
}
// read last played track
void getLastPlayedTrack(){
}
// 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();
}
}
//
// LL EEEEEE DDDDDD
// LL EE DD DD
// LL EEEE DD DD
// LL EE DD DD
// LLLLLL EEEEEE DDDDDD
// BELOW THIS LINE THE LIGHT EFFECTS ARE DEFINED
//
// fading organically
void fader(){
time = millis();
lightValue1 = 128+127*cos(2*PI/periode*time);
lightValue2 = 128+127*cos(2*PI/periode*(displace-time));
lightValue3 = 128+127*cos(2*PI/periode*(2*displace-time));
analogWrite(redPin, lightValue1); // sets the value (range from 0 to 255)
analogWrite(greenPin, lightValue2); // sets the value (range from 0 to 255)
analogWrite(bluePin, lightValue3); // sets the value (range from 0 to 255)
}
// illuminate the 3 led with some fancy lightning during startup
void startuplight(){
for (int i = 0; i<150; i++) {
analogWrite(redPin, i);
analogWrite(greenPin, i);
analogWrite(bluePin, i);
delay(10);
}
for (int i = 150; i>0; i--) {
analogWrite(redPin, i);
analogWrite(greenPin, i);
analogWrite(bluePin, i);
delay(10);
}
analogWrite(redPin, 0);
analogWrite(greenPin, 0);
analogWrite(bluePin, 0);
}
//turn on the desired pin for 5000 milliseconds
void highlight(int pin){
time = millis();
while (millis()<time+5000){
analogWrite(pin, 255);
}
analogWrite(pin, 0);
}
//turn on the desired pin for 5000 milliseconds
void flash(int pin){
time = millis();
while (millis()<time+1000){
analogWrite(pin, 255);
}
analogWrite(pin, 0);
}
//turn on the desired pin for 5000 milliseconds
void pulse(int pin){
for (int i=0;i<3;i++){
time = millis();
while (millis()<time+2500){
analogWrite(pin, 255);
}
analogWrite(pin, 0);
}
}