Problems with (external) library using SDFat

But File isn't just a wrapper for SdFat...
It's a generic file handling class. Adding a function to it means every underlying filesystem object must support it. That's exactly the sort of thing that libc's formatted I/O functions are designed to workaround.
I agree with this take, that fgets() should not be added to File/FS.h. It’s possible to implement Newlib’s auxiliary file-related functions (_read(), _write(), _open(), etc.). Then you get almost all of the C file calls for free, including fgets(). I’ve personally implemented this over top of the FS.h classes for a Lua port.
 
Last edited:
@wwatson
Think I found the problem. Change the get strings to lower case, i.e.,
Code:
while (configFile.read(configFileName))
  {
    // Each parameter can be retrieved using the "get" method
    configFile.get("intValue", intValue);
    configFile.get("longValue", longValue);
    configFile.get("floatValue", floatValue);
    configFile.get("boolValue1", boolValue1);
    configFile.get("boolValue2", boolValue2);
    configFile.get("arduinoString", arduinoStringValue);
    configFile.get("cStringValue", cStringValue, 20);
  }

Now getting
Code:
IntValue: 1234
LongValue: 12678
FloatValue: 0.24689
boolValue1: 1
boolValue2: 0
arduinoString:
cStringValue: This is also a stri

Unfortunately not updating file with new values. You are up
 
Last edited:
@mjs513 - Sorry for the slow response. Been kinda sick for the last two day's🤭 Thanksgiving? Feeling a little better now.
Went through the code and found some more mismatched capitalization errors as well. That seemed to fix reads using the callback function.
Code:
 initialization Passed: OK.

--- Read Method 1 - While Loop ---
lineBuffer = intValue=1234
lineBuffer = longValue=12678
lineBuffer = floatValue=0.24689
lineBuffer = arduinoStringValue=Hello, this is a string with spaces
lineBuffer = cStringValue=This is also a string
lineBuffer =
lineBuffer = boolValue1=True
lineBuffer = boolValue2=0
lineBuffer = boolValue3=false
lineBuffer =
intValue: 1234
longValue: 12678
floatValue: 0.24689
boolValue1: 1
boolValue2: 0
arduinoString:
cStringValue: This is also a stri
--- Write Method 1 - While Loop ---
lineBuffer = intValue=1234
lineBuffer = longValue=12678
lineBuffer = floatValue=0.24689
lineBuffer = arduinoStringValue=Hello, this is a string with spaces
lineBuffer = cStringValue=This is also a string
lineBuffer =
lineBuffer = boolValue1=True
lineBuffer = boolValue2=0
lineBuffer = boolValue3=false
lineBuffer =
intValue: 1235
longValue: 12677
floatValue: 0.07054
boolValue1: 0
boolValue2: 1
arduinoString:  new
cStringValue: #his is also a stri
--- Read Method 2 - Callback ---
Success: config file parameters read
intValue: 1236
longValue: 12676
floatValue: 0.02015
boolValue1: 1
boolValue2: 0
arduinoString:  new new
cStringValue: #his is also a stri
--- Write Method 2 - Callback ---
lineBuffer = intValue=1234
lineBuffer = longValue=12678
lineBuffer = floatValue=0.24689
lineBuffer = arduinoStringValue=Hello, this is a string with spaces
lineBuffer = cStringValue=This is also a string
lineBuffer =
lineBuffer = boolValue1=True
lineBuffer = boolValue2=0
lineBuffer = boolValue3=false
lineBuffer =
Success: config file parameters write
It's showing that the write to the "test_file2.txt" is successful but the file is actually empty as well as any other writes to the three files ("test_file.txt", "test_file2.txt" and "_temp").

I'll start back at the printTofile() function first...
 
It's showing that the write to the "test_file2.txt" is successful but the file is actually empty as well as any other writes to the three files ("test_file.txt", "test_file2.txt" and "_temp").
Yeah saw that as well - trying to debug it now - looks like rename is failing.

And Hope you feel better - I am usually the same way. Recovering myself.
 
Last edited:
@wwatson - here is the fix - in write function
C++:
String tmpFileName = tempFile.name();
    tempFile.close();
    // Delete the original configuration file and rename the temporary file
    if(SD.exists(fileName))
        SD.remove(fileName);
    if (!SD.exists(fileName)) {
        SD.rename(tmpFileName.c_str(), fileName);
    }
 
@wwatson
Looks like that fixed the rest of it as well. The file marked copy is the original file. Oh for you ease of use - added MTP_teensy (Pauls version)
C++:
/**
 * SdConfigFile Library Example Sketch
 *
 * This example sketch shows how to read parameters from and write new
 * values to an SD Card Configuration File using the SdConfigFile library
 *
 * SdConfigFile <https://github.com/chillibasket/sd-config-file>
 * created:      25th January 2022
 * last updated: 27th February 2022
 * Copyright (C) 2022 by Simon Bluett
 *
 * Released in the public domain under the MIT license
 *
 * This example sketch requires the SdFat library to be installed:
 * SdFat <https://github.com/greiman/SdFat>
 */

/**
 * By default, the SdConfigFile library supports FAT16 and FAT32
 * SD card file system types. However, EXFAT support can also be
 * enabled by using one of the two "#defines" below. Note that
 * support for the EXFAT file system takes up more memory.
 *
 * SD_CONFIG_FILE_USE_EXFAT: support only EXFAT SD Cards
 * SD_CONFIG_FILE_USE_FSFAT: support both FAT16/32 and EXFAT SD Cards
 * default: FAT16 and FAT32 support only
 *
 * Uncomment the line below depending on your requirements:
 */
//#define SD_CONFIG_FILE_USE_EXFAT
//#define SD_CONFIG_FILE_USE_FSFAT

/**
 * Include the Sd config file library
 */
#include <SdConfigFile.h>
#include <MTP_Teensy.h>
#include <LittleFS.h>
LittleFS_Program lfsProg; // Used to create FS on the Flash memory of the chip
static const uint32_t file_system_size = 1024 * 512;
/**
 * Instantiate Sd config file object, passing
 * the chip select pin number as a variable
 */
SdConfigFile configFile(BUILTIN_SDCARD);

/**
 * Name of the configuration file to open
 */
String configFileName = "test_file.txt";
char configFileName2[] = "test_file2.txt";

// Define some variables which we will set using the
// values from the SD card configuration file
int intValue = 0;
long longValue = 0;
float floatValue = 0;
bool boolValue1 = false;
bool boolValue2 = false;
String arduinoStringValue = "";
char cStringValue[20] = { 0 };

/**
 * Setup function
 */
void setup() {
  // Start serial comms and wait for user to open the serial monitor
  Serial.begin(115200);
  while(!Serial);
  delay(1000);
  MTP.begin();
  // Try connecting to the SD card
  if (!SD.begin(BUILTIN_SDCARD)) {
    SD.sdfs.initErrorPrint(&Serial);
  }
  MTP.addFilesystem(SD, "SD Card");
  if (lfsProg.begin(file_system_size)) {
    MTP.addFilesystem(lfsProg, "Program");
  } else {
    Serial.println("Error starting Program Flash storage");
  }
  /**
   * Reading method 1 - using a while loop
   */
  Serial.println(F("--- Read Method 1 - While Loop ---"));
  // Use the "read" method and supply the directory and file name
  while (configFile.read(configFileName))
  {
    // Each parameter can be retrieved using the "get" method
    configFile.get("intValue", intValue);
    configFile.get("longValue", longValue);
    configFile.get("floatValue", floatValue);
    configFile.get("boolValue1", boolValue1);
    configFile.get("boolValue2", boolValue2);
    configFile.get("arduinoString", arduinoStringValue);
    configFile.get("cStringValue", cStringValue, 20);
  }

  // Print current variable values to the serial monitor
  outputParameterValues();
 
  // Change some of the parameters
  intValue++;
  longValue--;
  floatValue /= 3.5;
  boolValue1 = !boolValue1;
  boolValue2 = !boolValue2;
  arduinoStringValue += " new";
  cStringValue[0] = '#';

  /**
   * Writing method 1 - using a while loop
   */
  Serial.println(F("--- Write Method 1 - While Loop ---"));
  // Use the "write" method and supply the directory and file name
  while (configFile.write(configFileName))
  {
    // Each parameter can be saved using the "set" method
    // Note that when saving the parameter, the existing
    // parameter entry is removed from the file and the new
    // value is added to the bottom of the file
    configFile.set("intValue", intValue);
    configFile.set("longValue", longValue);
    configFile.set("floatValue", floatValue);
    configFile.set("boolValue1", boolValue1);
    configFile.set("arduinoString", arduinoStringValue);
    configFile.set("cStringValue", cStringValue);
    // New values can also be added to the file using the "set" method
    configFile.set("New Float Value", 12.6745, 4);
    // To remove a parameter from the file, use the "remove" method
    //configFile.remove("boolValue2");
  }
  // Print current variable values to the serial monitor
  outputParameterValues();
//while(1) { MTP.loop(); }
  // Change some of the parameters
  intValue++;
  longValue--;
  floatValue /= 3.5;
  boolValue1 = !boolValue1;
  boolValue2 = !boolValue2;
  arduinoStringValue += " new";
  cStringValue[0] = '#';

  /**
   * Read method 2 - using a callback function
   * The benefit of this method is that the function returns
   * a True/False value depending on if the read was successful
   */
  Serial.println(F("--- Read Method 2 - Callback ---"));
  if (configFile.read(configFileName, readConfigFunction))
  {
    Serial.println(F("Success: config file parameters read"));
  }
  else
  {
    Serial.println(F("Error: unable to read from config file"));
  }
 
  // Print current variable values to the serial monitor
  outputParameterValues();
  // Change some of the parameters
  intValue++;
  longValue--;
  floatValue /= 3.5;
  boolValue1 = !boolValue1;
  boolValue2 = !boolValue2;
  arduinoStringValue += " new2";
  cStringValue[0] = '#';
  /**
   * Write method 2 - using a callback function
   * The benefit of this method is that the function returns
   * a True/False value depending on if the read was successful
   */
  Serial.println(F("--- Write Method 2 - Callback ---"));
  if (configFile.write(configFileName2, writeConfigFunction))
  {
    Serial.println(F("Success: config file parameters write"));
  }
  else
  {
    Serial.println(F("Error: unable to write to config file"));
  }
}

/**
 * Main Program Loop
 */
void loop() {
    MTP.loop();
}

/**
 * Read Method 2 - Callback function
 *
 * This callback function is used to update the
 * variables each time that the "read" method finds
 * another parameter value in the configuration file
 */
void readConfigFunction() {
  configFile.get("intValue", intValue);
  configFile.get("longValue", longValue);
  configFile.get("floatValue", floatValue);
  configFile.get("boolValue1", boolValue1);
  configFile.get("boolValue2", boolValue2);
  configFile.get("arduinoString", arduinoStringValue);
  configFile.get("cStringValue", cStringValue, 20);
}

/**
 * Write Method 2 - Callback function
 *
 * This callback function is used to update the
 * variables each time that the "write" method finds
 * another parameter value in the configuration file
 */
void writeConfigFunction() {
  configFile.set("intValue", intValue);
  configFile.set("longValue", longValue);
  configFile.set("FloatValue", floatValue);
  configFile.set("boolValue1", boolValue1);
  configFile.set("boolValue2", boolValue2);
  configFile.set("arduinoString", arduinoStringValue);
  configFile.set("cStringValue", cStringValue);
}

/**
 * Output the current variables values to the serial monitor
 */
void outputParameterValues() {
  Serial.print("IntValue: "); Serial.println(intValue);
  Serial.print("LongValue: "); Serial.println(longValue);
  Serial.print("FloatValue: "); Serial.println(floatValue, 5);
  Serial.print("boolValue1: "); Serial.println(boolValue1);
  Serial.print("boolValue2: "); Serial.println(boolValue2);
  Serial.print("arduinoString: "); Serial.println(arduinoStringValue);
  Serial.print("cStringValue: "); Serial.println(cStringValue);
}
 

Attachments

  • test_file.txt
    233 bytes · Views: 9
  • test_file - Copy.txt
    193 bytes · Views: 9
  • test_file2.txt
    137 bytes · Views: 7
@mjs513 - As per the PM, the fix works :D Last thing to test is added back the comments part to "test_file.txt" and that seems to process properly. Done for tonight...
 
@wwatson
Tried with a modified test file that included "#" and "//" looks like it worked as well. Here are the files.
 

Attachments

  • test_file_orig.txt
    696 bytes · Views: 7
  • test_file.txt
    722 bytes · Views: 6
  • test_file2.txt
    148 bytes · Views: 6
@wwatson
Forgot you will need to update the example as well"
C++:
/**
 * SdConfigFile Library Example Sketch
 *
 * This example sketch shows how to read parameters from and write new
 * values to an SD Card Configuration File using the SdConfigFile library
 *
 * SdConfigFile <https://github.com/chillibasket/sd-config-file>
 * created:      25th January 2022
 * last updated: 27th February 2022
 * Copyright (C) 2022 by Simon Bluett
 *
 * Released in the public domain under the MIT license
 *
 * This example sketch requires the SdFat library to be installed:
 * SdFat <https://github.com/greiman/SdFat>
 */

/**
 * By default, the SdConfigFile library supports FAT16 and FAT32
 * SD card file system types. However, EXFAT support can also be
 * enabled by using one of the two "#defines" below. Note that
 * support for the EXFAT file system takes up more memory.
 *
 * SD_CONFIG_FILE_USE_EXFAT: support only EXFAT SD Cards
 * SD_CONFIG_FILE_USE_FSFAT: support both FAT16/32 and EXFAT SD Cards
 * default: FAT16 and FAT32 support only
 *
 * Uncomment the line below depending on your requirements:
 */
//#define SD_CONFIG_FILE_USE_EXFAT
//#define SD_CONFIG_FILE_USE_FSFAT

/**
 * Include the Sd config file library
 */
#include <SdConfigFile.h>
#include <MTP_Teensy.h>
#include <LittleFS.h>
LittleFS_Program lfsProg; // Used to create FS on the Flash memory of the chip
static const uint32_t file_system_size = 1024 * 512;
/**
 * Instantiate Sd config file object, passing
 * the chip select pin number as a variable
 */
SdConfigFile configFile(BUILTIN_SDCARD);

/**
 * Name of the configuration file to open
 */
String configFileName = "test_file.txt";
char configFileName2[] = "test_file2.txt";

// Define some variables which we will set using the
// values from the SD card configuration file
int IntValue = 0;
long longValue = 0;
float floatValue = 0;
bool BoolValue1 = false;
bool BoolValue2 = false;
bool boolValue3 = false;
String arduinoStringValue = "";
char cStringValue[20] = { 0 };

/**
 * Setup function
 */
void setup() {
  // Start serial comms and wait for user to open the serial monitor
  Serial.begin(115200);
  while(!Serial);
  delay(1000);
  MTP.begin();
  // Try connecting to the SD card
  if (!SD.begin(BUILTIN_SDCARD)) {
    SD.sdfs.initErrorPrint(&Serial);
  }
  MTP.addFilesystem(SD, "SD Card");
  if (lfsProg.begin(file_system_size)) {
    MTP.addFilesystem(lfsProg, "Program");
  } else {
    Serial.println("Error starting Program Flash storage");
  }
  /**
   * Reading method 1 - using a while loop
   */
  Serial.println(F("--- Read Method 1 - While Loop ---"));
  // Use the "read" method and supply the directory and file name
  while (configFile.read(configFileName))
  {
    // Each parameter can be retrieved using the "get" method
    configFile.get("IntValue", IntValue);
    configFile.get("longValue", longValue);
    configFile.get("floatValue", floatValue);
    configFile.get("BoolValue1", BoolValue1);
    configFile.get("BoolValue2", BoolValue2);
    configFile.get("boolValue2", boolValue3);
    configFile.get("arduinoString", arduinoStringValue);
    configFile.get("cStringValue", cStringValue, 20);
  }

  // Print current variable values to the serial monitor
  outputParameterValues();
 
  // Change some of the parameters
  IntValue++;
  longValue--;
  floatValue /= 3.5;
  BoolValue1 = !BoolValue1;
  BoolValue2 = !BoolValue2;
  boolValue3 = !boolValue3;
  arduinoStringValue += " new";
  cStringValue[0] = '#';

  /**
   * Writing method 1 - using a while loop
   */
  Serial.println(F("--- Write Method 1 - While Loop ---"));
  // Use the "write" method and supply the directory and file name
  while (configFile.write(configFileName))
  {
    // Each parameter can be saved using the "set" method
    // Note that when saving the parameter, the existing
    // parameter entry is removed from the file and the new
    // value is added to the bottom of the file
    configFile.set("IntValue", IntValue);
    configFile.set("longValue", longValue);
    configFile.set("floatValue", floatValue);
    configFile.set("BoolValue1", BoolValue1);
    configFile.set("boolValue3", boolValue3);
    configFile.set("arduinoString", arduinoStringValue);
    configFile.set("cStringValue", cStringValue);
    // New values can also be added to the file using the "set" method
    configFile.set("New Float Value", 12.6745, 4);
    // To remove a parameter from the file, use the "remove" method
    configFile.remove("BoolValue2");
  }
  // Print current variable values to the serial monitor
  outputParameterValues();
  // Change some of the parameters
  IntValue++;
  longValue--;
  floatValue /= 3.5;
  BoolValue1 = !BoolValue1;
  BoolValue2 = !BoolValue2;
  boolValue3 = !boolValue3;
  arduinoStringValue += " new";
  cStringValue[0] = '#';

  /**
   * Read method 2 - using a callback function
   * The benefit of this method is that the function returns
   * a True/False value depending on if the read was successful
   */
  Serial.println(F("--- Read Method 2 - Callback ---"));
  if (configFile.read(configFileName, readConfigFunction))
  {
    Serial.println(F("Success: config file parameters read"));
  }
  else
  {
    Serial.println(F("Error: unable to read from config file"));
  }
 
  // Print current variable values to the serial monitor
  outputParameterValues();
  // Change some of the parameters
  IntValue++;
  longValue--;
  floatValue /= 3.5;
  BoolValue1 = !BoolValue1;
  BoolValue2 = !BoolValue2;
  boolValue3 = !boolValue3;
  arduinoStringValue += " new2";
  cStringValue[0] = '#';
  /**
   * Write method 2 - using a callback function
   * The benefit of this method is that the function returns
   * a True/False value depending on if the read was successful
   */
  Serial.println(F("--- Write Method 2 - Callback ---"));
  if (configFile.write(configFileName2, writeConfigFunction))
  {
    Serial.println(F("Success: config file parameters write"));
  }
  else
  {
    Serial.println(F("Error: unable to write to config file"));
  }
}

/**
 * Main Program Loop
 */
void loop() {
    MTP.loop();
}

/**
 * Read Method 2 - Callback function
 *
 * This callback function is used to update the
 * variables each time that the "read" method finds
 * another parameter value in the configuration file
 */
void readConfigFunction() {
  configFile.get("IntValue", IntValue);
  configFile.get("longValue", longValue);
  configFile.get("floatValue", floatValue);
  configFile.get("BoolValue1", BoolValue1);
  configFile.get("BoolValue2", BoolValue2);
  configFile.get("boolValue3", boolValue3);
  configFile.get("arduinoString", arduinoStringValue);
  configFile.get("cStringValue", cStringValue, 20);
}

/**
 * Write Method 2 - Callback function
 *
 * This callback function is used to update the
 * variables each time that the "write" method finds
 * another parameter value in the configuration file
 */
void writeConfigFunction() {
  configFile.set("IntValue", IntValue);
  configFile.set("longValue", longValue);
  configFile.set("FloatValue", floatValue);
  configFile.set("BoolValue1", BoolValue1);
  configFile.set("BoolValue2", BoolValue2);
  configFile.set("boolValue3", boolValue3);
  configFile.set("arduinoString", arduinoStringValue);
  configFile.set("cStringValue", cStringValue);
}

/**
 * Output the current variables values to the serial monitor
 */
void outputParameterValues() {
  Serial.print("IntValue: "); Serial.println(IntValue);
  Serial.print("LongValue: "); Serial.println(longValue);
  Serial.print("FloatValue: "); Serial.println(floatValue, 5);
  Serial.print("BoolValue1: "); Serial.println(BoolValue1);
  Serial.print("BoolValue2: "); Serial.println(BoolValue2);
  Serial.print("boolValue3: "); Serial.println(boolValue3);
  Serial.print("arduinoString: "); Serial.println(arduinoStringValue);
  Serial.print("cStringValue: "); Serial.println(cStringValue);
}
 
Dear all,

I‘m still alive.
Sorry if I‘m creating some „what a moron“ reaction but …
to avoid stupid questions by using the wrong code:
are these the correct/necessary steps to get the latest lib code running?
- update to latest Teensyduino 0.60b5 version
- replace all fs.h and sd.h with versions as posted here in the thread by mjs513
- pull the latest lib version from the git branch from wwatson https://github.com/wwatson4506/sd-config-file/tree/sd-config-file_T4

Thanks so much,
Tom
 
Dear all,

I‘m still alive.
Sorry if I‘m creating some „what a moron“ reaction but …
to avoid stupid questions by using the wrong code:
are these the correct/necessary steps to get the latest lib code running?
- update to latest Teensyduino 0.60b5 version
- replace all fs.h and sd.h with versions as posted here in the thread by mjs513
- pull the latest lib version from the git branch from wwatson https://github.com/wwatson4506/sd-config-file/tree/sd-config-file_T4

Thanks so much,
Tom
Sorry, we have just finished fixing and testing. The changes will be pushed up to my repo of the library. I'll let you know when I have done that. There is one more slight change to FS.h. I will create an extras folder to put the modified FS.h and SD.h in and add that to the library...
 
You beat me to it. Just got back from picking up the wife from work. Give me a minute to eat breakfast and I will finish up and post :D

Take your time, I‘m preparing dinner now and will have to take care of my family later.
Tomorrow is another day.

Again, so many thanks to everybody helping me out!

Tom
 
Take your time, I‘m preparing dinner now and will have to take care of my family later.
Tomorrow is another day.

Again, so many thanks to everybody helping me out!

Tom
Great because I think I may have discovered another issue with beginning or append to a file. Maybe not. Have test a little more. I only have to finish testing the examples and then push them up to the repo...
 
@Nanoprecision - I think this library is mostly ready for you to try out. I have updated the README.md file with new installation instructions. There are now three examples too test with:
File "ReadWrite_ConfigFile.ino" is the modified version of the original authors sketch.
File "ReadWrite_ConfigFile_Test.ino" is your modified sketch.
File "ReadWrite_ConfigFile_MTP_littleFS.ino" is a modified version of the original authors sketch that allows you to examine and edit the test files on the SDcard without having to remove the SDcard from the Teensy 4.1. Makes it kinda handy for testing and usage. Just make sure that you select "tools > USB TYPE: "MTP Disk (Experimental)" in Arduino when using MTP with the Teensy.
I have added a new folder to the library called "extras" that contain the modified versions of "FS.h" and "SD.h". I have also added "test_file.txt" that need to be on the SDcard to run the examples. The contents of the file are:
Code:
// Comments are skipped by the library while reading a file
// A comment line is marked by two forward slashes // at the start of a line
# Alternatively, the hash symbol # can also be used to define a comment
# When writing to a file, the comments will be retained

# Each parameter is defined by the name, followed by an equals sign and the value
# No other data (such as a comment) is allowed on the same line
ParameterName=1234
LongValue=12678
FloatValue=0.24689
arduinoString=Hello, this is a string with spaces
cStringValue=This is also a string

# Boolean values can be capitalised or lowercase, or can be written using a 0 or 1
BoolValue1=True
BoolValue2=0
boolValue3=false

Here is the link to the library again. Still have to check out the append mode usage but that will have to wait till a little later.
In the mean time you can play with it what's there ;)
 
Hi,
got the example up&running :) :)

I'll start integration of the lib + coding, please allow some tiome for feedback.



FYI:
I have seen some issues with the MTP version "ReadWrite_ConfigFile_MTP_littleFS".
The SD-Card only shows up in the explorer as long as the Arduino IDE is running.
(The example "Basic_SD_Card.ino" is working fine, so likely not an issue of my environment)
Sequence:
- compile & load "ReadWrite_ConfigFile_MTP_littleFS", IDE running --> "Teensy" shows up as MTP in explorer, files on SD can be seen/edited
- close IDE ->"Teensy" still shows up as MTP in explorer, files on SD can be seen/edited
- power Teensy off & on, no IDE running ->"Teensy" does *not* show up as MTP in explorer

Cheers,
Tom
 
Last edited:
FYI:
I have seen some issues with the MTP version "ReadWrite_ConfigFile_MTP_littleFS".
The SD-Card only shows up in the explorer as long as the Arduino IDE is running.
(The example "Basic_SD_Card.ino" is working fine, so likely not an issue of my environment)
Sequence:
- compile & load "ReadWrite_ConfigFile_MTP_littleFS", IDE running --> "Teensy" shows up as MTP in explorer, files on SD can be seen/edited
- close IDE ->"Teensy" still shows up as MTP in explorer, files on SD can be seen/edited
- power Teensy off & on, no IDE running ->"Teensy" does *not* show up as MTP in explorer

Cheers,
Tom

@Nanoprecision:

Comment out the while(!Serial); line in your setup(). Otherwise, with this line uncommented, your sketch will wait (forever) at that point for the Serial Monitor to be connected.

Mark J Culross
KD5RXT
 
Back
Top