Running SD and SdFat in the same project.

Well, I promised I would share my code after posing a problem in a different thread so here goes.

I needed to run both SD.h and SdFat.h in the same project. Namely, because I wanted to display long file names of wav files that are on an sd card, but also play them after. The issue is the audio and audiozero library only accepts filenames in the form of a FILE object which I found is tricky if you are using the SdFat library to get long filenames... So here is what I did.. I created an external class for SdFat and called it first to retrieve long filenames and return them as a String Array. So in my main code, I used SD.h to get short filenames (8.3) in a second string array so I could instantiate a FILE object to pass to the audio library.

Here it is > GitHub - rickyelqasem/DigiWavuino: Arduino WAV player for retro computer

It was a big learning curve for me as I'd never created libraries in CPP before.

Enjoy!

rickyelqasem:
Well, I promised I would share my code after posing a problem in a different thread so here goes.

Link.

I needed to run both SD.h and SdFat.h in the same project.

Yeah, no. Sorry to rain on your parade.

Who wants to load 2 copies of the same library?

... and then use the String class

... to hold all the filenames in RAM,

... in a dynamically-allocated array of 250 Strings?

Ick. Don't use String™. PaulS was trying to help you work through the real issue: AudioZero uses the old library, SD.

Your time would have been better spent updating AudioZero to use the new library, SdFat. SdFat has many bug fixes and performance improvements.

There is a problem calling sd.init twice, so I'm surprised that this even works for you.

Yeeaaahhh.... Well there's that old saying.. if it works, it works...Why add a load of complexity for myself when there is a workable solution?

Technically you are right that it would help if I put some effort into updating the AudioZero or SD library but I don't think I'm the right person to do that. BTW it would be the Audio library too (not just AudioZero) ...

Hey, thanks for your comments though and I will check out your feedback about Strings. I'm interested in what the alternative is. Is it merely creating an object?

rickyelqasem:
Why add a load of complexity for myself when there is a workable solution?

I haven't tried it, but I think all you had to do was change the "#include <SD.h>" to "#include <SdFat.h>".
IIRC, it seems like there is one different thing to get the filename from the directory object. PaulS was trying to lead you down that path. Instead, you kludged up a big steaming pile of "it works."

I'm interested in what the alternative is. Is it merely creating an object?

On a desktop, with an OS and virtual memory on an external hard drive, sure! Instantiate all you want! Be sure to reboot once per day.

In an embedded environment, only read one filename at a time. Read another when you're ready for the next one. Don't store them all in RAM.

Filenames can be very efficiently stored in RAM with a plain old C string (note the lowercase "s"). These are just char arrays. Both SD libraries provide C string filenames, but your code converted them to the wasteful String objects. :frowning:

I actually found someone on GitHub who by the looks of it tried to change the AudioZero library to just include SdFat but I'm not sure he actually got it working because when I tried it failed.

The reason I stored them in RAM is speed. If I had to grab the next one from the SD card it could add a lag to the operation. But in hindsight maybe you are right because I now see a similar project took that same approach.

And another thing I could do to improve my code is using an interrupt for the scrolling display... but that is why we have GitHub.

another thing I could do to improve my code is using an interrupt for the scrolling display

Unfortunately, you cannot do anything in an interrupt routine that requires interrupts... like scrolling the display. :frowning:

Instead, use millis() to constantly check if the required time has elapsed. See the examples for "blink without delay" and "using millis () guide".

If the library doesn't return until the entire file has played, you can modify it to not "block" like that. There are several ways to do that.

Thanks, will check it when I go for a 1.1.. thx again.