Pages: [1] 2   Go Down
Author Topic: String to character formatting for SD logging.  (Read 1449 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Full Member
***
Karma: 0
Posts: 164
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I want to get the date string from my DS1307 RTC and use that as a file name, checking if one exists and creating it if not. So that it will create a new file every day.

I'm trying to use this to save and write to a file where the name of the file is a string File_name retrieved from the RTC clock. But it doesn't work

Code:
for(int i=1;;i++)
  {
    String temp = File_name;
    temp.concat(i);
    temp.concat(".txt");
    char filename[temp.length()+1];
    temp.toCharArray(filename, sizeof(filename));

    if(!SD.exists(filename))
    {
      File dataFile = SD.open(filename,FILE_WRITE);
      break;
    

    if (dataFile)
    {
      dataFile.println(".");
      dataFile.close();
    }
    }
  }


If I use
Code:
File dataFile = SD.open("Newfile.txt",FILE_WRITE);
it creates the file, but doesn't write to it.
« Last Edit: September 03, 2013, 10:07:40 pm by syphex » Logged

Cincinnati, OH
Offline Offline
God Member
*****
Karma: 46
Posts: 795
I'm not bossy...I just know what you should be doing.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Sometimes errors become more obvious when you form the habit of formatting the source code correctly using Ctrl-T. In your code, you check to see if the file doesn't exist and, if it doesn't, you then define datafile and promptly execute the break statement, which transfers program control to whatever statement exists after the closing brace of the for loop. Therefore, nothing gets written to the file. It seems to me that you need to get rid of the break statement.

Also, try to compile the code and you'll find several other compile-time errors. Always try to get rid of those first. Why did you omit expression 2 in the for loop? If expression 2 (i.e., usually a relational test to see if another iteration of the loop is needed) is missing, it is logic True, which attempts to write an infinite number of data files. Why?
« Last Edit: September 03, 2013, 10:19:14 pm by econjack » Logged

Offline Offline
Full Member
***
Karma: 0
Posts: 164
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I didn't write the code I just copied it from somewhere, but I guess its just ment to loop until the filename array is full and then terminates with the break. Wouldn't it create a file name each time a character is concatenated? It seems a while loop would be better. It doesn't seem very efficient to say the least.

I didn't notice that the println was inside the for loop.

Im having trouble dealing with the variable scope. So the variables created inside the for loop are limited to that block of code? But I can't declare filename at setup because I don't know the length of it yet.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 485
Posts: 18786
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

You are using the String class which can adjust the file name length dynamically, so that shouldn't matter.
Logged


Offline Offline
Full Member
***
Karma: 0
Posts: 164
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

filename is a Char array. I don't understand what it does in this bit of code when in the loop?

Code:
if(!SD.exists(filename))
    {
      File dataFile = SD.open(filename,FILE_WRITE);
      break;
    }

Does it only break at the end? Isn't filename being concatenated every loop and therefore dataFile is pointing to new files all the time? But you can only open one file at a time right?
« Last Edit: September 04, 2013, 02:44:56 am by syphex » Logged

Offline Offline
Full Member
***
Karma: 0
Posts: 164
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I just want to pass a variable into
Code:
myFile = SD.open(filename, FILE_WRITE)
How can I convert a string into a char effectively? I tried to use
Code:
File myFile;
String temp="newfile.txt";
char filename[temp.length()+1];
temp.toCharArray(filename, sizeof(filename));

But that gives me: array bound is not an integer constant
Logged

ivrea (to)
Offline Offline
Faraday Member
**
Karma: 86
Posts: 4946
miaaao ^-^
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

char filename[temp.length()+1];
Not possible, must be a constant value.
A value 40 I think is sufficient for a file name.

Code:
char filename[40];
Logged

my name is IGOR, not AIGOR

Offline Offline
Full Member
***
Karma: 0
Posts: 164
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok I got it working using this before the setup():
Code:
File myFile;
String temp=("newfile");

And this inside the setup():
Code:
temp+=".txt";
char filename[temp.length()+1];
temp.toCharArray(filename, sizeof(filename));
myFile = SD.open(filename, FILE_WRITE);

But I need to do it during the loop, and it won't let me declare filename outside of the setup loop so I can't use it in the loop. Also my SD reader has no CD pin and I need to know when its in there and when someone takes it out is there anyway to do it??
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 614
Posts: 49343
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
and it won't let me declare filename outside of the setup loop
It won't? What the hell is it?

There is no "setup loop". There is a setup FUNCTION.

Where IS the code you are having problems with?
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 614
Posts: 49343
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

By the way, do you really need the String crutch? The length of a file name on an SD card is limited (12 characters total). There is no reason to use a dynamically sizable construct to hold a fixed amount of data. Learn to use sprintf() and char arrays.

Finally, there is a world of difference between a string (a NULL terminated array of chars) and a String. The terms are NOT interchangeable.
Logged

Offline Offline
Full Member
***
Karma: 0
Posts: 164
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yeah your right, it doesn't really need to exceed 12 characters and I guess I don't need to use Stringobjects at all.

I have a question though, I want to be able to take the SD out while its still logging. But without a CD pin I can't tell it when to start writing to EEPROM, so I'll have to leave that out.

Now I want to write time in minutes for the day to the SD card only when the arduino is reset, so I can insert the SD card and restart to indicate to write to SD again. I need to organise it so that excel can detect it in a file for logging. I've been using comma delimiters so far. This is what I mean:

60, 20, 50
  , 20, 50
  , 20, 50
  , 20, 50
//SD card removed
...

//SD card inserted and arduino reset
120, 24, 45
  , 24, 45
  , 24, 45
...

Then Excel can add the new data to cell 120, and leave a gap between minute 60 and minute 120. Is there any better way to do this? How much memory does a blank space use? I guess a byte to store the character reference?

I calculate a 4gb SD card has enough memory for over a thousand years of 5 byte one minute logs... is this correct?

4GB = (((4294967296 bytes/5)/60)/24)/356 = 1675.6 years??

But excel has enough trouble loading the data as it is. Maybe I should log the seconds and use matlab instead? Or whats a program dedicated to graphing lots of log data?
« Last Edit: September 05, 2013, 09:14:04 pm by syphex » Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 614
Posts: 49343
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
But without a CD pin I can't tell it when to start writing to EEPROM, so I'll have to leave that out.
You REALLY should add a switch that defines whether to log to the SD card, or not. You should NOT remove the card when the switch is in the log position. Doing so can corrupt the file, if it is open when you remove the card. When the switch is flipped to the not-log position, you should close the file, if you keep it open.

Quote
I calculate a 4gb SD card has enough memory for over a thousand years of 5 byte one minute logs... is this correct?
Not even close. You are writing 5 byte-sized values as strings. A byte-sized value, like 100, can take 3 bytes to represent as a string ('1', '0', and '0'). Add a separator between strings and 5 bytes can use 19 characters. Plus the carriage return and line feed between records, and each record could be as many as 21 bytes, not 5.
Logged

0
Offline Offline
Tesla Member
***
Karma: 143
Posts: 9601
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Finally, there is a world of difference between a string (a NULL terminated array of chars) and a String. The terms are NOT interchangeable.

Isn't a string an ordered set of bytes, and a "c-string" an ordered set of bytes saved to a memory location with a null terminator added to the end of the original string?
Logged

Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   smiley-cool

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 614
Posts: 49343
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Isn't a string an ordered set of bytes
It's an ordered set of bytes that is NULL terminated.

Quote
and a "c-string"
If we were discussing the differences between C and PHP and Java, I might feel compelled to clarify which language's string I was talking about. Since this forum is about the Arduino, which is programmed in C++, which is a superset of C, I don't feel it necessary to qualify the particular language's string I am talking about.
Logged

0
Offline Offline
Tesla Member
***
Karma: 143
Posts: 9601
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I don't feel it necessary to qualify the particular language's string I am talking about.

What ever floats your boat.  smiley
Logged

Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   smiley-cool

Pages: [1] 2   Go Up
Jump to: