Porting an application to Workbench that uses SDFat library

I am porting my main application over to Workbench. In doing the first local compile I am hitting some problems not seen with cloud compile on Web IDE that related to the SDFat library. I would appreciate any advice/help about how to understand and fix these 4 errors. The first 3 appear to be something to do with “Arduino.h” header which is included.

./inc/Arduino.h:22:2: error: #error isnan is not defined please ensure this header is included before any STL headers
 #error isnan is not defined please ensure this header is included before any STL headers
/inc/Arduino.h:203:1: error: expected ';' before 'using'
 using std::isinf
./inc/Arduino.h:240:1: error: expected ';' before 'typedef'
 typedef USARTSerial HardwareSerial;
/Users/xxx/Documents/xyz/VSC_Projects/z-t-base/lib/SdFat/src/SdCard/SdInfo.h:112:34: error: 'F_CPU' was not declared in this scope

I have set the SDFat library version to be 0.0.7 whereas it appears to have installed 1.0.16 which is the latest and has these problems.

This can usually be solved via #include <math.h>

I have that in the list of includes but after the SDFat library include.

That won’t solve the issue with the F_CPU?

I thought you could specify a library version in the project.properties for the project but what seems to happen when I install the library is that it takes the latest version and then auto corrects the project.properties.

Just go with SPI_FULL_SPEED that way you won’t need the F_CPU macro which is not defined for Particle.

I have found there to be issues sometimes with using SPI_FULL_SPEED - anyhow to get it compiled. Thanks

You can also use SD_SCK_HZ() with the desired SPI speed instead of any of these predefined speed macros.

BTW, that’s just a wrapper for SPISettings() as seen here

Putting #include “math.h” in didn’t solve the errors

/inc/Arduino.h:22:2: error: #error isnan is not defined please ensure this header is included before any STL headers
#error isnan is not defined please ensure this header is included before any STL headers
./inc/Arduino.h:203:1: error: expected ‘;’ before ‘using’
using std::isinf
./inc/Arduino.h:240:1: error: expected ‘;’ before ‘typedef’
typedef USARTSerial HardwareSerial;

Looking into the definition of Arduino.h

#include "math.h"
#ifndef isnan
#error isnan is not defined please ensure this header is included before any STL headers - line 22

The other errors in the #ifdef __c_plus_plus section.

I am a bit lost why this library on this version targeted to a Photon with OS 1.4.1 won’t build.

Can you provide me with your project sources to see what may be happening?

I think something else ig going on here - I have a sdFat based project in workbench

name=SdFat version=1.0.16 license=MIT author=Bill Greiman <fat16lib@sbcglobal.net> maintainer=Bill Greiman <fat16lib@sbcglobal.net> sentence=FAT16/FAT32 file system for SD cards. paragraph=FAT16/FAT32 file system for SD cards. category=Data Storage url=https://github.com/greiman/SdFat repository=https://github.com/greiman/SdFat.git architectures=*

I am using minimal sd definitions and no Arduino.h includes


File dbFile;
File tagLogFile;
SdFat SD;
SdFile root;


if (!SD.begin(SS))
        strcat(tempMsg, "Fail"); // Fail
        strcat(tempMsg, "OK"); // OK

This is targeted to a photon on 1.4.x - app runs as expected - 10k records in a db on the sd card

So to paraphrase @ScruffR - “Show us some code”… :slight_smile:

1 Like

I have just been considering how to do that - it is a rather large application and there are bits I can’t share. I have compiled other applications targeted at Gen3 on 1.4.2 and using SdFat 1.0.16 and they work fine - thus I believe it is something related to Photon as the PlatformID. The SdFat library deep down has many Arduino.h includes amongst others from the standard libraries stdint, etc.

So to test…

New project
Installed SdFat library (latest 1.0.16)
Opened “ReadWrite.ino” from examples folder of LIB - copied content and pasted to .ino in src folder
Target device Photon with 1.4.4
Compiled clean

> Executing task: make -f '/Users/shanevanj/.particle/toolchains/buildscripts/1.8.0/Makefile' compile-user -s <


   text    data     bss     dec     hex filename
  12572     108    2644   15324    3bdc /Users/shanevanj/Documents/Workbench/Test/Test/SDFatTestPhoton/target/1.4.4/photon/SDFatTestPhoton.elf


Press any key to close the terminal.

So at a basic level - this shows the standard library in a small standard test works - you will need to find all the sdFat related calls in your app to narrow the search, since there are many, many functions in the sdFat library and you may be calling something that has a specific ARCH dependancy. I would comment out sdFat.h - compile and extract all the sdFat function call errors (perhaps that you can publish here) and we can work through them to find the culprit(s)?

Not even via PM with NDA? (hence the “me” in my post vs. “us”)
I have never had a problem with the Photon’s platform ID with SdFat.
If you want to dive into the library you may also need to consider other compiler options (e.g. the Photon also falls into the ARM branch as well as STM32F* and potentially others too) but that is a deeeep rabbit hole :wink:

1 Like

Thanks - I appreciate the responses/help @shanevanj @ScruffR. I will work along the lines suggested and if it can’t find anything then I’ll PM with a link to the code in a dropbox to see if you super sleuths can unearth the issue.

1 Like

I thought I would try building back on the Web IDE with SdFat 1.0.16 - I get the exact same errors.

I had an idea to move the #include <SdFat.h> to just after #include “Particle.h” and low and behold the first 3 issues disappear. This last issue was solved before. I will go and try this on the Workbench copy.

The conclusion I arrive at is that there is something in the #include “Adafruit_mfGFX.h” that is upsetting the apple cart - undefining something?

Yes, F_CPU is not declared and that won’t go away as long you use any macro that expects it to be declared (i.e. SPI_HALF_SPEED).
The way around this is to either use SD_SCK_HZ(), SD_SCK_MHZ() or even better SPISettings() directly.

I am sure I can figure my way around that - thanks for the pointers.

I had another funny on the Workbench compile where I have added to the Adafruit_ILI9341 library and defined DEG_TO_RAD - I get a warning that I am redefining it, turns out that this was declared before in spark_wiring_arduino_constants.h but if I remove from Adafruit_ILI9341.h I then get an error saying not defined. Is this to do with using or not using EXTERN ?

Probably not especially when this constant is #defined via the compiler directive and that is one reason why #define is considered “bad” (by some :wink: ).

You’d need to know in what order the compiler compiles the module (especially expanding #include statements and macros) and #defines are always local to the module and are non-existent at link time.

If you do get a redefinition warning for a #define you should check all instances of this definition for consistency and make sure you don’t inadvertently introduce incompatibilities. Once you have made sure it’s safe to redefine you can wrap your “redefinition” in a #ifndef block to only define it when it’s not already defined, otherwise stick with the preexisting one.

Whenever I come across code that uses #define for constants I sustitute that with a const <fitting data type> declaration to avoid confusion.
I prefer a failing build due to a proper error (the latest at link time) due to multiple declarations over a “silent” warning which may hint a re#define of something I’m later on using with the expectation that it still has its original value, causing extra debugging effort.

1 Like

Thanks for those learning points - I know @m_m likes to hear this - the Workbench compile and output is tons better in uncovering these things and in tracing the definitions. Case closed.


This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.