C language write/read SD card - examples

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.
#include "simpletools.h" // Provides I/O tools for use w/ SD // vars & cons int DO = 22, CLK = 23, DI = 24, CS = 25; // SD card pins on Propeller BOE // values for writes & values to receive reads char myChar1='P'; // ASCII 80 char myChar2='a'; // ASCII 97 char myReadChar; int main(void){ //--- Setup to use SD Card -------------- sd_mount(DO, CLK, DI, CS); // Mount SD card //--- One char ------------------------ // write one char FILE* fp = fopen("CharString01.txt", "w"); // Open&erase or create a file print("\nmyChar1 = %d",myChar1); // User info fwrite(&myChar1, 1, 1, fp); // Write to SD card fclose(fp); // Close the file // read one char fopen("CharString01.txt", "r"); // Open a file for read fread(&myReadChar, 1, 1, fp); // Read from SD print(", myReadChar = %s\n",myReadChar); // User info fclose(fp); // Close the file // PROBLEM // terminal output is "myChar1 = 80, myReadChar = " // last character above is ASCII 25 }// main
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?
//--- String of known length ---------------- FILE* fp=fopen("String01.txt", "w"); // Open/erase or create file for write fwrite("String length known 22", 1, 22, fp); // n.b 1 byte per char, 22 chars fclose(fp); fopen("String01.txt", "r"); // Open/erase or create file for write char myReadChar[100]; // buffer - give some extra room for future fread(myReadChar, 1, 22, fp); // known length of 22 chars print(myReadChar); fclose(fp);
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.
#include "simpletools.h" // Provides I/O tools for use w/ SD // vars & cons int DO = 22, CLK = 23, DI = 24, CS = 25; // SD card pins on Propeller BOE int main(void){ //--- Setup to use SD Card -------------- sd_mount(DO, CLK, DI, CS); // Mount SD card //--- String of unknown length ---------------- FILE* fp=fopen("Str02.txt", "w"); // Open/erase or create file for write char myStringAnySize[80]; char myReadStringAnySize[80]; fgets(myStringAnySize, sizeof(myStringAnySize), stdin); // from user input printf("Input = %s\t", myStringAnySize); //test point fclose(fp); fopen("Str02.txt", "r"); // Open file for read fread(myReadStringAnySize, 1,??????, fp); // how many chars to read? print("%s\n",myReadStringAnySize); fclose(fp); }// main
fgets(myReadStringAnySize, sizeof(myReadStringAnySize), fp);
This implies that your buffer is large enough to be able to hold the longest string from your file (which you have to write the string to, you don't currently do that). Otherwise fgets will simply stop after the buffer has been filled which may be considered an error anyway.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.