Creating SD file with variable name

Hello everybody,

currently I am setting up a device to measure the brightness of a display and save the measured data to an SD card. Since I do not want a fixed name for the file but read it in via the serial monitor. I looked through a lot of threads here but cannot solve it anyhow. As far as I understood the String from serial read must be converted to a string but the .c_str() is not working. Can anybody help me here ?

#include <SPI.h>
#include <SD.h>

const int CSmemory = 9;          //Chip select for SD card module
const int aInput1 = A0;
const int aInput2 = A1;
const int aInput3 = A2;

String cali = "";
String measname = "";
void setup() {
  Serial.begin(9600);
  pinMode(CSmemory, OUTPUT);
  pinMode(aInput1, INPUT);
  pinMode(aInput2, INPUT);
  pinMode(aInput3, INPUT);
  int ADCread1 = 0;
  int zw = 0;
  int topvalue = 0;
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }


  Serial.print("Initializing SD card...");

  // see if the card is present and can be initialized:
  if (!SD.begin(CSmemory)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    while (1);
  }
  Serial.println("card initialized.");

  SPI.begin();

  Serial.print("Name of measurment?"); //here starts the naming process
  while (Serial.available() == 0) {}
  measname = Serial.readString();
  Serial.print("I received ");
  Serial.println(measname);
  File dataFile = SD.open(measname.c_str(), FILE_WRITE);
  if (dataFile) {
    do{
      ADCread1 = analogRead(aInput1);
    }while (ADCread1 <40);
    for (int i = 0; i < 256; i++) {
      ADCread1 = analogRead(aInput1);
      dataFile.println(ADCread1);
      if (i==255){
        topvalue = ADCread1;
      }
    }
  dataFile.flush();
  Serial.print("Finish rise measurment"); 
  
  if (dataFile) {
    do{
      ADCread1 = analogRead(aInput1);
    }while (ADCread1 >= topvalue-15);
    for (int i = 0; i < 256; i++) {
      ADCread1 = analogRead(aInput1);
      dataFile.println(ADCread1);      }
    }
  dataFile.close();
  Serial.print("Finish complete measurment");
  }



}
void loop() {
}

How do you know ?

Well normally after the file creation the measurement starts as soon as there is a brightness change. This is not happening when I am not using something like "test.txt" instead of the variable. So it might be that the command itself is working but no file is created

You could determine whether the file has been opened by adding an else clause to

  if (dataFile)
  {

rather than letting the sketch run on regardless

there is a "if (dataFile) , that is the reason why the sketch is not continuing after the creation, or in this case not-creation, of the file

Agreed, but it would be much more satisfactory to have a message telling you that the file had not been opened

What happens if you hard code the filename as a C string ?
Does the sketch work then ?

It is not possible to use Serial.readString with a C string / char array

I know, which is why I suggested hard coding the filename as a C style string to test the sketch

as I said, when I hard code the file name ( for example test.txt) the sketch works. It is only the naming process itself that is not working.

Hard code it as a String or a C style string ?

In your sketch that uses Strings what do you see when you print the filename after conversion from a String to a C style string ? Before you print it. print a ">" and after you print it using Serial.print() (not Serial.println()) print a "<". This will allow you to see whether there are hidden control characters such as Carriage Return and/or Linefeed as part of teh C string

I think when I put "text.txt" as the part of the SD.open command it converts it to a C string as standard.
Or do you mean something different?

It will be used as a C style constant string (lowercase s) but my point was that when you do

measname = Serial.readString();

I am not convinced that the value of measname is what you think. For instance, try this

String measname = "";

void setup()
{
  Serial.begin(115200);
  while (!Serial);
  while (Serial.available() == 0) {}
  measname = Serial.readString();
  Serial.print("I received ");
  Serial.print(">");
  Serial.print(measname);
  Serial.print("<");
}

void loop()
{
}

If you have the Line ending of the Serial monitor set to anything but No line ending then the output will be like this if you enter filename

I received >filename
<

Noye that the < is on a new line, which means that the String has an extra control character (or 2) on the end so no wonder you can't use it as a filename

Now do you see why I suggested

So, what do you see ?

Ah now I understood. I tried it as you said and unfortunately I cannot copy the serial monitor, but I have a new line after the name. so it seems that there are some extra control character(s?). How can I get rid of it ?

Set the Line ending in the Serial monitor to "No line ending"

You can copy text from the Serial monitor by selecting it with the mouse then using Ctrl+C to copy it to the clipboard

1 Like

wow thats it ? I searched for hours to solve this. now it works. thank you very much

I am glad that you got it working

When debugging do not take anything for granted. For instance, if and while tests may fail to do what you expect so it is helpful to print the values of what is being tested and in the case of your sketch if you had put an else on the if (dataFile) then you might had got an inkling that something was wrong in that area

The trick of adding start and end markers when printing Strings or strings is also something to consider doing so that you can see whether there are non printing characters at the start and end

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