Showing the files on an sdcard


#1

Hi David ,

Do you think it’s possible to read the directory structure from an sdcard ?
Only the root would be enough.

Kind regards,
Ronny


#2

The Arduino SD library provides two functions to help with this:

File entry = dir.openNextFile();

opens the next file in the current directory, or returns 0 if there are no more files, and:

entry.name()

returns the name of the current file. I could provide uLisp equivalents of these functions.

Alternatively, a better solution might be to provide something more like Common Lisp:

(directory)

which could return a list of the filenames of the files in the current directory.


#3

Hi David ,

I searched on this and found an example on following link on the arduino site :

I used the ‘list files’ program , did the chip select en spi1 change and it works fine on my challenger board !

Initializing SD card…initialization done.
sunrise-sunset.fs 7567
Greeting.txt 9
ULISP.IMG 320
test.fs 26
done!

Maybe this could be implemented in ulisp ?
What do you think.

Kind regards,
Ronny


#4

Funnily enough I was just putting something together as a uLisp extension. Here it is:

/*
 SD Card Extension
*/
  
object *fn_directory (object *args, object *env) {
  (void) env;
  SD.begin(SDCARD_SS_PIN);
  File root = SD.open("/");
  if (!root) error2(PSTR("problem reading from SD card"));
  object *result = cons(NULL, NULL);
  object *ptr = result;
  while (true) {
    File entry = root.openNextFile();
    if (!entry) break;
    object *filename = lispstring(entry.name());
    cdr(ptr) = cons(filename, NULL);
    ptr = cdr(ptr);
  };
  root.close();
  return cdr(result);
}

// Symbol names
const char stringdirectory[] PROGMEM = "directory";

// Documentation strings
const char docdirectory[] PROGMEM = "(directory)\n"
"Reads the directory at the top level of an SD card and returns\n"
"a list of the filenames.";

// Symbol lookup table
const tbl_entry_t lookup_table2[] PROGMEM = {
  { stringdirectory, fn_directory, 0200, docdirectory },
};

// Table cross-reference functions

tbl_entry_t *tables[] = {lookup_table, lookup_table2};
const unsigned int tablesizes[] = { arraysize(lookup_table), arraysize(lookup_table2) };

const tbl_entry_t *table (int n) {
  return tables[n];
}

unsigned int tablesize (int n) {
  return tablesizes[n];
}

To use this:

  • Put it in a file Directory.ino in the same folder as the uLisp source file for your platform.
  • Uncomment #define extensions at the start of the main uLisp source file.
  • Compile and upload uLisp.

An example of listing the files on an SD card:

> (directory)
("CARDS2.GIF" "SPOTLI~1" "YELLOW.GIF" "CARDS8.GIF" "_YELLO~1.GIF")

#5

Hi David ,

Thanks , but it seems to throw an error :
Compilation error: invalid conversion from ‘const char*’ to ‘char*’ [-fpermissive]
for this line in directory.ino
object *filename = lispstring(entry.name());


#6

What platform are you using it on? I tested it on an Arduino MRRZero and it was fine.


#7

Oh yes, I remember now - it’s the RP2040 Challenger. I’ll test it on RP2040 and see if I get the same problem.


#8

yes the challenger


#9

David ,

I even tried the original 4.5 version for rpi pico , but always the same error …
I don’t really have a clue what causes this.
Regards,
Ronny


#10

I think you just have to change:

object *filename = lispstring(entry.name());

to:

object *filename = lispstring((char*)entry.name());

Let me know if that works!


#11

Oh, in your case you have to change:

SD.begin(SDCARD_SS_PIN);

to:

SD.begin(SDCARD_SS_PIN,SPI1);

#12

Hi David ,

That change object filename = lispstring((char)entry.name()); did it !
I already had changed the spi1 , so that was not a problem.
Thanks again , you’re marvelous as always :-)

uLisp 4.5
22820> (directory)
(“sunrise-sunset.fs” “Greeting.txt” “ULISP.IMG” “test.fs”)

22820>


#13

Hi David ,

One more question :
Is it possible to print the files each on a new line ?

Kind regards,
Ronny


#14

I thought it would be best for (directory) to return a list of filenames that you can do what you want with. So you could do:

(progn (mapc #'print (directory)) nothing)

#15

Thanks very much !!

Ronny