SdFat icon indicating copy to clipboard operation
SdFat copied to clipboard

Problems with SDFAT + WiFi Libraries. ESP32

Open kugelkopf123 opened this issue 5 years ago • 9 comments

Hey.

I found the following problem:

As soon as I activate one of the libraries specified in the example code, it is no longer possible to open a file.


//#include <ESPAsyncWebServer.h>
//#include <WiFi.h>
//#include <ESPmDNS.h>
//#include "esp_wifi.h"

Presumably it is because in the different libraries the "Wifi.h" library is added.

As soon as you add the "ESPAsyncServer.h" library you get an additional error.

conversion from 'File' to non-scalar type 'fs :: File' requested

But it disappears if you add this:

#define FS_NO_GLOBALS
#include <FS.h>

Why it works then, I do not understand.

But probably that has nothing to do with this main problem.

Does somebody has any idea?

ESP WEMOS/LOLIN 32 v1 Dev Board. 4MB ESP32WROOM Arduino 1.8.9 Arduinojson v6 Standard WiFi.h Library Nothing is changed in SdFatConfig.h nor other Files. SDCARD Modul connected via Board 5V/GND and HSPI(CLK18,Miso19,Mosi23, CS15)

Example Code:


//#define FS_NO_GLOBALS
//#include <FS.h>

#include <SPI.h>
#include "SdFat.h"

SdFat SD;
const uint8_t SD_CS_PIN = 15;

const char* configjson = "/config.json";


#include <ArduinoJson.h>
/* // Libraries I need for a project!
  #include "UBLOX.h"
  #include "SSD1306Wire.h" // legacy include: `#include "SSD1306.h"`
  #include <DHT.h>;
  #include <Time.h>
  #include <TimeLib.h>
  #include <sys/time.h>
  #include <Wire.h>
  #include <RtcDS3231.h>

  #define TINY_GSM_MODEM_SIM800
  // Increase RX buffer if needed
  #define TINY_GSM_RX_BUFFER 1024
  #include <TinyGsmClient.h>
  #include <DNSServer.h>
//RtcDS3231<TwoWire> Rtc(Wire);
*/

// Libraries that make Problems each one of them. 
//#include <ESPAsyncWebServer.h>
//#include <WiFi.h>
//#include <ESPmDNS.h>
//#include "esp_wifi.h"



// Just a random Struct
struct Config {
  char hostname[20];
  char ssid[24];
  char wifiPW[24];
  char ssidAP[24];
};
Config config;







void setup() {

  Serial.begin(115200);
  while (!Serial) continue;

  if ( ! SD.begin(15, SD_SCK_MHZ(19))) {
    Serial.println("SD initiatization failed. Retrying.");
    while (!SD.begin(15, SD_SCK_MHZ(19))) {
      delay(250);
    }
  }


  Serial.println(F("Loading configuration..."));
  loadConfiguration(configjson, config);

  // Create configuration file
  Serial.println(F("Saving configuration..."));
  saveConfiguration(configjson, config);
  
  printFile(configjson);



}

void loop() {
}


void loadConfiguration(const char *filename, Config &config) {
  // Open file for reading
  File file = SD.open(filename);
  if (!file) {
    Serial.println("Cant load the file");
  }


  // Allocate a temporary JsonDocument
  StaticJsonDocument<1024> doc;

  // Deserialize the JSON document
  DeserializationError error = deserializeJson(doc, file);
  if (error)
    Serial.println(F("Failed to read file, using default configuration"));
  strlcpy(config.hostname,                  // <- destination
          doc["hostname"] | "ESPWoWa",  // <- source
          sizeof(config.hostname));         // <- destination's capacity
  strlcpy(config.ssid,
          doc["ssid"] | "WIFIAP",
          sizeof(config.ssid));
  strlcpy(config.wifiPW,
          doc["wifiPW"] | "1234567890",
          sizeof(config.wifiPW));
  strlcpy(config.ssidAP,
          doc["ssidAP"] | "ANOTHERAP",
          sizeof(config.ssidAP));


  file.close();
}


void saveConfiguration(const char *filename, const Config &config) {
  // Delete existing file, otherwise the configuration is appended to the file
  SD.remove(filename);

  // Open file for writing
  File file = SD.open(filename, FILE_WRITE);
  if (!file) {
    Serial.println(F("Failed to create file"));
    return;
    
  }
  StaticJsonDocument<1024> doc;
    doc["hostname"] = config.hostname;
    doc["ssid"] = config.ssid;
    doc["wifiPW"] = config.wifiPW;
    doc["ssidAP"] = config.ssidAP ;


if (serializeJsonPretty(doc, file) == 0) {

    Serial.println(F("Failed to write to file"));
  }
  
  file.close();
}

void printFile(const char *filename) {

  //SDCARD();
  // Open file for reading
  File file = SD.open(filename);
  if (!file) {
    Serial.println(F("Failed to read file"));
    return;
  }

  // Extract each characters by one by one
  while (file.available()) {
    Serial.print((char)file.read());
  }
  Serial.println();

  // Close the file
  file.close();
}

Output with WiFi.h:

Loading configuration...
Cant load the file
Failed to read file, using default configuration
Saving configuration...
Failed to create file
Failed to read file

Output without WiFi stuff:

Loading configuration...
Saving configuration...
{
  "hostname": "ESPWoWa",
  "ssid": "WIFIAP",
  "wifiPW": "1234567890",
  "ssidAP": "ANOTHERAP"
}

kugelkopf123 avatar Jul 31 '19 23:07 kugelkopf123

Please test with 1.1.2. I believe that the new version solves your problem.

xvinny-zz avatar Feb 27 '20 12:02 xvinny-zz

Give me some time, i will check this.

kugelkopf123 avatar Feb 27 '20 22:02 kugelkopf123

Finally got a chance to try it. Sorry it took so long. With the above mentioned WiFi libraries it works. Only with AsyncWebServer it does not.

I have added an error log.

In file included from /Users/kugelkopf/Documents/Arduino/libraries/ESPAsyncWebServer/src/ESPAsyncWebServer.h:27:0,
                 from /Users/kugelkopf/Documents/Arduino/SDFAT_Problem_TEST/SDFAT_Problem_TEST.ino:33:
/Users/kugelkopf/Library/Arduino15/packages/esp32/hardware/esp32/1.0.4/libraries/FS/src/FS.h:30:0: warning: "FILE_READ" redefined
 #define FILE_READ       "r"
 ^
In file included from /Users/kugelkopf/Documents/Arduino/libraries/SdFat/src/FatLib/FatLib.h:27:0,
                 from /Users/kugelkopf/Documents/Arduino/libraries/SdFat/src/SdFat.h:33,
                 from /Users/kugelkopf/Documents/Arduino/SDFAT_Problem_TEST/SDFAT_Problem_TEST.ino:5:
/Users/kugelkopf/Documents/Arduino/libraries/SdFat/src/FatLib/ArduinoFiles.h:37:0: note: this is the location of the previous definition
 #define FILE_READ O_RDONLY
 ^
In file included from /Users/kugelkopf/Documents/Arduino/libraries/ESPAsyncWebServer/src/ESPAsyncWebServer.h:27:0,
                 from /Users/kugelkopf/Documents/Arduino/SDFAT_Problem_TEST/SDFAT_Problem_TEST.ino:33:
/Users/kugelkopf/Library/Arduino15/packages/esp32/hardware/esp32/1.0.4/libraries/FS/src/FS.h:31:0: warning: "FILE_WRITE" redefined
 #define FILE_WRITE      "w"
 ^
In file included from /Users/kugelkopf/Documents/Arduino/libraries/SdFat/src/FatLib/FatLib.h:27:0,
                 from /Users/kugelkopf/Documents/Arduino/libraries/SdFat/src/SdFat.h:33,
                 from /Users/kugelkopf/Documents/Arduino/SDFAT_Problem_TEST/SDFAT_Problem_TEST.ino:5:
/Users/kugelkopf/Documents/Arduino/libraries/SdFat/src/FatLib/ArduinoFiles.h:39:0: note: this is the location of the previous definition
 #define FILE_WRITE (O_RDWR | O_CREAT | O_AT_END)
 ^
In file included from /Users/kugelkopf/Documents/Arduino/libraries/ESPAsyncWebServer/src/ESPAsyncWebServer.h:27:0,
                 from /Users/kugelkopf/Documents/Arduino/SDFAT_Problem_TEST/SDFAT_Problem_TEST.ino:33:
/Users/kugelkopf/Library/Arduino15/packages/esp32/hardware/esp32/1.0.4/libraries/FS/src/FS.h:118:11: error: 'File' is already declared in this scope
 using fs::File;
           ^
/Users/kugelkopf/Documents/Arduino/SDFAT_Problem_TEST/SDFAT_Problem_TEST.ino: In function 'void loadConfiguration(const char*, Config&)':
SDFAT_Problem_TEST:87:22: error: conversion from 'File' to non-scalar type 'fs::File' requested
   File file = SD.open(filename);
                      ^
/Users/kugelkopf/Documents/Arduino/SDFAT_Problem_TEST/SDFAT_Problem_TEST.ino: In function 'void saveConfiguration(const char*, const Config&)':
SDFAT_Problem_TEST:123:43: error: invalid conversion from 'const char*' to 'oflag_t {aka int}' [-fpermissive]
   File file = SD.open(filename, FILE_WRITE);
                                           ^
In file included from /Users/kugelkopf/Documents/Arduino/libraries/SdFat/src/FatLib/FatLib.h:28:0,
                 from /Users/kugelkopf/Documents/Arduino/libraries/SdFat/src/SdFat.h:33,
                 from /Users/kugelkopf/Documents/Arduino/SDFAT_Problem_TEST/SDFAT_Problem_TEST.ino:5:
/Users/kugelkopf/Documents/Arduino/libraries/SdFat/src/FatLib/FatFileSystem.h:93:8: note:   initializing argument 2 of 'File FatFileSystem::open(const char*, oflag_t)'
   File open(const char *path, oflag_t oflag = FILE_READ) {
        ^
SDFAT_Problem_TEST:123:22: error: conversion from 'File' to non-scalar type 'fs::File' requested
   File file = SD.open(filename, FILE_WRITE);
                      ^
/Users/kugelkopf/Documents/Arduino/SDFAT_Problem_TEST/SDFAT_Problem_TEST.ino: In function 'void printFile(const char*)':
SDFAT_Problem_TEST:148:22: error: conversion from 'File' to non-scalar type 'fs::File' requested
   File file = SD.open(filename);
                      ^
Mehrere Bibliotheken wurden für "WiFi.h" gefunden
 Benutzt: /Users/kugelkopf/Library/Arduino15/packages/esp32/hardware/esp32/1.0.4/libraries/WiFi
 Nicht benutzt: /Applications/Arduino.app/Contents/Java/libraries/WiFi
exit status 1
conversion from 'File' to non-scalar type 'fs::File' requested

kugelkopf123 avatar Apr 10 '20 21:04 kugelkopf123

You might try SdFat-beta, it has several fixes for ESP32.

greiman avatar Apr 11 '20 13:04 greiman

Just keep the wifi related library at the top and put the sd card related library below it. It will work I guess

ayashkant avatar May 11 '21 08:05 ayashkant

Same problem, and no solutions at the moment. Tried it with ESP8266WebServer and AsyncWebServer, but none worked. "FsFile to non scaler fs::File requested". It's a pb of "SdFat" conflicting with File system, may it be SPIFFS or LittleFS, the problem is the same :"FsFile to non scaler fs::File requested".

frnck37 avatar Jan 15 '23 23:01 frnck37

The type File is taken by the ESP8266 system. You can't use this on ESP8266:

File file;
file = sd.open(filename);

This means many libraries using SdFat won't work on ESP8266.

The following should still work:

FsFile file;
file.open(filename);

greiman avatar Jan 16 '23 12:01 greiman

I was able to solve the "incompatibility" between the SdFat and the FS type needed in places like server.serveStatic(some_path, SdFat32Fs, some_path"); // server is a ESP AsyncWebServer instance.

SdFat32Fs is an adapter instance in a variable like: fs::FS SdFat32Fs = fs::FS(fs::FSImplPtr(new SdFat32FSImpl(sd)));

where the is a previous SdFat instance like: SdFat32 sd;

See attached wrapper code for the SdFat32FSImpl and related SdFatFile32Impl. The wrappers/adapters are not complete, but they served enough the purpose I had in mind to bridge between the SdFat32 type and the FS types. This was used on a ESP32-S2 if that matters with framework-arduinoespressif32 @ 3.20006.221224 (2.0.6)

sd_fat32_fs_wrapper.zip

ockernuts avatar Mar 10 '23 20:03 ockernuts

Same problem, and no solutions at the moment. Tried it with ESP8266WebServer and AsyncWebServer, but none worked. "FsFile to non scaler fs::File requested". It's a pb of "SdFat" conflicting with File system, may it be SPIFFS or LittleFS, the problem is the same :"FsFile to non scaler fs::File requested".

Maybe the wrapper solution above can also be adapted to work on the ESP8266WebServer. It works for me on the AsyncWebServer on ESP32.

ockernuts avatar Mar 10 '23 20:03 ockernuts