Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 25 of 25

Thread: How to use SdFat Library with Teensy 4.1 Built-In SD Slot

  1. #1

    How to use SdFat Library with Teensy 4.1 Built-In SD Slot

    Hi, does anyone have an example of how to use the SdFat library with the Teensy 4.1's built-in SD card slot? This is related to my last question, but I think this specific piece of information may be the key to getting my project working, so I thought it was worth a separate post.

    In the past I've just used the Teensy's SD.h library, and it has worked fine for everything I've wanted to do. Now however I need to use a library that is built around the SdFat library, so I need to switch over to that unless I want to rewrite a ton of library code.

    As far as I can tell, these libraries have extremely similar functionality, most of the difference being some small points of syntax, which is where I'm getting tripped up. The SdFat library has an example for Teensy, but frankly it's a convoluted mess, and I can't for the life of me tell what it's even attempting to demonstrate ��. A clear example for how to open the SD card on the Teensy 4.1 would be extremely helpful to me, and I think to others as well.

    TLDR: All I need to know is how to properly replicate the "SD.begin(BUILTIN_SDCARD)" function using the SdFat library, and the rest will fall into place. Can anyone share this one line of code?

  2. #2
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    13,751
    Update to TeensyDuino 1.54 Beta 6 - Job Done.

    It has replaced the SD.h CODE with SdFat ( Beta version 2.0.1 )

    That may not expose anything and everything ? But anything SD.h had AFAIK is mapped into SdFat - tremendous speed increase - and as possible mapping to work with SdFat should work.

    Find an issue and post it on the Beta thread.

    No idea what other question - not linked and since related quite possible this answer would have applied there if kept on that thread ...

  3. #3
    Senior Member
    Join Date
    Jul 2014
    Posts
    3,122
    Quote Originally Posted by defragster View Post
    Update to TeensyDuino 1.54 Beta 6 - Job Done.
    and use
    Code:
    SD.begin(BUILTIN_SDCARD);

  4. #4
    The begin function from the midi file library requires a pointer to the SdFat object. Trying to use the SD object throws an error, even when I updated to version 1.54 beta 6:

    Library definition of begin code:
    Code:
    void MD_MIDIFile::begin(SdFat *psd)
    {
      _sd = psd;
    }
    Here is some code showing how the error is generated.

    Code:
    #include <SD.h>
    #include <MD_MIDIFile.h>
    
    MD_MIDIFile SMF;
    
    void setup(){
      // Initialize SD
      if (!SD.begin(BUILTIN_SDCARD))
      {
        DEBUGS("\nSD init fail!");
        while (true) ;
      }
      // Initialize MIDIFile
      SMF.begin(&SD); // <<<< this line throws an error
      SMF.setMidiHandler(midiCallback);
      SMF.looping(true);
    }
    Here is the error:

    Code:
    MD_MIDIFile_Loop_TeensyBuiltin: In function 'void setup()':
    MD_MIDIFile_Loop_TeensyBuiltin:83: error: no matching function for call to 'MD_MIDIFile::begin(SDClass*)'
       SMF.begin(&SD);

  5. #5
    Any ideas what I can do to fix this or work around this?

    Is there a way I can get the built-in Teensy SD library to work with the Midi file library?

    Is there a way I can get the SDFat library to work with the Teensy 4.1's built-in SD slot?

  6. #6
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    23,994
    I'm not familiar with this MD_MIDIFile library. Can you give me a link?


    Quote Originally Posted by grinch View Post
    Any ideas what I can do to fix this or work around this?
    Yes, there is a workaround. But since this is beta, I'm imagining maybe adding a little code to make this nicer for you and everyone else in the future. That's why I'm asking for the link to the code you're using...

  7. #7
    Here is the midi file library: https://github.com/MajicDesigns/MD_MIDIFile

  8. #8
    Quote Originally Posted by PaulStoffregen View Post
    Yes, there is a workaround. But since this is beta, I'm imagining maybe adding a little code to make this nicer for you and everyone else in the future. That's why I'm asking for the link to the code you're using...
    What's the workaround?

  9. #9
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    23,994
    Try using this copy of SD.h (with 1.54-beta6, not 1.53). Put it in {Arduino}/hardware/teensy/avr/libraries/SD/src. On Windows, the default Arduino location is C:\Program Files (x86)\Arduino.

    Please let me know if this fully solves the problem? Will put it into 1.54-beta7 if it works....
    Attached Files Attached Files
    • File Type: h SD.h (6.2 KB, 10 views)

  10. #10
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    23,994
    FWIW, I got it to compile without error on this (based on msg #4). No way to know if it really works, as I'm not up to speed on using this library. Depending on you for that feedback.

    Code:
    #include <SD.h>
    #include <MD_MIDIFile.h>
    
    MD_MIDIFile SMF;
    
    void setup(){
      // Initialize SD
      if (!SD.begin(BUILTIN_SDCARD))
      {
        //DEBUGS("\nSD init fail!");
        while (true) ;
      }
      // Initialize MIDIFile
      SMF.begin(&(SD.sdfs)); // <<<< this line throws an error
      //SMF.setMidiHandler(midiCallback);
      SMF.looping(true);
    }
    
    void loop() {
    }

  11. #11
    Quote Originally Posted by PaulStoffregen View Post
    Try using this copy of SD.h (with 1.54-beta6, not 1.53). Put it in {Arduino}/hardware/teensy/avr/libraries/SD/src. On Windows, the default Arduino location is C:\Program Files (x86)\Arduino.

    Please let me know if this fully solves the problem? Will put it into 1.54-beta7 if it works....
    Okay, I'll try this. Do you know where I might be able to locate this folder on OSX? Is this folder inside the contents of the Teensy program itself (stuff revealed by right click > show package contents on Teensyduino icon), or is this a different application support folder?

  12. #12
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    23,994
    Yup, show package contents, then look for "hardware" inside Contents/Java.

    If you're on Catalina or Big Sur, changing any file will break the digital signature which Gatekeeper checks. Usually not a problem if you don't move Arduino anywhere else on your computer. But Apple is regularly tightening security with each update, so best to rename this copy before you edit so you'll later remember it's been edited and might trigger Apple security warnings in the future.

  13. #13
    Okay, I replaced SD.h in the location "Teensyduino.app/Contents/Java/hardware/teensy/avr/libraries/SD/src/SD.h" I'm still getting the same error when I try to compile. Tried restarting Teensyduino after changing out the file, but it didn't appear to make a difference. Anything else I should check?

    For reference here is the complete code I'm using to test this. Just modifying the MidiFileLoop example from the Midi File library to use the built-in SD lib in place of SD fat:

    Code:
    // Play a file from the SD card in looping mode, from the SD card.
    // Example program to demonstrate the use of the MIDFile library
    //
    // Hardware required:
    //  SD card interface - change SD_SELECT for SPI comms
    
    #include <SD.h>
    #include <MD_MIDIFile.h>
    
    #define USE_MIDI  1  // set to 1 for MIDI output, 0 for debug output
    
    #if USE_MIDI // set up for direct MIDI serial output
    
    #define DEBUGS(s)
    #define DEBUG(s, x)
    #define DEBUGX(s, x)
    #define SERIAL_RATE 31250
    
    #else // don't use MIDI to allow printing debug statements
    
    #define DEBUGS(s)     Serial.print(s)
    #define DEBUG(s, x)   { Serial.print(F(s)); Serial.print(x); }
    #define DEBUGX(s, x)  { Serial.print(F(s)); Serial.print(x, HEX); }
    #define SERIAL_RATE 57600
    
    #endif // USE_MIDI
    
    
    // SD chip select pin for SPI comms.
    // Arduino Ethernet shield, pin 4.
    // Default SD chip select is the SPI SS pin (10).
    // Other hardware will be different as documented for that hardware.
    const uint8_t SD_SELECT = 10;
    
    #define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
    
    // The files in the tune list should be located on the SD card 
    // or an error will occur opening the file and the next in the 
    // list will be opened (skips errors).
    const char *loopfile = "LOOPDEMO.MID";  // simple and short file
    
    MD_MIDIFile SMF;
    
    void midiCallback(midi_event *pev)
    // Called by the MIDIFile library when a file event needs to be processed
    // thru the midi communications interface.
    // This callback is set up in the setup() function.
    {
    #if USE_MIDI
      if ((pev->data[0] >= 0x80) && (pev->data[0] <= 0xe0))
      {
        Serial.write(pev->data[0] | pev->channel);
        Serial.write(&pev->data[1], pev->size-1);
      }
      else
        Serial.write(pev->data, pev->size);
    #endif
      DEBUG("\nM T", pev->track);
      DEBUG(":  Ch ", pev->channel+1);
      DEBUGS(" Data");
      for (uint8_t i=0; i<pev->size; i++)
      {
        DEBUGX(" ", pev->data[i]);
      }
    }
    
    void setup(void)
    {
      int  err;
    
      Serial.begin(SERIAL_RATE);
    
      DEBUGS("\n[MidiFile Looper]");
    
      // Initialize SD
      if (!SD.begin(BUILTIN_SDCARD))
      {
        DEBUGS("\nSD init fail!");
        while (true) ;
      }
    
      // Initialize MIDIFile
      SMF.begin(&SD);
      SMF.setMidiHandler(midiCallback);
      SMF.looping(true);
    
      // use the next file name and play it
      DEBUG("\nFile: ", loopfile);
      err = SMF.load(loopfile);
      if (err != MD_MIDIFile::E_OK)
      {
        DEBUG("\nSMF load Error ", err);
        while (true);
      }
    }
    
    void loop(void)
    {
      // play the file
      if (!SMF.isEOF())
      {
        SMF.getNextEvent();
      }
    }

  14. #14
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    23,994
    Quote Originally Posted by grinch View Post
    Anything else I should check?
    Maybe somewhere in the stuff Arduino prints is a message about duplicate libraries? It's supposed to tell you the full path of the SD lib it's actually using, and the location of any others it ignored.

    If you don't see that message, use File > Preferences to turn on verbose output while compiling.

    Those full paths are the way to make sure you're editing the right file. Easiest thing is to open the SD.h file and intentionally add a syntax error. If you see the error with that exact line appear, then you know you've got the file Arduino is actually using.

  15. #15
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    23,994
    You also need this, to convert SD to SdFat type

    SMF.begin(&(SdFat &)SD);

  16. #16
    Quote Originally Posted by PaulStoffregen View Post
    Maybe somewhere in the stuff Arduino prints is a message about duplicate libraries? It's supposed to tell you the full path of the SD lib it's actually using, and the location of any others it ignored.

    If you don't see that message, use File > Preferences to turn on verbose output while compiling.

    Those full paths are the way to make sure you're editing the right file. Easiest thing is to open the SD.h file and intentionally add a syntax error. If you see the error with that exact line appear, then you know you've got the file Arduino is actually using.
    I actually do get a message about duplicate libraries, but when I read the message it appears to says the used copy and the alternative copy are both the same filepath:

    Code:
    Multiple libraries were found for "SD.h"
     Used: /private/var/folders/j0/_sxbhppj1b9bmytyldk9lt600000gp/T/AppTranslocation/3127E6DE-31DD-4821-B385-FE0225410D7C/d/Teensyduino_BetaEdit.app/Contents/Java/hardware/teensy/avr/libraries/SD
     Not used: /private/var/folders/j0/_sxbhppj1b9bmytyldk9lt600000gp/T/AppTranslocation/3127E6DE-31DD-4821-B385-FE0225410D7C/d/Teensyduino_BetaEdit.app/Contents/Java/libraries/SD
    Any idea what might be going on here? Or where I can find the SD library I should actually be editting?

  17. #17
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    13,751
    This first one is correct - installed with TeensyDuino
    Used: /private/var/folders/j0/_sxbhppj1b9bmytyldk9lt600000gp/T/AppTranslocation/3127E6DE-31DD-4821-B385-FE0225410D7C/d/Teensyduino_BetaEdit.app/Contents/Java/hardware/teensy/avr/libraries/SD

    This second is the copy Arduino itself supplies - not for Teensy:
    Not used: /private/var/folders/j0/_sxbhppj1b9bmytyldk9lt600000gp/T/AppTranslocation/3127E6DE-31DD-4821-B385-FE0225410D7C/d/Teensyduino_BetaEdit.app/Contents/Java/libraries/SD

  18. #18
    Quote Originally Posted by defragster View Post
    This first one is correct - installed with TeensyDuino
    Used: /private/var/folders/j0/_sxbhppj1b9bmytyldk9lt600000gp/T/AppTranslocation/3127E6DE-31DD-4821-B385-FE0225410D7C/d/Teensyduino_BetaEdit.app/Contents/Java/hardware/teensy/avr/libraries/SD

    This second is the copy Arduino itself supplies - not for Teensy:
    Not used: /private/var/folders/j0/_sxbhppj1b9bmytyldk9lt600000gp/T/AppTranslocation/3127E6DE-31DD-4821-B385-FE0225410D7C/d/Teensyduino_BetaEdit.app/Contents/Java/libraries/SD
    Okay, thanks for catching that. The extremely long file path where almost everything is the same is easy to misread. So this indicates that I'm using the correct folder, which should have the updated SD.h file.

  19. #19
    Quote Originally Posted by PaulStoffregen View Post
    You also need this, to convert SD to SdFat type

    SMF.begin(&(SdFat &)SD);
    This worked for me. After replacing the SD file in the folder you specified and changing this line in my midi code it compiles. Thank you!

    Is there an estimate on when the new file will be incorporated into a downloadable Teensyduino release? Into a beta and a stable release respectively? This firmware is for an open ended hardware platform that I'm going to release to the public so to speak, so having an easy setup is important. Just wondering so I can adjust my project timeline accordingly.

    Really appreciate everyone's quick responses on this and being so willing to work with me in-depth.

  20. #20
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    23,994
    Quote Originally Posted by grinch View Post
    Is there an estimate on when the new file will be incorporated into a downloadable Teensyduino release? Into a beta and a stable release respectively?
    I've committed the code on github, so it'll certainly be in future releases.

    https://github.com/PaulStoffregen/SD...4606c7579e7fe7

    Timing of future releases is difficult to predict. Anything I say right now will probably turn out to be wrong. With that in mind, 1.54-beta7 is probably a couple weeks away. Timing for a final 1.54 release is much less certain. It is long overdue, but substantial issues remain with MTP which I really want to resolve for 1.54.



    If you have any contact with Marco Colli (author of MD_MIDIFile) or whoever is maintaining it, this usage could be much cleaner if another begin() function is added which takes a C++ reference.

    For example, in MD_MIDIFile.h:

    Code:
      void begin(SdFat *psd);
      void begin(SdFat & sd);
    and in MD_MIDIFile.cpp:

    Code:
    void MD_MIDIFile::begin(SdFat *psd)
    {
      _sd = psd;
    }
    
    void MD_MIDIFile::begin(SdFat & sd)
    {
      _sd = &sd;
    }
    With this change, user-level code would not need to (but still could) use the "&" pointer syntax. Then the sketch could could be:

    Code:
      SMF.begin(SD);
    The compiler is smarter about inferring the desired type of SdFat and converts Teensy's SD to SdFat automatically without any extra (somewhat ugly) syntax.

    When / if Arduino and others migrate from the ancient SD to SdFat, if they use Teensy's SD.h or build something similar, hopefully they'll gain similar ability to allow SD to be used with MD_MIDIFile.

  21. #21
    Quote Originally Posted by PaulStoffregen View Post
    I've committed the code on github, so it'll certainly be in future releases.

    https://github.com/PaulStoffregen/SD...4606c7579e7fe7

    Timing of future releases is difficult to predict. Anything I say right now will probably turn out to be wrong. With that in mind, 1.54-beta7 is probably a couple weeks away. Timing for a final 1.54 release is much less certain. It is long overdue, but substantial issues remain with MTP which I really want to resolve for 1.54.
    Cool, I think if I just tell people to download the beta that should be good enough. Is there some type of notification I can sign up for to let me know when a new beta comes out or should I just be checking the forums periodically?

  22. #22
    If you have any contact with Marco Colli (author of MD_MIDIFile) or whoever is maintaining it, this usage could be much cleaner if another begin() function is added which takes a C++ reference.
    No contact with Marco Colli unfortunately. Just the only library I could find online that was already written to work with midi files. Seems like it's kind of an old project, but I really didn't want to re-invent the wheel so it was worth figuring out how to work with it.

  23. #23
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    23,994
    Quote Originally Posted by grinch View Post
    Is there some type of notification I can sign up for to let me know when a new beta comes out
    You can subscribe to the announcements forum.

    https://forum.pjrc.com/forums/6-Announcements

    Look for the "Forum Tools" drop-down menu on that page.

  24. #24
    Hi, I'm trying to make a patch I can distribute to people with the stable release of Teensyduino by including the updated SD.h and .cpp files as PaulSD.h and .cpp in my patch folder. I've changed all of my <SD.h> includes to "PaulSD.h". However when I try to compile, I get the following error:

    Code:
    redefinition of 'class SDFile'
    This doesn't happen when I'm including the exact same code as a library file, what's going on here? I've checked and I'm not including SD.h anywhere in my patch.

  25. #25
    Senior Member
    Join Date
    Jul 2014
    Posts
    3,122
    Quote Originally Posted by grinch View Post
    I've checked and I'm not including SD.h anywhere in my patch.
    Did you restart Arduino before recompiling to clean-up cache?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •