C language write/read SD card - examples
John Kauffman
Posts: 653
I'm trying to create examples for many types of data saves to SD.
Here is simplest: one int. But read back is wrong as comments at end.
#include "simpletools.h" // Include simpletools header .
int DO = 22, CLK = 23, DI = 24, CS = 25; // SD card pins on Propeller BOE
// values for writes & values to receive reads
int myInt1 = 11;
int myInt2 = 22;
int myReadInt = 0;
int main(void){
//--- Setup to use SD Card
sd_mount(DO, CLK, DI, CS); // Mount SD card
//--- One int
FILE* fp = fopen("OneInt.txt", "w"); // Open a file for appending
print("\nmyInt1 = %d",myInt1); // Tell user value to write
fwrite(&myInt1, 4, 1, fp); // Write number to SD card
myReadInt = fread(&myInt1, 4, 1, fp); // Read from SD & get status
print(", myReadInt1 = %d\n",myReadInt); // Tell user value read
fclose(fp); // Close the file
// ***** problems: (n.b. using SD file multiple times in testing)
// result on terminal is "myInt1 = 11, myReadInt1 = 0"
// result on SD is " " (not parsed as ASCII?)
} // main
Here is simplest: one int. But read back is wrong as comments at end.
#include "simpletools.h" // Include simpletools header .
int DO = 22, CLK = 23, DI = 24, CS = 25; // SD card pins on Propeller BOE
// values for writes & values to receive reads
int myInt1 = 11;
int myInt2 = 22;
int myReadInt = 0;
int main(void){
//--- Setup to use SD Card
sd_mount(DO, CLK, DI, CS); // Mount SD card
//--- One int
FILE* fp = fopen("OneInt.txt", "w"); // Open a file for appending
print("\nmyInt1 = %d",myInt1); // Tell user value to write
fwrite(&myInt1, 4, 1, fp); // Write number to SD card
myReadInt = fread(&myInt1, 4, 1, fp); // Read from SD & get status
print(", myReadInt1 = %d\n",myReadInt); // Tell user value read
fclose(fp); // Close the file
// ***** problems: (n.b. using SD file multiple times in testing)
// result on terminal is "myInt1 = 11, myReadInt1 = 0"
// result on SD is " " (not parsed as ASCII?)
} // main
Comments
You can either close and then reopen the file with a "r" mode, or open it with "r+w", and then call fseek(fp, 0, SEEK_SET) between the fwrite and fread to reposition it back to the beginning of the file.
Thanks a million. Your post not only works but your explanation makes it clear why.
Now I'm going on to make examples of other permutations of values to save.
- John
I had a thought that since you are an educator and you are really pressing SimpleIDE and C for Propeller, that you might want to start a thread called John Kauffman's Simple IDE code examples. You're not alone and many people could learn from your code examples. Consider updating your samples in their original postings so they are useful for other people who also will want to do the same thing. You're now ahead of my Simple IDE and C experience, but I know I'll try to catch up soon.
I like what you're doing and I'm inspired to run the code myself.
I'm working on several example sheets which are made possible by help from lots of generous contributors on these fora. I'm also keeping notes on stumble points in transition from PBASIC to Propeller C Learning system. I'm glad to share them so I get feedback for improvements.
Rather than an eponymous thread I could see a new forum dedicated to the Propeller Learn C System. Right now those posts sort of get lost within the Learn forum as a whole. I predict you are going to get a lot of traffic specific to the C topics.
Also, do you pass "w" (string) to fopen or do you pass 'w' (char)? Maybe it doesn't matter (based on Dave Hein's response) but it doesn't hurt to check.
Do you need to put a delay in to allow for the SD card to mount?
Use the -Wall compiler option, and it will provide useful warning messages.
EDIT: The "w" parameter is correct.
Edit: Looks like I got beat by Dave Hein
I changed all examples to reflect 8.3.
I'm using SimpleIDE and just hit F8 to compile, load, run ad open Terminal. how would I add the -Wall option?
I think it is close, but I don't know how to set number of characters to read - the ????? below. I am guessing a loop that reads one chat at a time until the return of the fread() == a terminator character.
I have to leave for a few days so don't be surprised that I don't reply until Monday. I deeply appreciate sharing your expertise. I will be writing this up to be available to all of us switching from PBASIC to C.
It's also a good idea to start checking for errors (e.g. fp may be NULL).
I still have the problem of gibberish on the SD file. I get this:
l ,
Edit: Or do what kuroneko says...
Generally speaking we use fprintf and fscanf for text IO with ANSI C libraries for string formatting and interpretation. Those functions tend to balloon code size though. We developed alternatives for Propeller.
I see you've met the print function already - it is like a printf (print format), except not all ANSI features are supported.
The print and scan functions allow using %b (not ANSI), %c, %d, %e, %f, and %s without requiring the math library. The functions include all format specifier support all the time, so they are always the same size. There are even smaller alternatives in the simpletext library.
There are also functions that print to a buffer and get from a buffer much like ANSI sprintf and sscanf. Those functions are sprint and sscan.
So, given those tools and fread/fwrite, you can use code space more efficiently. To summarize:
sprint(buffer, "format", args ...) is like sprintf
sscan(buffer, "format", args ...) is like scanf
All of this information is available from the Help Menu or on line. Help Menu -> Simple Library Reference (simpletext for these examples).
Hope this helps.
--Steve
I can take data from SD file, run through Word to search/replace: change commas to tabs & semicolons to CRLF. Then send to Excel for a chart.
It looks like a hole in my understanding (as I come from PBASIC to Prop C) is the use of the ampersand before a variable name. I'll see if I can find a quick answer within Andy's tutorials and other C tutorials.
Now it is back to the unkown number of characters example.