My project code won't upload or run [SOLVED]

I've just moved from an arduino nano to an arduino nano ESP32 and I have been trying to make the code compatible with the new board, however I can't get the code to run at all anymore. I had some issues with the time library, of which it was constantly giving me LCD and serial output that the RTC has failed, so I changed it for the rtc library, as I know that one works. next, it was giving LCD/serial output that the SD card wasn't beginning, so I ran another code to get the SD card to work and deleted all files on the card. Now, I'm having trouble running my code: The SD example I used won't begin the SD card (MISO pin 12, MOSI pin 11, SCK pin 13 and CS pin 10), and even after resetting the arduino and uploading my code multiple times, the SD example code was still running on the serial monitor. I uploaded an empty sketch and then uploaded my code, but I'm getting nothing back. Does anyone know why? Here is my code, it isn't fully finished yet but I thought I'd at least still be getting serial monitor output like before:

/*    _______________________________________________________________________________________________________________________________________________________________________
ㅤㅤ /\             \                                                                                                                                          /            /\
ㅤ ㅤ|_\             \                                                               DATALOGGER                                                               /            /_|
ㅤㅤ |__\             \________________________________     20x4 LCD, SD ADAPTER, DS3231, DS18B20 (5.1kPU), FLOAT SWITCH     ________________________________/            /__| 
ㅤㅤ |___\                                             \____________________________________________________________________/                                            /___|  
ㅤㅤ |____\                                                                                                                                                             /____|
ㅤ ㅤ|_____\                  _______________________________________________________________________________________________________________________                  /_____|
ㅤㅤ \______\                /                                                                                                                       \                /______/                                            
ㅤㅤ  \_____/\______________/  THIS PROGRAM MAY ALSO BE USED AS A GENERAL DATA LOGGER BY MODIFYING THE SENSOR CODE AND INPUTTING THE NECESSARY CODE   \______________/\_____/
ㅤ ㅤ                        \________________________________________________________________________________________________________________________/                     

___________________________________________________________________________________________________________________________________________________________________________________
ㅤ  ㅤ   ㅤ           ㅤ/   (ALL VCC AND GND TO BE WIRED TO VCC AND GND)    \                           /
HARDWARE WIRING LIST: /                                                     \   PROGRAM DESCRIPTION:  /   
_____________________/                                                       \_______________________/
ㅤ                                                      
_________________________________                        _________________________________________________________________
FOR 20X4 LIQUID CRYSTAL DISPLAY: \                      /                                                                 \
............_____________________/                     /  This program is designed to log data from a DS18B20 temperature  \
-VSS GND   /                                           | sensor and read a  float  switch  value.  Once the  SD  card  is  | 
-VDD 5V    \____                                       |  initialised and  the RTC reads the set time, the  program  will  | 
-V0 2k RESISTOR \                                      |  create a file in the SD card and name it according to the  date  | 
-RS PIN A0  ____/                                      |  (the date is retrieved using a DS3231 RTC). once the  file  and  | 
-RW GND    /                                           |  file name is created, 8 data samples from all  DS18B20  sensors  | 
-E PIN A1  |                                           |  are  averaged,  formatted  and  logged   within   the   logging  | 
-D0 X     /                                            |  interval into the created file, as well as the time of the  day  | 
-D1 X    /                                             |  in seconds and the current state of the  float  switch.  If  the | 
-D2 X    \                                             |  program is ran  until  the  next  day,  data  logging  will  be  | 
-D3 X     \                                            |  stopped, and another file will be created and  named  according  | 
-D4 PIN A2 \                                           |  to the date. The liquid  crystal  display  and  serial  monitor  | 
-D5 PIN A3  \                                          |  will show all relevant info, and can be used to ensure that the  | 
-D6 PIN D2  |                                          |  program runs correctly, displaying SD card initialisation,  RTC  | 
-D7 PIN D7  /                                          |  initialisation, the filename the data is writing to,  the  time  | 
-A 10K POT /                                           |  the data started logging in DHHMMSS, and the  current  time  of  | 
-K GND    /                                            \  the RTC. If any Errors occur, the LCD or  serial  monitor  will  / 
_________/                                              \__________________  display an Error message.  __________________/ 
ㅤ                                                                         \___________________________/
____________________________
FOR SD CARD ADAPTER MODULE: \
....................________/
-chipSelect PIN D10 \
-MOSI PIN D11  _____/
-MISO PIN D12 /
-SCK PIN D13 /
____________/

_________________
FOR DS3231 RTC:  \
..................\
-SCL PIN SCL OR A5 \
-SDA PIN SDA OR A4  |
-SQW X  ___________/
_______/

________________________________
FOR DS18B20 TEMPERATURE SENSOR: \
........._______________________/
-POS 5V  \
-NEG GND  \__
-DQ 5.1kPU   \________________
-5.1kPU LINKING PIN D9 AND 5V \______________
-104pF CERAMIC CAPACITOR LIKNING POS AND NEG \
_____________________________________________/

__________________
FOR FLOAT SWITCH: \
............._____/
-POS PIN D4 /
-NEG GND __/
________/

// INCLUDE LIBRARIES AND DEFINED CONSTANTS:                                                                                      
/********************************************************************************************************************************************************************************/

#include <OneWire.h>
#include <DallasTemperature.h>
#include <SD.h>
#include <SPI.h>
#include <LiquidCrystal.h>
#include <WiFi.h>
#include <RTClib.h>
#include <esp_sntp.h>
#include <sntp.h>

#define BLUE 3
#define floatSw 4
#define GREEN 5
#define RED 6
#define buzzer 8
#define ONE_WIRE_BUS 9
#define buzzerTogglePin A6
#define printAll(txt) Serial.println(txt), lcd.print(txt)


// used as general global variables
/********************************************************************************************************************************************************************************/
File dataFile;
LiquidCrystal lcd(A0, A1, A2, A3, 2, 7);
RTC_DS3231 rtc;
DateTime now = rtc.now();
int year = now.year() - 2000;

unsigned long tStart = millis();
unsigned long totMillis;
unsigned long lastMillis = 0;
unsigned long logTm = 10000;
unsigned long sampleTm = 1250;
unsigned long tLog = totMillis + logTm;
unsigned long tSample = totMillis + sampleTm;

int buzzerState = 1;
int BTstate;
int chipSelect = 10;

const char* SSID = "my SSID";
const char* PASSWORD = "my password";
const char* ntpServer1 = "pool.ntp.org";
const char* ntpServer2 = "time.nist.gov";
const long  gmtOffsetSec = -3600;
const int   daylightOffsetSec = 3600;
const char* time_zone = PSTR("GMT0BST,M3.5.0/1,M10.5.0");

char dirName[8] = "TANKLOG";
char fileName[13];
char fullPath[22];

void (* resetFunc)(void) = 0;


// variables only used for the specific type of datalogging
/********************************************************************************************************************************************************************************/
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

// function runs if a hardware error occurs
/********************************************************************************************************************************************************************************/
void hardwareErr() {
  while (!SD.begin(chipSelect) || !SD.open(fullPath)) {
    digitalWrite(buzzer, 1);
    delay(100);
    digitalWrite(buzzer, 0);
    delay(1900);
  }

  if(SD.begin(chipSelect) && SD.open(fullPath)) {
    resetFunc();
  }
}

// initialises most of the hardware
/********************************************************************************************************************************************************************************/
void timeavailable(struct timeval *t) {
  printAll("NTP time adjusted");
  initialisation();
}

void initialisation() {
  sntp_set_time_sync_notification_cb( timeavailable );
  WiFi.begin(SSID, PASSWORD);
  printAll("Connecting to WiFi..");
  sensors.begin();
  sensors.setWaitForConversion(false);
  lcd.begin(20, 4);
  lcd.clear();
  sensors.requestTemperatures();
  pinMode(buzzer, OUTPUT);
  pinMode(buzzerTogglePin, INPUT);
  buzzerState = 1;
  pinMode(floatSw, INPUT_PULLUP);
  pinMode(RED, OUTPUT);
  pinMode(GREEN, OUTPUT);
  pinMode(BLUE, OUTPUT);
  SD.begin(chipSelect);
  Serial.print(F(""));
  if (!SD.begin(chipSelect)) {
    printAll(F("SD Card Failed."));
    hardwareErr();
  }
  sntp_servermode_dhcp(1);
  configTime(gmtOffsetSec, daylightOffsetSec, ntpServer1, ntpServer2);
  lcd.setCursor(0, 1);
  if(WiFi.status() == WL_CONNECTED) {
    printAll("WiFi connected");
  }
}

// creates the file and name, and prints lcd info if the file is available to write to
/*******************************************************************************************************************************************************************************/
void createFileAndName() {
  
  sprintf(fileName, "%02d-%02d-%d.txt", now.day(), now.month(), year);
  strlcpy(fullPath, dirName, sizeof fullPath);
  strlcat(fullPath, "/", sizeof fullPath);
  strlcat(fullPath, fileName, sizeof fullPath);
  SD.mkdir(dirName);

  // INITIALISE LCD DISPLAY DATA
  /********************************************************************************************************************************************************************************/
  Serial.println(fullPath);
  lcd.print(dirName);
  lcd.print("     ");
  lcd.print(fileName);
  lcd.setCursor(0, 1);
  lcd.print(F("TEMP:"));
  lcd.setCursor(0, 2);
  lcd.print(F("TANK LVL:"));
  lcd.setCursor(17, 2);
}

void firstWrite() {
  dataFile = SD.open(fullPath, FILE_WRITE);
  dataFile.close();
  dataFile = SD.open(fullPath, FILE_WRITE);
  if (!dataFile) {
    printAll("First Write Error.");
    hardwareErr();
  }
  dataFile.println("#Time Sw Temp");
  dataFile.close();
  }


//  DATA AND DIAGNOSTICS:
/********************************************************************************************************************************************************************************/
void DatalogAndDiagnostics() {

  // TIME INFO:
  /********************************************************************************************************************************************************************************/
  char displayTime[21];
  if (now.hour() == 0 && now.minute() == 0 && now.second() == 0) {
    createFileAndName();
    delay(750);
  }
  unsigned long totMillis = millis() - tStart;
  unsigned long totSeconds = (millis() - tStart) / 1000;
  unsigned long totMinutes = totSeconds / 60;
  unsigned long totHours = totMinutes / 60;
  unsigned long totDays = totHours / 24;

  totSeconds %= 60;
  totMinutes %= 60;
  totHours %= 24;
  totDays %= 7;

  char charDays[2];
  char charHours[3];
  char charMinutes[3];
  char charSeconds[3];

  dtostrf(totDays, 1, 0, charDays);
  dtostrf(totHours, 2, 0, charHours);
  dtostrf(totMinutes, 2, 0, charMinutes);
  dtostrf(totSeconds, 2, 0, charSeconds);

  sprintf(displayTime, "%02d:%02d:%02d %sd%02sh%02sm%02ss", now.hour(), now.minute(), now.second(),
  charDays, charHours, charMinutes, charSeconds);

  lcd.setCursor(0, 3);
  lcd.print(displayTime);

  unsigned long hToM = now.hour() * 60;
  unsigned long hToS = hToM * 60;
  unsigned long mToS = (now.minute() * 60);
  unsigned long sToS = now.second();
  unsigned long tmDayInS = hToS + mToS + sToS;

  //SPECIFIC DATALOGGING CODE:
  /********************************************************************************************************************************************************************************/
  static int floatSwState;
  static byte nSample = 0;
  const int highTempTm = 1000;
  const int tempErrTm = 1500;
  const int floatSwTm = 500;
  static bool highTempErrState = 0;
  static bool hardwareErrState = 0;
  static bool floatSwErrState = 0;
  lcd.setCursor(10, 2);
  if (digitalRead(floatSw) == 1) {
    lcd.print("OK    ");
    floatSwState = 1;
    floatSwErrState = 0;
  } else if (digitalRead(floatSw == 0)) {
    lcd.print("NOT OK");
    floatSwState = 0;
    floatSwErrState = 1;
    if (totMillis - lastMillis > floatSwTm) {
      lastMillis = totMillis;
      if (buzzerState == 1) {
        digitalWrite(buzzer, 1);
      }
      digitalWrite(RED, 0);
      digitalWrite(GREEN, 0);
      digitalWrite(BLUE, 1);

    } else {
      digitalWrite(buzzer, 0);
    }
  }
  lcd.setCursor(6, 1);
  sensors.getTempCByIndex(0);
  lcd.print(sensors.getTempCByIndex(0));
  lcd.print("\337C");
  sensors.requestTemperatures();
  if (sensors.getTempCByIndex(0) >= 0 && sensors.getTempCByIndex(0) <= 22) {
    digitalWrite(RED, 0);
    digitalWrite(GREEN, 1);
    digitalWrite(BLUE, 0);
    highTempErrState = 0;
  } else if (sensors.getTempCByIndex(0) > 22 && sensors.getTempCByIndex(0) <= 23) {
    analogWrite(RED, 255);
    analogWrite(GREEN, 255);
    digitalWrite(BLUE, 0);
    highTempErrState = 0;
  } else if (sensors.getTempCByIndex(0) > 23 && sensors.getTempCByIndex(0) <= 24) {
    analogWrite(RED, 255);
    analogWrite(GREEN, 90);
    digitalWrite(BLUE, 0);
    highTempErrState = 0;
  } else if (sensors.getTempCByIndex(0) > 24 && sensors.getTempCByIndex(0) <= 25) {
    digitalWrite(RED, 1);
    digitalWrite(GREEN, 0);
    digitalWrite(BLUE, 0);
    highTempErrState = 0;
  } else if (sensors.getTempCByIndex(0) > 25) {
    highTempErrState = 1;
    if (totMillis - lastMillis > highTempTm) {
      lastMillis = totMillis;
      if (buzzerState == 1) {
        digitalWrite(buzzer, 1);
      }
      digitalWrite(RED, 1);
      digitalWrite(GREEN, 0);
      digitalWrite(BLUE, 0);
    } else {
      digitalWrite(buzzer, 0);
      digitalWrite(RED, 0);
      digitalWrite(GREEN, 0);
      digitalWrite(BLUE, 0);
    }
  } else {
    hardwareErrState = 1;
    if (totMillis - lastMillis > tempErrTm) {
      lastMillis = totMillis;
      if (buzzerState == 1) {
        digitalWrite(buzzer, 1);
      }
      digitalWrite(RED, 1);
      digitalWrite(GREEN, 1);
      digitalWrite(BLUE, 1);
    } else {
      digitalWrite(buzzer, 0);
      digitalWrite(RED, 0);
      digitalWrite(GREEN, 0);
      digitalWrite(BLUE, 0);
    }
  }
  static float aveT1 = sensors.getTempCByIndex(0);
  static float totT1 = aveT1;
  static char charAveT1[9];
  static char charTotT1[9];
  static char charTemp[9];
  dtostrf(aveT1, 7, 2, charAveT1);
  dtostrf(totT1, 8, 2, charTotT1);
  dtostrf(sensors.getTempCByIndex(0), 7, 2, charTemp);
  if (totMillis > tSample) {
    nSample += 1;
    aveT1 = totT1 / nSample;
    totT1 += sensors.getTempCByIndex(0);
    sensors.requestTemperatures();
    char sampleData[70];
    sprintf(sampleData, "Sample: %d Sw: %d temp(°C):%s Ave:%s Tot:%s",
            nSample, floatSwState, charTemp, charAveT1, charTotT1);
    Serial.println(sampleData);
    tSample += sampleTm;
  }

  if (highTempErrState == 0 && hardwareErrState == 0 && floatSwErrState == 0) {

    digitalWrite(buzzer, 0);
  }


  // OPEN FILE:
  /********************************************************************************************************************************************************************************/
  char aveData[20];
  char charTmDayInS[7];
  dtostrf(tmDayInS, 5, 0, charTmDayInS);
  sprintf(aveData, "%ls %d%s", charTmDayInS, floatSwState, charAveT1);
  dataFile = SD.open(fullPath, FILE_WRITE);
  if (dataFile) {
    if (totMillis > tLog) {
      dataFile.println(aveData);
      Serial.println("#Time Sw Temp");
      Serial.println(aveData);
      tLog += logTm;
    }
    if (nSample > 7) {
      nSample = 0;
      totT1 = sensors.getTempCByIndex(0);
    }
  } else {
    printAll(F("File write Err"));
    lcd.clear();
    printAll(F("File write Err"));
    hardwareErr();
  }

  // ALARM
  /********************************************************************************************************************************************************************************/
  static bool lastBTstate = 0;
  unsigned long lastDebounceTime = 0;
  const byte debounceDelay = 50;
  lcd.setCursor(13, 1);
  lcd.print("  ALARM");
  int newBTstate = analogRead(buzzerTogglePin) < 500 ? 1 : 0;
  if (newBTstate != lastBTstate) {
    lastDebounceTime = totMillis;
  }
  if ((totMillis - lastDebounceTime) > debounceDelay) {
    if (newBTstate != BTstate) {
      BTstate = newBTstate;
      if (BTstate == 1) {
        buzzerState = !buzzerState;
      }
    }
  }
  lcd.setCursor(17, 2);
  if (buzzerState == 1) {

    lcd.print(" ON");
  }

  else if (buzzerState == 0) {

    lcd.print("OFF");
  }
  lastBTstate = newBTstate;

  dataFile.close();
}

// SETUP() FUNCTION
/********************************************************************************************************************************************************************************/
void setup() {
  Serial.begin(115200);
  tStart = millis();
  initialisation();
  createFileAndName();
  firstWrite();
}

// LOOP() FUNCTION
/********************************************************************************************************************************************************************************/
void loop() {
  DatalogAndDiagnostics();
}

// END OF PROGRAM
/********************************************************************************************************************************************************************************/

obviously the SSID and password are written in the actual sketch, I just don't want to post that online!

these pins are valid for your Nano but not suitable for an ESP32

You need to adjust those to the pins used by your specific ESP32 for I2C and SPI.

remember also that your ESP32 is a 3.3V device and that your Nano was a 5V device, so ensure voltage are suitable or provide adaptation where necessary.

I'm using arduino's nano ESP32- the pinout is available here:

ABX00083-full-pinout.pdf (arduino.cc)

As it is in the arduino IDE, I can use arduino's pin configurations.

I am also using VBUS for the voltage, which is being supplied via my computer through a USB-C - USB-C cable, supplying regulated 5V DC to the hardware, which is necessary for the LCD to run brightly and the SD adapter module for the logic and level shifter.

I've also looked at the SPI and I2C configurations, which are the same for any other standard nano.

The problem is even after uploading my sketch (the code available above) the previous code that was uploaded remains on the board, no matter what. I've even tried copying my code into a new sketch and uploading it there, but it just doesn't upload. I'm running a simple counter sketch right now and the serial output remains as the counter sketch, rather than my project sketch.

well then that's the first thing you need to sort out...

I don't have that board

well that was the reason I created this topic in the first place...

Thanks for your help!

if you try to compile and upload this

void setup() {
	Serial.begin(115200); 
	while (!Serial);
	Serial.println("Hello World");
}

void loop() {}

what do you see?

I see:

Hello World

Then I upload my project sketch and I see:

Hello World

I then reset the arduino with the on-board reset button and I see:

Hello World

I also try entering bootloader mode by clicking the reset button twice and uploading my project code and I see- as you can already predict:

nothing.

OK that's a good start, it means uploading code works and the Serial monitor works too.

what's your SD module and how did you connect it exactly to the ESP32 Nano? can you show a picture?

I have the SD adapter module by AZ delivery from amazon

The wiring is included in the sketch at the start (the ASCII art wasn't just for cosmetic purposes):

CS pin - D10
MOSI pin - D11
MISO pin - D12
SCK pin - D13
GND - GND
VCC - VBUS

It's just weird that the only sketch that doesn't upload is my project sketch. I have all compiler warnings on now, and have appended the code accordingly, but it still just spurts "Hello World" at me, even after entering bootloader mode now.

if you try to compile this

#include <SD.h>
/*
   CS pin - D10
  MOSI pin - D11
  MISO pin - D12
  SCK pin - D13
  GND - GND
  VCC - VBUS
*/

void setup() {
  Serial.begin(115200);
  while (!Serial);

  if (!SD.begin(10)) {
    Serial.println("Card Mount Failed");
    return;
  }
  uint8_t cardType = SD.cardType();
  if (cardType == CARD_NONE) {
    Serial.println("No SD card attached");
    return;
  }
  Serial.print("SD Card Type: "); Serial.println(cardType);
}

void loop() {}

what do you see?

I get:

c:/users/christopher.donnelly/appdata/local/arduino15/packages/esp32/tools/xtensa-esp32s3-elf-gcc/esp-2021r2-patch5-8.4.0/bin/../lib/gcc/xtensa-esp32s3-elf/8.4.0/../../../../xtensa-esp32s3-elf/bin/ld.exe: C:\Users\christopher.donnelly\AppData\Local\Temp\arduino\cores\esp32_esp32_nano_nora_91c475973af02f9e78ad9bc85833a62e\core.a(main.cpp.o):(.literal._Z8loopTaskPv+0x8): undefined reference to `loop()'
c:/users/christopher.donnelly/appdata/local/arduino15/packages/esp32/tools/xtensa-esp32s3-elf-gcc/esp-2021r2-patch5-8.4.0/bin/../lib/gcc/xtensa-esp32s3-elf/8.4.0/../../../../xtensa-esp32s3-elf/bin/ld.exe: C:\Users\christopher.donnelly\AppData\Local\Temp\arduino\cores\esp32_esp32_nano_nora_91c475973af02f9e78ad9bc85833a62e\core.a(main.cpp.o): in function `loopTask(void*)':
C:\Users\christopher.donnelly\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.11\cores\esp32/main.cpp:50: undefined reference to `loop()'
collect2.exe: error: ld returned 1 exit status
Multiple libraries were found for "SD.h"
  Used: C:\Users\christopher.donnelly\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.11\libraries\SD
  Not used: C:\Users\christopher.donnelly\AppData\Local\Arduino15\libraries\SD
Using library SD at version 2.0.0 in folder: C:\Users\christopher.donnelly\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.11\libraries\SD 
Using library FS at version 2.0.0 in folder: C:\Users\christopher.donnelly\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.11\libraries\FS 
Using library SPI at version 2.0.0 in folder: C:\Users\christopher.donnelly\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.11\libraries\SPI 
exit status 1

Compilation error: exit status 1

did you forget to copy the

in the sketch?

Yeah, sorry lol. Been busy and I'm running off a few hours of sleep. I just get:

SD Card Type: 3

There is only an issue with certain sketches for some reason

try to open a file and write something in there and then read it back

It can't write anything to the ESP32. I tried the datalogger example sketch from the SD library with a regular nano and the ESP32: the nano worked fine but the ESP32 just spits out:

error opening datalog.txt

to the serial monitor

write a simple code for the time being

#include <SD.h>
/*
   CS pin - D10
  MOSI pin - D11
  MISO pin - D12
  SCK pin - D13
  GND - GND
  VCC - VBUS
*/

void setup() {
  Serial.begin(115200);
  while (!Serial);

  if (!SD.begin(10)) {
    Serial.println("Card Mount Failed");
    return;
  }
  uint8_t cardType = SD.cardType();
  if (cardType == CARD_NONE) {
    Serial.println("No SD card attached");
    return;
  }
  Serial.print("SD Card Type: "); Serial.println(cardType);

  File myFile = SD.open("test.txt", FILE_WRITE);;

  // if the file opened fine, write to it:
  if (myFile) {
    Serial.print("Writing to test.txt...");
    myFile.println("testing 1, 2, 3.");
    myFile.close();
    Serial.println("done.");
  } else {
    Serial.println("error opening test.txt for write");
    return;
  }

  // re-open the file for reading:
  myFile = SD.open("test.txt");
  if (myFile) {
    Serial.println("test.txt:");
    while (myFile.available())  Serial.write(myFile.read());
    // close the file:
    myFile.close();
  } else {
    Serial.println("error opening test.txt for read");
  }
}

void loop() {}

That code gives me an error too. This code works, I think it is just because I'm using FS to write to the SDHC card as opposed to the SD library:

/*
 * Connect the SD card to the following pins:
 *
 * SD Card | ESP32 NANO
 * GND          GND     
 * VCC           VCC
 * MOSI        D11  
 *MISO         D12
 *SCK            D13
 *CS              D10
 */
#include "FS.h"
#include "SD.h"
#include "SPI.h"

void listDir(fs::FS &fs, const char * dirname, uint8_t levels){
    Serial.printf("Listing directory: %s\n", dirname);

    File root = fs.open(dirname);
    if(!root){
        Serial.println("Failed to open directory");
        return;
    }
    if(!root.isDirectory()){
        Serial.println("Not a directory");
        return;
    }

    File file = root.openNextFile();
    while(file){
        if(file.isDirectory()){
            Serial.print("  DIR : ");
            Serial.println(file.name());
            if(levels){
                listDir(fs, file.path(), levels -1);
            }
        } else {
            Serial.print("  FILE: ");
            Serial.print(file.name());
            Serial.print("  SIZE: ");
            Serial.println(file.size());
        }
        file = root.openNextFile();
    }
}

void createDir(fs::FS &fs, const char * path){
    Serial.printf("Creating Dir: %s\n", path);
    if(fs.mkdir(path)){
        Serial.println("Dir created");
    } else {
        Serial.println("mkdir failed");
    }
}

void removeDir(fs::FS &fs, const char * path){
    Serial.printf("Removing Dir: %s\n", path);
    if(fs.rmdir(path)){
        Serial.println("Dir removed");
    } else {
        Serial.println("rmdir failed");
    }
}

void readFile(fs::FS &fs, const char * path){
    Serial.printf("Reading file: %s\n", path);

    File file = fs.open(path);
    if(!file){
        Serial.println("Failed to open file for reading");
        return;
    }

    Serial.print("Read from file: ");
    while(file.available()){
        Serial.write(file.read());
    }
    file.close();
}

void writeFile(fs::FS &fs, const char * path, const char * message){
    Serial.printf("Writing file: %s\n", path);

    File file = fs.open(path, FILE_WRITE);
    if(!file){
        Serial.println("Failed to open file for writing");
        return;
    }
    if(file.print(message)){
        Serial.println("File written");
    } else {
        Serial.println("Write failed");
    }
    file.close();
}

void appendFile(fs::FS &fs, const char * path, const char * message){
    Serial.printf("Appending to file: %s\n", path);

    File file = fs.open(path, FILE_APPEND);
    if(!file){
        Serial.println("Failed to open file for appending");
        return;
    }
    if(file.print(message)){
        Serial.println("Message appended");
    } else {
        Serial.println("Append failed");
    }
    file.close();
}

void renameFile(fs::FS &fs, const char * path1, const char * path2){
    Serial.printf("Renaming file %s to %s\n", path1, path2);
    if (fs.rename(path1, path2)) {
        Serial.println("File renamed");
    } else {
        Serial.println("Rename failed");
    }
}

void deleteFile(fs::FS &fs, const char * path){
    Serial.printf("Deleting file: %s\n", path);
    if(fs.remove(path)){
        Serial.println("File deleted");
    } else {
        Serial.println("Delete failed");
    }
}

void testFileIO(fs::FS &fs, const char * path){
    File file = fs.open(path);
    static uint8_t buf[512];
    size_t len = 0;
    uint32_t start = millis();
    uint32_t end = start;
    if(file){
        len = file.size();
        size_t flen = len;
        start = millis();
        while(len){
            size_t toRead = len;
            if(toRead > 512){
                toRead = 512;
            }
            file.read(buf, toRead);
            len -= toRead;
        }
        end = millis() - start;
        Serial.printf("%u bytes read for %u ms\n", flen, end);
        file.close();
    } else {
        Serial.println("Failed to open file for reading");
    }


    file = fs.open(path, FILE_WRITE);
    if(!file){
        Serial.println("Failed to open file for writing");
        return;
    }

    size_t i;
    start = millis();
    for(i=0; i<2048; i++){
        file.write(buf, 512);
    }
    end = millis() - start;
    Serial.printf("%u bytes written for %u ms\n", 2048 * 512, end);
    file.close();
}

void setup(){
    Serial.begin(115200);
    while(!Serial);
    if(!SD.begin()){
        Serial.println("Card Mount Failed");
        return;
    }
    uint8_t cardType = SD.cardType();

    if(cardType == CARD_NONE){
        Serial.println("No SD card attached");
        return;
    }

    Serial.print("SD Card Type: ");
    if(cardType == CARD_MMC){
        Serial.println("MMC");
    } else if(cardType == CARD_SD){
        Serial.println("SDSC");
    } else if(cardType == CARD_SDHC){
        Serial.println("SDHC");
    } else {
        Serial.println("UNKNOWN");
    }

    uint64_t cardSize = SD.cardSize() / (1024 * 1024);
    Serial.printf("SD Card Size: %lluMB\n", cardSize);

    listDir(SD, "/", 0);
    createDir(SD, "/mydir");
    listDir(SD, "/", 0);
    removeDir(SD, "/mydir");
    listDir(SD, "/", 2);
    writeFile(SD, "/hello.txt", "Hello ");
    appendFile(SD, "/hello.txt", "World!\n");
    readFile(SD, "/hello.txt");
    deleteFile(SD, "/foo.txt");
    renameFile(SD, "/hello.txt", "/foo.txt");
    readFile(SD, "/foo.txt");
    testFileIO(SD, "/test.txt");
    Serial.printf("Total space: %lluMB\n", SD.totalBytes() / (1024 * 1024));
    Serial.printf("Used space: %lluMB\n", SD.usedBytes() / (1024 * 1024));
}

void loop(){

}

You pass SD as the file system

But anyway if 5hat works like this, use that in your code

The problem is, I'm not sure how to implement it into my code without changing a large area of my project code. It's weird that the simplest of code doesn't work

I'm not sure what's going on with the arduino nano ESP32... It's true that on an ESP32 you would rather use Espressif's API and so you probably would need to consider changing that in the code even if it's a lot of work