Can't get SD.open to work in nested if statement.

The Hardware

Arduino Mega
Elegoo 2.8" TFT touchscreen display with SD slot

The Code
due to the length I am going to post the part I have a problem with, and put the full thing in an attachment.

    if (p.x > 230 && p.x < 280 && p.y > 10 && p.y < 40) //Sets up push for enter button -SFO
    {
      /*The first portion of this button draws over the keypad to give a 'blank slate'.
         The second portaion takes the ASCII value of the numbers and translates them into
         the actual numbers by subtracting the ASCII value of 0 from them, and then holds
         them in the dgt variables. The tot variable then adds them up.
         The third section is an if statment, the maximum value of all added digits
         should never be over 36 (9*4) for a four digit number, unless one digit was
         still an X, which has a value of 88, or 40 after the ASCII value for 0 has been
         subtracted. If using for a 5 digit number, you will either need to change 88 (X)
         to 126 (~) or 196 (─) as the new sum would be maxed at 45, and thus would be possible
         to go past this point with the other digits adding to less than 6. If this check passes
         it outputs to a red LED and throws an error message, if it fails it continues on. -SFO

         Each scenario (invalid entry, valid entry/valid user, valid entry/invalid user) will then
         light a red or green LED and holds a message for 5 seconds, then resets to the beginning of
         the code. Eventually each entry (valid/invalid) will be logged to the same place as the
         user codes. -SFO
      */
      tft.fillRect(8, 100, 231, 306, BLACK);
      dgt1 = dig1 - 48;
      dgt2 = dig2 - 48;
      dgt3 = dig3 - 48;
      dgt4 = dig4 - 48;
      tot = dgt1 + dgt2 + dgt3 + dgt4;
      //Within the if coding, it will throw an error if the sum is over 36.
      if (tot > 36) {
        tft.setCursor(10, 100);
        tft.setTextColor(RED);
        tft.print("  INVALID      INPUT");
        pinMode(51, OUTPUT);
        digitalWrite(51, HIGH);
        myFile = SD.open(fileName, FILE_WRITE);
        Serial.println("File opened.");
        myFile.print("Invalid Entry - Not a full code: ");
        myFile.print(timeStamp);
        myFile.println(";");
        Serial.println("Entry Written");
        myFile.close();
        Serial.println("File Closed");
        delay(5000);
        digitalWrite(51, LOW);
        softwareReset();

      }
void softwareReset() {
  asm volatile (" jmp 0");
}

The Problem

I cannot get the SD.open/SD.print/SD.println/SD.close functions to work. I get the serial code I have left around the code printed, but no file is written to the SD card. I can get the code to work when I paste it directly in the setup or loop section, and I can make it a function and call it from the same places, but I cannot seem to get it to work nested in my code.

I also apologize about the attached code. I patchworked most of it from various sources until I got something that worked, and I left myself crazy detailed comments on any portion I understood/ made myself.

The goal of this project is to have a keypad that will allow access to a restricted area using an employee ID# and log any attempts (successful or not) to get in. The portion I am working on is the “Invalid Entry” portion that checks to see if all 4 numbers have been entered, It throws the error nicely but does not log it.

Also I am not using the standard SD library, I am using this one so I can get the SD reader portion of my working without problems (the library allows SD on any pin).

SD card is 4gb FAT formatted.

Code.txt (25.4 KB)

One possible issue is that your file names may get too big:

sprintf(fileName, "%08lu.txt", date);

I believe you are restricted to an "8.3" format at least with the standard SD card library.

If you still have trouble, lift the core code out into a separate sketch and then add to it until you can duplicate the failure. I doubt if the problem is related to the structure of an "if" statement and is more likeley to be a basic SD card library issue or a conflict such as with pin 13 which you appear to be directly using and is also managed by SPI.

Could you please elaborate on the 8.3 format portion? and I was under the impression the MEGA uses 50,51,52, and 53, is this not so? Other than that I think I am going to start simplifying my code and breaking down the loop section into called functions, and see if that works.

EDIT: Found the pin 13 output you were talking about, have to figure out what I put that there for.

8.3 = max 8 character name then a dot then a max 3 character extension (old MS DOS format).

eg. ABC123LU.txt
but not, for example, ABCD1234LU.txt (which is too long )

Sorry. I didn't notice you were using a Mega. The pin13 comment is not relevant to a Mega because, as you have said, 50-53 are the SPI pins there.

Some reason I thought 8.3 was a firmware version of some sort. I do have the name in 8.3 format, it'll print as the date in YYYYMMDD.txt format. I've also removed the seemingly useless pinmode I had for 13 stuck in there, I'm in the middle of condensing the code, I'll post when I'm done.

Figured it out:

  char fileName[13]; //variable to name file, will hold date later
  char timeStamp[8]; //variable to put timestamp in file, will hold time later
  sprintf(fileName, "%08lu.txt", date);
  sprintf(timeStamp, "%04lu.txt", tme);

Needed to be:

  char fileName[13]; //variable to name file, will hold date later
  char timeStamp[5]; //variable to put timestamp in file, will hold time later
  sprintf(fileName, "%08lu.txt", date);
  sprintf(timeStamp, "%04lu", tme);

Something in the old was corrupting the .txt portion of fileName and it couldn't create the file because of it. I had apparently been pasting a good copy from the simple sketch I made to test functionality, while the typed version I commented out a few times had the error in it, thus making it work when I moved it, but not when I put it back.