I'm trying to feed a variable in as a file name for SD.open() with no luck. If I use a defined character string it works fine.
myFile = SD.open("sample_0000.txt", FILE_WRITE);
I'm generating my file names using Strings and I know that SD.open() doesn't support Strings. I've found several posts on this forum along these lines but was unable to make a solution work.
I've tried the following methods of conversion with no success:
// currentFileName is a String defined earlier and in a fixed 11.3 format
char fileName_converted[16];
currentFileName.toCharArray(fileName_converted, 16);
myFile = SD.open(fileName_converted, FILE_WRITE);
if (myFile){
Serial.println("File open was successful.");
myFile.println("test");
myFile.close();
}
and
// currentFileName is a String defined earlier and in a fixed 11.3 format
myFile = SD.open(currentFileName.c_str(), FILE_WRITE);
if (myFile){
Serial.println("File open was successful.");
myFile.println("test");
myFile.close();
}
Can anyone help me figure out why I can't seem to convert this String to a proper character array that SD.open() will like?
I believe SD.open() has an overload for String, so using a String as an argument should work.
Basic diagnostic practise says that you should print out your converted string to serial to see what it looks like.
It would be more useful to post a minimal compilable sketch that exhibits the issue, rather than a bunch of fragments. In particular we would need to see how currentFileName is constructed and used.
Hi thanks for the feedback! I actually took a bajillion print statements out of the above code to make it easier to read - I can find no differences between the data in the examples even when I go through the character array a character at a time and print it. Below is the same code but included in a format that I think you can copy, paste, and run. Beyond the copy and paste, just call the function generateNewFile()in your setup function and it should work fine.
The board is an Adafruit Feather M0 Adalogger, since I failed to mention that above.
In all examples below, seeing the text "File open was successful." indicates success.
This is the standard code you'll find in most examples and it works fine. Note the hardcoded file name.
#include <SPI.h>
#include <SD.h>
Sd2Card card;
SdVolume volume;
SdFile root;
const int chipSelect = 4;
int fileNum = 0;
String fileName = "sample_";
String extension = ".txt";
bool outOfFiles = false;
void generateNewFile()
{
String currentFileName = "";
String stringNum = "";
File myFile;
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.print("\nInitializing SD card...");
// we'll use the initialization code from the utility libraries
// since we're just testing if the card is working!
if (!card.init(SPI_HALF_SPEED, chipSelect)) {
Serial.println("initialization failed. Things to check:");
Serial.println("* is a card inserted?");
Serial.println("* is your wiring correct?");
Serial.println("* did you change the chipSelect pin to match your shield or module?");
while (1);
//replace while with interrupt code to gracefully handle the error
} else {
Serial.println("Wiring is correct and a card is present.");
}
// Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32
if (!volume.init(card)) {
Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card");
while (1);
}
if (!SD.begin(4)) {
Serial.println("initialization failed!");
while (1);
}
if (fileNum < 10){
stringNum = "000" + String(fileNum, DEC);
}
else if (fileNum < 100){
stringNum = "00" + String(fileNum, DEC);
}
else if (fileNum < 1000){
stringNum = "0" + String(fileNum, DEC);
}
else {
stringNum = String(fileNum, DEC);
}
currentFileName = fileName + stringNum + extension;
Serial.println(currentFileName);
fileNum++;
if (fileNum > 9999){
outOfFiles = true;
}
myFile = SD.open("testfile.txt", FILE_WRITE);
if (myFile){
Serial.println("File open was successful.");
myFile.println("test");
myFile.close();
}
Serial.println("File operation complete.");
}
So with the above code we can demonstrate that everything works and things are talking as they should. The next examples illustrate my problem of converting the String I want to use (currentFileName) to a form SD.open() will accept. None of the following methods generate a file on the micro SD card (they are in following posts, since everything together was too long for a single post).
This example attempts to convert the String currentFileName to a character array.
#include <SPI.h>
#include <SD.h>
Sd2Card card;
SdVolume volume;
SdFile root;
const int chipSelect = 4;
int fileNum = 0;
String fileName = "sample_";
String extension = ".txt";
bool outOfFiles = false;
void generateNewFile()
{
String currentFileName = "";
String stringNum = "";
File myFile;
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.print("\nInitializing SD card...");
// we'll use the initialization code from the utility libraries
// since we're just testing if the card is working!
if (!card.init(SPI_HALF_SPEED, chipSelect)) {
Serial.println("initialization failed. Things to check:");
Serial.println("* is a card inserted?");
Serial.println("* is your wiring correct?");
Serial.println("* did you change the chipSelect pin to match your shield or module?");
while (1);
//replace while with interrupt code to gracefully handle the error
} else {
Serial.println("Wiring is correct and a card is present.");
}
// Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32
if (!volume.init(card)) {
Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card");
while (1);
}
if (!SD.begin(4)) {
Serial.println("initialization failed!");
while (1);
}
if (fileNum < 10){
stringNum = "000" + String(fileNum, DEC);
}
else if (fileNum < 100){
stringNum = "00" + String(fileNum, DEC);
}
else if (fileNum < 1000){
stringNum = "0" + String(fileNum, DEC);
}
else {
stringNum = String(fileNum, DEC);
}
currentFileName = fileName + stringNum + extension;
Serial.println(currentFileName);
fileNum++;
if (fileNum > 9999){
outOfFiles = true;
}
char fileName_converted[16];
currentFileName.toCharArray(fileName_converted, 16);
Serial.println(fileName_converted);
for (int i=0; i<16; i++){
Serial.print(fileName_converted[i]);
}
Serial.println(".");
myFile = SD.open(fileName_converted, FILE_WRITE);
if (myFile){
Serial.println("File open was successful.");
myFile.println("test");
myFile.close();
}
Serial.println("File operation complete.");
}
This example attempts to use another method of Stringto do the conversion for me:
#include <SPI.h>
#include <SD.h>
Sd2Card card;
SdVolume volume;
SdFile root;
const int chipSelect = 4;
int fileNum = 0;
String fileName = "sample_";
String extension = ".txt";
bool outOfFiles = false;
void generateNewFile()
{
String currentFileName = "";
String stringNum = "";
File myFile;
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.print("\nInitializing SD card...");
// we'll use the initialization code from the utility libraries
// since we're just testing if the card is working!
if (!card.init(SPI_HALF_SPEED, chipSelect)) {
Serial.println("initialization failed. Things to check:");
Serial.println("* is a card inserted?");
Serial.println("* is your wiring correct?");
Serial.println("* did you change the chipSelect pin to match your shield or module?");
while (1);
//replace while with interrupt code to gracefully handle the error
} else {
Serial.println("Wiring is correct and a card is present.");
}
// Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32
if (!volume.init(card)) {
Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card");
while (1);
}
if (!SD.begin(4)) {
Serial.println("initialization failed!");
while (1);
}
if (fileNum < 10){
stringNum = "000" + String(fileNum, DEC);
}
else if (fileNum < 100){
stringNum = "00" + String(fileNum, DEC);
}
else if (fileNum < 1000){
stringNum = "0" + String(fileNum, DEC);
}
else {
stringNum = String(fileNum, DEC);
}
currentFileName = fileName + stringNum + extension;
Serial.println(currentFileName);
fileNum++;
if (fileNum > 9999){
outOfFiles = true;
}
Serial.println(currentFileName.c_str());
myFile = SD.open(currentFileName.c_str(), FILE_WRITE);
if (myFile){
Serial.println("File open was successful.");
myFile.println("test");
myFile.close();
}
Serial.println("File operation complete.");
}
Finally, here is an example of just using the String currentFileNamewith no conversion.
#include <SPI.h>
#include <SD.h>
Sd2Card card;
SdVolume volume;
SdFile root;
const int chipSelect = 4;
int fileNum = 0;
String fileName = "sample_";
String extension = ".txt";
bool outOfFiles = false;
void generateNewFile()
{
String currentFileName = "";
String stringNum = "";
File myFile;
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.print("\nInitializing SD card...");
// we'll use the initialization code from the utility libraries
// since we're just testing if the card is working!
if (!card.init(SPI_HALF_SPEED, chipSelect)) {
Serial.println("initialization failed. Things to check:");
Serial.println("* is a card inserted?");
Serial.println("* is your wiring correct?");
Serial.println("* did you change the chipSelect pin to match your shield or module?");
while (1);
//replace while with interrupt code to gracefully handle the error
} else {
Serial.println("Wiring is correct and a card is present.");
}
// Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32
if (!volume.init(card)) {
Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card");
while (1);
}
if (!SD.begin(4)) {
Serial.println("initialization failed!");
while (1);
}
if (fileNum < 10){
stringNum = "000" + String(fileNum, DEC);
}
else if (fileNum < 100){
stringNum = "00" + String(fileNum, DEC);
}
else if (fileNum < 1000){
stringNum = "0" + String(fileNum, DEC);
}
else {
stringNum = String(fileNum, DEC);
}
currentFileName = fileName + stringNum + extension;
Serial.println(currentFileName);
fileNum++;
if (fileNum > 9999){
outOfFiles = true;
}
myFile = SD.open(currentFileName, FILE_WRITE);
if (myFile){
Serial.println("File open was successful.");
myFile.println("test");
myFile.close();
}
Serial.println("File operation complete.");
}