My situation is that I have made several hardware versions of a device that uses an Arduino Uno or Microduino Core+ for the processor, three different types of GPS receivers (so far), and two different types of barometric pressure sensors. Data collected from the GPS receiver and barometric pressure sensor are recorded to a microSD card in each of the configurations, and different shields have different SD card chip select lines. Different versions also have different serial port configurations.
I'm trying to publish this project on GitHub with at least three hardware configurations, I have different sketches and libraries for each configuration. I want my GitHub repo to be easy for others to use.
When I first started developing the three hardware variants of this project, I put all of the necessary libraries in C:\Users\username\My Documents\Arduino\libraries, where my sketchbook folder was C:\Users\username\My Documents\Arduino. That was OK for the barometric pressure sensor, because I could use one library for the BMP180 and another library for the BMP280, with no customization required. But the NeoGPS library is highly configurable via multiple header files for different protocol types (e.g., NMEA vs proprietary), variations on what NMEA sentences different receivers put out, and what information you want out of those sentences (e.g., if you don't need speed and heading, you can configure the library not to parse them). The NeoGPS library has a a src folder containing NMEA sentence processing .h and .cpp files, and subfolder under src called ublox, which contains .h and .cpp files for handling the u-blox proprietary GPS receiver protocol. In addition, using an Arduino Uno, which only has one hardware serial port, you have one GPS serial port configuration, but with the Microduino Core+, you have a second hardware serial port that you can use, which requires a different GPSPort.h configuration in NeoGPS. So I started out creating different versions of the various NeoGPS header files with different names for the different configurations. This (IMO) was a really bad idea, because if I update the NeoGPS library, the Arduino library manager replaces the existing library folder with the updated library folder, thus wiping out any custom header files I created. (Hooray for daily backups!) Moreover, it starts to get ugly (inelegant) fast.
After some research, I learned that the Arduino IDE looks for libraries in several places (the following is Windows specific): (1) the libraries folder in your sketchbook, e.g. C:\Users\username\My Documents\Arduino\libraries; (2) in the libraries folder of the Arduino IDE installation folder, e.g. C:\Program Files (x86)\Arduino\libraries; (3) in the folders below C:\Program Files (x86)\Arduino\hardware, e.g., C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries; and (4) in your sketch folder. If you want to include a library in one of the first three places, you enclose the appropriate header file name in angle brackets (<>), e.g., #include <SomeLib.h>
, and if you want to include a library in your sketch (not sketchbook) folder, you enclose the header file name in double quotes, e.g. #include "MyLib.h"
.
In order to be able to have several different configurations of the NeoGPS library, as well as other libraries including Adafruit_BMP280_Library or Adafruit_BMP085_Library, NeoSWSerial (if using an Arduino Uno, not needed for a Microduino Core+), PString, and SDFat, the solution I eventually settled on is to have a different sketchbook folder for each configuration, containing a libraries folder and a sketch folder. I have a copy of the each of the required libraries that are normally stored in the Arduino sketchbook folder in the libraries folder of my hardware-configuration-specific sketchbook folders. The main disadvantage of this approach (in addition to multiple copies of libraries that you may need to update) is that you have to remember to point the Arduino IDE to the correct sketchbook. You can easily change the sketchbook folder that the Arduino IDE uses under File... Preferences... Sketchbook location in the Arduino IDE (I'm using version 1.8.5 right now).
Another thing I learned is that if a library has at least one subfolder containing additional source code (.h and/or .cpp) files, all of the source code files must be within a src folder inside the library folder, or the IDE won't find the source code files within the subfolder. An exception to this src folder requirement may be if the subfolder is named "utility". See the Arduino IDE 1.5: Library specfication, under the Layout of folders and files heading. I quote:
The source code found in src folder and all its subfolders is compiled and linked in the user’s sketch. Only the src folder is added to the include search path (both when compiling the sketch and the library). When the user imports a library into their sketch (from the "Tools > Import Library" menu), an #include statement will be added for all header (.h) files in the src/ directory (but not its subfolders). As a result, these header files form something of a de facto interface to your library; in general, the only header files in the root src/ folder should be those that you want to expose to the user's sketch and plan to maintain compatibility with in future versions of the library. Place internal header files in a subfolder of the src/ folder.
For backward compatibility with Arduino 1.0.x, the library author may opt to place source code into the root folder, instead of the folder called src. In this case the 1.0 library format is applied and the source code is searched from the library root folder and the utility folder...
Hope this helps someone avoid wasting the amount of time I did in making my project work and look at least a bit elegant. Wish the Arduino website discussion of libraries was a bit more clear and thorough. I don't believe one should have to peruse multiple sources, including the Arduino Tutorial and Reference, the Arduino Wiki on GitHub, and this forum to figure this stuff out.