Based on your all suggestions, I am looking into the SdFat library.
@sterretje I am using an arduino board without a built in SD card, so I need to use an adapter. However, that's not the only thing I need to connect to the various IO pins. In order to accommodate the multiple various accessories, it helps to have flexibility in which pins I can connect any one accessory to
With the exception of CPUs where hardware modules (SPI, I2C, Serial) can be assigned arbitrarily to any pins by internal hardware switching/multiplexing, it’s advisable to stick with the original hardware assignments whenever possible. Most software ‘emulations’ of hardware functionality have compromises, usually in the area of speed, but functionality can also be impacted.
I realize you may be backed into a corner by things out of your control, but if changing a few wires/traces on a PCB, for example, can allow you to use the native SPI hardware, it’s worth considering.
The Nano 33 IoT indeed does not have a built-in card reader
That is not quite how hardware works.
What I suggest is that you use a baseboard. For development that can be a breadboard, for the final product stripboard or a specifically designed board. You can also use a screw shield for a Nano. E.g. Arduino Nano Screw Terminal Adapter — Arduino Official Store; cheaper versions available form the far east.
That way you can add multiple devices on the SPI bus or I2C bus.`
A very sloppy PCB design with a Nano and 3 SPI connectors, I did not spend too much time on it. Note that the Nano here is not a Nano 33 IoT but that should not matter too much.
Neither a breadboard nor a custom PCB are practical options for my project at this point in time. (For one, a breadboard completely eliminates the size advantage of using a small board like an Arduino Nano).
Please simply accept that I have valid reasons for desiring to use a software solution to utilize the general purpose IO pins, instead of trying to push a hardware alternative
Unfortunately, not how it works. With C/C++, each translation unit is compiled separately. The resulting modules are linked together (for embedded, it's static linking) after all the compilation.
In the simplest case, a header is just a set of forward declarations: these are the signatures of the functions, the shapes of the types, and maybe some magic numbers. It's common practice to put that in a header file and then use it on "both ends": in the actual implementation, to ensure it conforms with what you said it is going to be; and for those that use the library, so that the compiler knows how to setup the calls/usage.
Finding a header file that works differently is (with some specific exceptions) simply insufficient to change the behavior of another module.
That's prudent. So instead do this
In the IDE Settings, turn on Show files inside Sketches
Unfortunately, the IDE does not enable folder creation, so you'll have to do this manually with the File Explorer/Finder or shell: inside the sketch folder, create a subfolder for your copy of the library, under a new subdirectory named src
[sketchbook, probably] Arduino/
hello/
hello.ino
libraries/
my2ndsketch/
my2ndsketch.ino
thissketch/
thissketch.ino
src/
mySDlib/ ##-- this one
Copy the necessary files into the new folder
src/
mySDlib/
SD.h
SD.cpp
File.cpp
In your .ino, use the actual path to the header
#include "src/mySDlib/SD.h"
Now if you build/Verify, it will compile SD.cpp and File.cpp, both which use SD.h, as does your .ino: three translation units using the same header. This works because the backend will compile all the sources in
the sketch folder (containing the same-name .ino)
its src/ subfolder
all subdirectories (recursively) of src/
but not any other subfolders of the sketch
You are free to edit these files in any way.
Now if you can get it to work, and you want to use this as a new library in other sketches... that's some another set of steps.