MTP, MSC, USB, SD, LittleFS.. what do I use and how?

Rezo

Well-known member
Hi all,

I've got a project up and running and I've just gotten the SD part of it working with LittleFS to take screenshots from the UI and save them to the SD card.
Hardware wise it's a Teensy MicroMod using the SDIO interface.
I am starting to work on a data logging mechanism that will also be writing files to the SD card.

What I would like to achieve is to be able to plug the device into my laptop's USB (Mac or PC), and be able to view copy the files from the SD card without having to remove the card, put it in a card reader etc.. What exactly do I need to to get this to work?
I've seen various threads about MTP, MSC, LittleFS etc and I am just confused. If someone can point me to a code example that would be great.

BTW I am using PIO with TD1.56 (waiting for 1.57 to release on PIO)
 
Look at the thread: https://forum.pjrc.com/threads/68139-Teensyduino-File-System-Integration-including-MTP-and-MSC

With 1.57 and MTP_Teensy: https://github.com/KurtE/MTP_Teensy

Mass Storage Controller (MSC) - is only needed if you are doing stuff with some form of drive like thumb drive or SSD connected through the USB Host port

MTP: Example that shows having an SD card show up in explorer window: Simplified examples -> Example_3_SD.ino
Code:
#include <SD.h>
#include <MTP_Teensy.h>

#define CS_SD BUILTIN_SDCARD  // Works on T_3.6 and T_4.1
//#define CS_SD 10  // Works on SPI with this CS pin
void setup()
{
  Serial.begin(9600);
  while (!Serial && millis() < 5000) {
    // wait for serial port to connect.
  }

  // mandatory to begin the MTP session.
  MTP.begin();

  // Add SD Card
  if (SD.begin(CS_SD)) {
    MTP.addFilesystem(SD, "SD Card");
    Serial.println("Added SD card using built in SDIO, or given SPI CS");
  } else {
    Serial.println("No SD Card");
  }
  Serial.println("\nSetup done");
}


void loop() {
  MTP.loop();  //This is mandatory to be placed in the loop code.
}
Note: this version currently has some limitations, that it does not work if initially the SD card is not in the drive, nor does it handle insertion and removals. I have some versions that do this. However I have a few different ways of being able to do that behind the scenes and we have not decided on best approach yet.
 
Hi Kurt, Thanks for the links and code example!

I do have a few questions:
1. How often does MTP.loop have to be called? I have a bunch of other tasks that need to keep their high priority.
2. Can I mount the MTP with sdFat/filefs?
3. My sd slot has a card detect pin. I assume I can detect card in/out via an interrupt and then call begin/mount and enable the loop with some simple logic?

Many thanks!
 
Is there any guide on best practices for using the SD library?
For example, should I call SD.begin() each time I want to write to the card?
Or, what's the best route of logic to handle card insert/remove? (I have a card detect pin on the SD slot).

If someone can point me to some type of writeup somewhere or has code examples that would be great!
 
I don't know of any such guide for using the SD library, there may be one for the SDFat library that SD is now a simple wrapper of.

SD.begin() - I typically only call once. Now I know some have stated that if you get a failure you may want to try it a couple of times as maybe a startup timing issue...
But again, my usages are mainly for testing code, not in the field or the like. Others may have different suggestions on how they handle things.

However, with more recent releases of Teensyduino there is a mechanism in place to help with Card Insertions and Deletions.

That is, you can do something like: if (SD.mediaPresent()) {

The mediaPresent will detect if there is a card within the slot and if before there was not, it will try to restart the SD...

How it detects a card is there depends:
For BUILTIN_SDCARD - Special code in place. When there was previous no card, it uses digitalReads on the _SD_DAT3 pin, if there as a card it reads.

For SPI type connections - If we know there is a Media Detect pin, we use digitalRead to know. Else we ask the card...

So, if you have a media detect pin, there is a call: SD.setMediaDetectPin(mypin);

What is not yet fully in place is code that calls mediaPresent, without yoru sketch having to know to do so.

In MTP type setup, it would be good if this was done automagically for the MTP client, such that they did not have to do a bunch of stuff in their code to handle this and to inform MTP of the change in status. Likewise, if you wanted USB Drives to show up and go away depending on if they are plugged in.

I have a couple of approaches that have been setup, but I know Paul wants a more generic approach where things may be added to the FS class. Hopefully in near future we will converge on an approach that will part of the next release of Teensyduino, or maybe one after that.
 
We do use the SDIO interface to communicate with the card, so I will take on your suggestion to use SD.mediaPresent to check if it's still there, and I'll reserve the card detect pin for later if it ever needs to be used.
Now, we do want to use the MTP library as the goal is to be able to plug in the device to a PC and copy/delete/add files from the card, so I am currently going around in circles trying to figure out how to manage that logic, as well as trying to understand what each of the public functions does.
 
Back
Top