How to enter a filename from Serial Monitor and use it to create a new data file?

Hello, I know how to save the data to a SD Card if I specify the filename in advance using

myFilename = SD.open("file1.txt", FILE_WRITE);

Could you please let me know what to do if I want the user to enter the filename in the Serial Monitor and then use it to create a new file to write the data to?

Here is a conceptual explanation.
Change your hard coded filename to a variable.
Add code to ask for the filename
wait for a response
read the data
verify it appears to be a valid filename
assign that data to the variable in step 1.

The easiest approach is to modify your code to receive a string from the serial monitor. You'll then need to validate the string to ensure it is correct before processing it. Since I don't know your skill level or the tools available to you, I should mention this likely won't be a simple one or two evening project.

I know how to do it in C/C++ but not in Arduino. Is asking for user input acceptable under setup() rather than inside loop()?

In another project, I was able to get the user input from the serial terminal and then do some processing inside loop(). For entering of the filename and creating the file, is it OK to do it inside setup()?

Arduino is programmed in C++.

Where and how you get your filename is… up to you.

Typically setup() is used for initialisation stuff, but there is no reason not to do anything that only needs be done once, at the beginning, right there.

Placed in the loop() or a function called from there, you could have some sort of condition that would make it ask you (again perhaps) for the filename when the need arose.

There is no right or wrong or better or worse about it.

a7

1 Like

That is not difficult. Make the filename a global character array, and the name entry can proceed in any part of the program.

The Serial Input Basics tutorial is a good place to start.

1 Like

I am able to use Example 2 of the tutorial but entering the filename in a loop is a bit counter intuitive for me.

How come even I have the scanf line, the Serial Monitor does not allow me to input the filename? scanf is called under setup()

char temp_filename[50] = "";
scanf("%s", &temp_filename);

Unlikely. The serial monitor has a small window in which you can type in a file name. Click on the window and start typing. Hit the "send" button when done.

I recommend that you read the Serial Input Basics tutorial linked above, and try the examples.

I tried Example2 and it worked. However, I want to know why my method of entering the file name using scanf in setup() does not work.
Here is the complete code:

#include <stdio.h>

FILE myFile;
char temp_name[50] = "";     // temporary filename
char filename[50]="";            // final filename 


void setup() 
{
  Serial.begin(9600);
  Serial.println("Enter name");
  scanf("%s", &temp_name);
  sprintf(filename, "%s.txt", temp_name);
  Serial.print(filename);
}

void loop() 
{
;
}

When I executed the code, the Serial Monitor printed a bunch of square followed by Enter name. Then, it printed .txt without giving me a chance to enter the name in the Message field.

scanf() doesn't work on Arduino, because there is no standard I/O file system.

Follow the instructions in the Serial Input Basics tutorial and you'll be fine.

1 Like

OK. In the else part of the while loop of Example 2, I opened the file with the file name I entered on the Serial Monitor. Although there was no error message, the program did not create the file. What is wrong?

while (Serial.available() > 0 && newData == false) {
        rc = Serial.read();

        if (rc != endMarker) {
            receivedChars[ndx] = rc;
            ndx++;
            if (ndx >= numChars) {
                ndx = numChars - 1;
            }
        }
        else {
            receivedChars[ndx] = '\0'; // terminate the string
            ndx = 0;
            newData = true;
            myFile = SD.open(receivedChars, FILE_WRITE);
        }
    }

here's code i'm using to set credentials for wifi

each cmd is delimited by a semicolon (:wink: allowing multiple commands to be on the same line terminated with a \n

the cmds setting string variables are multi-character, starting with an '_'. I use a single letter command, 'U' to update the strings in EEPROM

you can use a cmd to set the string and an 2nd cmd to create your file. cmd() is repeatedly called in loop()

#define MAX_TOKS   10
static int    _nToks;
static char * _toks [MAX_TOKS];
static int    _vals [MAX_TOKS];

int
_tokenize (
    char *s)
{
    int n = 0;
    for (_toks [n] = strtok (s, " "); _toks [n]; ) {
        _vals [n] = atoi (_toks [n]);
     // printf ("   %2d: %6d %s\n", n, _vals [n], _toks [n]);
        _toks [++n] = strtok (NULL, " ");
    }

    return _nToks = n;
}

// ---------------------------------------------------------

void cmds ()
{
    if (Serial.available ()) {
        char buf [90];
        int  n = Serial.readBytesUntil (';', buf, sizeof(buf)-1);
        buf [n] = '\0';

        if ('_' == buf [0])  {
            int nTok = _tokenize (&buf [1]);

            if (! strcmp (_toks [0], "host") && 2 == nTok)
                strcpy (host, _toks [1]);

            else if (! strcmp (_toks [0], "pass") && 2 == nTok)
                strcpy (pass, _toks [1]);

            else if (! strcmp (_toks [0], "ssid") && 2 == nTok)
                strcpy (ssid, _toks [1]);

            else {
                printf ("%s: invalid input\n", __func__);
                for (int n = 0; n < nTok; n++)
                    printf (" %s: %2d  %s\n", __func__, n, _toks [n]);
            }
        }
        else if ('r' == buf [0])
            run = ! run;
        else if ('U' == buf [0])
            eepromUpdate ();
        else
           printf ("cmds: invalid - %s\n",  buf);
    }
}

obviously such an approach can be used for many other types of cmds

Can't say, because you forgot to post the rest of the code.

Hint: many Arduino functions do not print error messages. You are responsible for checking error return values. For example

myFile = SD.open(receivedChars, FILE_WRITE);
if (!myFile) Serial.println("File open failure");
1 Like

It is a bit strange but after I added your checking code, it created a file on the SD card. Problem is why the resulting file name is made of capital letters even I entered lower case letters and the program confirmed this by printing the name in lower case letters on the Serial Monitor?

For help on this forum, please read and follow the instructions in the "How to get the best out of this forum" post, linked at the head of every forum category.

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