Pages: [1]   Go Down
Author Topic: SDFat error file.open and what does it really mean for a file to be 'open'  (Read 1223 times)
0 Members and 1 Guest are viewing this topic.
Melbourne, Australia
Offline Offline
Newbie
*
Karma: 0
Posts: 9
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The analoglogger example for sdfatlib creates 100 unique log files of the form LOGGERnn.CSV before wrapping around and clobbering the earliest file.
ie

Code:
 for (uint8_t i = 0; i < 100; i++) {
    name[6] = i/10 + '0';
    name[7] = i%10 + '0';
    if (sd.exists(name)) continue;
    logfile.open(name);
    break;
  }
  if (!logfile.is_open()) error("file.open");

Ideally I would like the filename created in my application to be the date of today's log. However since the log files have a creation date (or is it modification date?) when viewed in a desktop OS then having a sequence of log files that don't contain the date as their filename will suffice until my understanding of C improves.

In attempting to create not 100 unique but 1000 unique log files (ie several years worth of daily logs) I modified my sketch, which borrows heavily from analoglogger thusly:

Code:
 char name[] = "LOGGE000.CSV";

  for (uint16_t i = 0; i < 1000; i++) {
    name[5] = i/100 + '0';
    name[6] = i/10 + '0';
    name[7] = i%10 + '0';
    if (sd.exists(name)) continue;
    logfile.open(name);
    break;
  }
  if (!logfile.is_open()) error("file.open");

Upon every reset a new log file is created. Everyone is fine until after LOGGE099.CSV - then to my surprise rather than getting LOGGE100.CSV I got

Quote
Logging to: LOGGE1:1.CSV
echoed to the terminal.
Obviously there is a beginners error in my code which any experienced C programmer will be able to correct but what I think might be more revealing is that continuing to reset my target board produced log files up to:

Quote
Logging to: LOGGE1:9.CSV
and then I received a file.open error - presumably as the file name wraps around.

I had always always thought that fat16lib's extensive error trapping throughout the analoglogger sketch was a little overboard and made the code harder to follow but this shows why it is important.

The more interesting and abstract question that my hamfisted coding might give someone the opportunity to comment on is what does it really mean for a file on an SD card to be 'open' in the Arduino environment.

Is this just a concept that the AVR has of while data that is in static RAM that has yet to be written out or is the concept of being open something that the SD card itself has in an index stored on the card, or is there a flag against the file itself that
Code:
logfile.is_open())
is reading.

What is, to me, equally interesting is what these 'open' files look like from the point of view of the desktop OS



presumably the colon is replaced with a slash as by the OS but you can see that the files have no modification date and furthermore can't be moved to the trash due to error

Quote
The operation can’t be completed because one or more required items can’t be found.
(Error code -35)
« Last Edit: September 23, 2013, 05:59:41 am by VK3UBM » Logged

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

Quote
However since the log files have a creation date (or is it modification date?) when viewed in a desktop OS then having a sequence of log files that don't contain the date as their filename will suffice until my understanding of C improves.
The date may well be meaningless, as the Arduino doesn't really know what time it is. If you add some mechanism (RTC, ethernet connection, link to PC) so that it does, the SD class doesn't know that the Arduino knows what time it is.

Quote
Upon every reset a new log file is created. Everyone is fine until after LOGGE099.CSV - then to my surprise rather than getting LOGGE100.CSV I got
No surprise, really:
Code:
    name[5] = i/100 + '0';
    name[6] = i/10 + '0';
    name[7] = i%10 + '0';
i = 100, so i/100 is 1. 1 + '0' is '1'.
i/10 is 10. 10 + '1' is?
i%10 is 0. 0 + '0' is '0'.

Try again. Think i%100/10.

Quote
presumably as the file name wraps around.
No. You get the error because the name contains an invalid character.

Logged

Melbourne, Australia
Offline Offline
Newbie
*
Karma: 0
Posts: 9
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

OK Thanks Paul,

I have successfully modified my analoglogger derivative to make more than 100 log files as per:
Code:
  char name[] = "LOGGE000.CSV";

  for (uint16_t i = 0; i < 1000; i++) {
    name[5] = i/100 + '0';
    name[6] = i%100/10 + '0';
    name[7] = i%10 + '0';
    if (sd.exists(name)) continue;
    logfile.open(name);
    break;
  }
  if (!logfile.is_open()) error("file.open");

and without wishing to disappear don't the rabbit hole with this can you elaborate on why

Code:
name[6] = i/10 + '0';

(which evaluates to 11) causes a colon to be output in the filename echoed to the terminal. 11 is not the ASCII character code for a colon, is it simply that if you feed a 2 character alphanumeric string into name[6] the output is ambiguous because you want to select a single character ?

Logged

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

Quote
and without wishing to disappear don't the rabbit hole with this can you elaborate on why
Code:
name[6] = i/10 + '0';
(which evaluates to 11) causes a colon to be output in the filename echoed to the terminal. 11 is not the ASCII character code for a colon
When i is 100, i/10 is 10. '0' is 48 in the ASCII table. 10 + 48 is 58. Not surprisingly, 58 in the ASCII table is ':'.

I don't know how you figure that 10 + '0' is 11. It's your turn to explain.
Logged

Melbourne, Australia
Offline Offline
Newbie
*
Karma: 0
Posts: 9
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sorry Paul I meant that 11 is the answer to the question posed in your second last post

Quote
i/10 is 10. 10 + '1' is?
Logged

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

Quote
Sorry Paul I meant that 11 is the answer to the question posed in your second last post
But, it isn't. 10 + 1 is 11. 10 + '0' is 58. 58 is ':'.

(The + '1' was a typo; it was supposed to be + '0')
Logged

Melbourne, Australia
Offline Offline
Newbie
*
Karma: 0
Posts: 9
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

OK I now understand that the C statement:

Code:
char[6] = i/10 + '0'

simply converts between a single digital decimal number 'i' and it's equivalent ASCII character code (necessary to build a filename in a character array) by adding (decimal) 48 to each number between 0 and 9.

This works because the ASCII character code for the characters '0' through '9' are ASCII 48 to 57

The colon character ':' is ASCII 58 which is the first thing you hit if drive out of the numerals and into non alphanumeric territory in the ASCII table.
Logged

Pages: [1]   Go Up
Jump to: