How to assign a variable to SD.open()

HELP!
This is on an UNO board.

If I use
myFile = SD.open("Results.txt", FILE_WRITE);
everything works perfectly.

However, if I try to use any variable such as
char myFileName[] = "Results.txt";
myFile = SD.open(myFileName, FILE_WRITE);
it fails.

I also tried
char myFileName[] = "Results.txt";
myFile = SD.open(filename.c_str(), FILE_WRITE);
But that fails also.

How do I assign a variable for the file name?

This should have worked.

This should fail because 'filename' is not defined. If you had used the expression "myFileName.c_str()" it should fail because "myFileName" is a character array, not a "String".

Sorry that was a typo, I did use myFileName.

It compiles on IDE but fails when it runs on the board when I use any variable instead of writing the file name in quotes.

There is nothing wrong with this snippet, so the problem is in the code you forgot to post.

char myFileName[] = "Results.txt";
myFile = SD.open(myFileName, FILE_WRITE);

Post ALL the code, and the error messages.

There is nothing wrong with the code other than when I try to use a variable. It works with a static name.

I just came across a note that FAT32 SD cards must follow the 8.3 file naming convention.

I'm thinking that my variable file name has more than 8 characters...

Good luck with your project.

Here it is...

#include <SPI.h>                                      // Include the SPI library for Ethernet and SD card communication
#include <SD.h>                                       // Include the SD library for accessing files on the SD card
#include <Ethernet.h>                                 // Include the Ethernet library for Internet connectivity
#include <Wire.h>                                     // Include the Wire library for I2C communication
#include <LiquidCrystal_I2C.h>                        // Include the LiquidCrystal_I2C library for controlling the LCD display
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };  // Set up the MAC address of the Arduino using a byte array
EthernetClient client;                                // Create an instance of the EthernetClient class to handle Internet connectivity
File myFile;                                          // Declare a File object for accessing files on the SD card
LiquidCrystal_I2C lcd(0x27, 20, 4);                   // Create an instance of the LiquidCrystal_I2C class for controlling the LCD display
int myDelay = 3000;                                   // Set a delay of 3 seconds
char myFileName[] = "Results.txt";                    // Set the filename for the results file that will be created on the SD card

void setup() {
  lcd.init();                                        // Initialize the LCD display
  lcd.backlight();                                   // Turn on the backlight of the LCD display
  lcd.setCursor(0, 0);                               // Set the cursor position to the first row, first column
  lcd.print("VERSION 1           ");                 // Display a message on the LCD display
  lcd.setCursor(0, 1);                               // Set the cursor position to the second row, first column
  lcd.print("  NETWORK SCANNER   ");                 // Display a message on the LCD display
  delay(myDelay);                                    // Wait for a specified period of time
  lcd.clear();                                       // Clear the LCD display
  lcd.setCursor(0, 0);                               // Set the cursor position to the first row, first column
  lcd.print("Initializing Network");                 // Display a message on the LCD display
  Ethernet.begin(mac);                               // Initialize the Ethernet library with the specified MAC address
  delay(myDelay);                                    // Wait for the Ethernet shield to initialize
  lcd.setCursor(0, 0);                               // Set the cursor position to the first row, first column
  lcd.print("   Network Ready    ");                 // Display a message on the LCD display
  delay(myDelay);                                    // Wait for a specified period of time
  lcd.setCursor(0, 1);                               // Set the cursor position to the second row, first column
  lcd.print(" IP: ");                                // Display a message on the LCD display
  lcd.print(Ethernet.localIP());                     // Display the local IP address on the LCD display
  delay(myDelay);                                    // Wait for a specified period of time
  lcd.clear();                                       // Clear the LCD display
  lcd.setCursor(0, 0);                               // Set the cursor position to the first row, first column
  lcd.print("Initializing SD card");                 // Display a message on the LCD display
  delay(myDelay);                                    // Wait for a specified period of time
  if (!SD.begin(4)) {                                // If the SD card fails to initialize
    lcd.setCursor(0, 0);                             // Set the cursor position to the first row, first column
    lcd.println("init failed!        ");             // Display an error message on the LCD display
    while (1)                                        // Infinite loop to halt program execution
      ;                                              //
  }                                                  //
  lcd.setCursor(0, 0);                               // Set the cursor position to the first row, first column
  lcd.print("   SD Card Ready    ");                 // Display a message on the LCD display
  delay(myDelay);                                    // Wait for a specified period of time
  lcd.setCursor(0, 1);                               // Set the cursor position to the second row, first column
  lcd.print(myFileName);                             // Display the filename for the results file on the LCD display
  delay(myDelay);                                    // Wait for a specified period of time
  myFile = SD.open(myFileName, FILE_WRITE);  // Open a file on the SD card for writing and store the file object in "myFile"
  if (myFile) {                                      // If the file was opened successfully, execute the following code block
    myFile.println(Ethernet.localIP());              // Write the local IP address to the file
    pingScan();                                      // Call the "pingScan" function
    myFile.close();                                  // Close the file
    lcd.clear();                                     // Clear the LCD screen
    lcd.setCursor(0, 0);                             // Set the cursor to the top left corner of the LCD screen
    lcd.print("VERSION 1           ");               // Display the message on the first line of the LCD screen
    lcd.setCursor(0, 1);                             // Set the cursor to the beginning of the second line of the LCD screen
    lcd.print(" NETWORK SCANNER ");                  // Display the message " NETWORK SCANNER" on the second line of the LCD screen
    lcd.setCursor(0, 2);                             // Set the cursor to the beginning of the third line of the LCD screen
    lcd.print(" Scan Complete ");                    // Display the message " Scan Complete" on the third line of the LCD screen
    delay(myDelay);                                  // Delay for "myDelay" milliseconds
    lcd.setCursor(0, 3);                             // Set the cursor to the beginning of the fourth line of the LCD screen
    lcd.print("Results saved to SD ");               // Display the message "Results saved to SD" on the fourth line of the LCD screen
  } else {                                           // If the file failed to open, execute the following code block
    lcd.setCursor(0, 3);                             // Set the cursor to the beginning of the fourth line of the LCD screen
    lcd.println("Error Opening SD ");                // Display the message "Error Opening SD" on the fourth line of the LCD screen
  }                                                  //
  myFile = SD.open(myFileName);              // re-open the file for reading:
  if (myFile) {                                      //
    while (myFile.available()) {                     // read from the file until there's nothing else in it:
      Serial.write(myFile.read());                   //
    }                                                //
    myFile.close();                                  // close the file:
  } else {                                           //
    Serial.print("Error Closing SD    ");            // if the file didn't close, print an error:
  }
}

void loop() {
  // Future options here
}

void pingScan() {
  lcd.clear();                        // Clear the LCD screen
  lcd.setCursor(0, 0);                // Set the cursor to the top left corner of the LCD screen
  lcd.print("Scanning network... ");  // Display the message "Scanning network..." on the first line of the LCD screen
  delay(myDelay);                     // Delay for "myDelay" milliseconds
  for (int i = 1; i <= 12; i++) {     // Loop through a subset of IP addresses for testing purposes. Using 12 instead of 254 for time testing

    // Create an IPAddress object with the current IP address
    IPAddress address(Ethernet.localIP()[0], Ethernet.localIP()[1], Ethernet.localIP()[2], i);

    if (client.connect(address, 80)) {      // If the client is able to connect to the IP address on port 80
      client.stop();                        // Stop the client connection
      lcd.setCursor(0, 2);                  // Set the cursor to the beginning of the third line of the LCD screen
      lcd.print("IP Addresses Found ");     // Display the message "IP Addresses Found" on the third line of the LCD screen
      lcd.setCursor(0, 3);                  // Set the cursor to the beginning of the fourth line of the LCD screen
      lcd.print(" ");                       // Clear the fourth line of the LCD screen
      lcd.print(Ethernet.localIP()[0]);     // Display the first part of the local IP address on the fourth line of the LCD screen
      lcd.print(".");                       // Display a period on the fourth line of the LCD screen
      lcd.print(Ethernet.localIP()[1]);     // Display the second part of the local IP address on the fourth line of the LCD screen
      lcd.print(".");                       // Display a period on the fourth line of the LCD screen
      lcd.print(Ethernet.localIP()[2]);     // Display the third part of the local IP address on the fourth line of the LCD screen
      lcd.print(".");                       // Display a period on the fourth line of the LCD screen
      lcd.print(i);                         // Display the current IP address being scanned on the fourth line of the LCD screen
      myFile.print(Ethernet.localIP()[0]);  // Write the first part of the local IP address to the SD card file
      myFile.print(".");                    // Write a period to the SD card file
      myFile.print(Ethernet.localIP()[1]);  // Write the second part of the local IP address to the SD card file
      myFile.print(".");                    // Write a period to the SD card file
      myFile.print(Ethernet.localIP()[2]);  // Write the third part of the local IP address to the SD card file
      myFile.print(".");                    // Write a period to the SD card file
      myFile.println(i);                    // Write the current IP address being scanned to the SD card file
    }
  }
}

The error is not from IDE, it is from the code "Error Opening SD "

On the Uno, you could be running out of memory, with unpredictable results. Post the link message that describes the memory usage statistics. Keep in mind that the SD library uses 1/4 of SRAM for the file buffer, when opening a file.

To save SRAM memory, all the string constants in print() statements should be put into flash memory using the F macro, e.g. replace this:

lcd.print("Initializing Network");                 // Display a message on the LCD display

with this:

lcd.print(F("Initializing Network"));                 // Display a message on the LCD display
 

Sketch uses 25744 bytes (79%) of program storage space. Maximum is 32256 bytes.
Global variables use 1742 bytes (85%) of dynamic memory, leaving 306 bytes for local variables. Maximum is 2048 bytes.

Yep, SRAM is the problem. SD.open() fails to allocate the file buffer.

And here it is after adding "(F".

Sketch uses 25846 bytes (80%) of program storage space. Maximum is 32256 bytes.
Global variables use 1452 bytes (70%) of dynamic memory, leaving 596 bytes for local variables. Maximum is 2048 bytes.

You may still not have enough memory for the program to run correctly. The file buffer takes 512 bytes.

You DA man!

It runs perfect now....

Does the file open as expected, given the 596 bytes free from the last memory report?

Even if it does, that does not guarantee long term stability.

Yes, I pulled the SD card out, read it and everything was there.

The last step is to squeeze a way for the variable to assign a unique file name... :sob:

You are really, really short on space, but here is a minimalist approach to assign consecutive file names: 100.txt, 101.txt, etc.

char fileName[13]={0};
fileCount = 100; //starting file number, could be in EEPROM
itoa(fileCount,fileName,10);  //make ASCII
fileCount++; //next file name
strncat(fileName,".txt",sizeof(fileName));  //add .txt extension
myFile = SD.open(fileName, FILE_WRITE);

This would start the count each time it boots at 100.txt correct?

I think with the memory squeeze I have I'll just need to stick to static file names and manually delete them after each scan after all...

Thank you for taking the time to help with that though.

It just blows that just adding the libraries for the ethernet/SD shield it practically bricks the board...

There are lots of ARM and ESP-based boards out there that have way more resources (and faster processors) than an Uno. Many are cheaper too.

Use SD.exists(filename) to skip the used names.

How much effort is involved to get the code and hardware to one of those?