I am using the SMARTGPU2 for a GPS data logging project and have come across a bizarre behaviour when trying to log data to a file on the SD card.
The behaviour is that all my GPS data is passed correctly and logged into the file, however it seems to OVERWRITE any existing data stored in the file, rather than APPEND to it. As you can imagine - this isn't great for wanting to keep lots of GPS data strings!
Has anyone experienced this behaviour using the SMARTGPU2 before?
I have looked in the header file for the SmartGPU2 library (attached for reference including the .cpp) and the function to write to the file on the SD card is defined as below:
SDFwriteFile(char, NUMBEROFBYTES,NUMBEROFBYTES*, WORKSPACEBLOCK); //Bytes to Write, Succesfully Written Bytes, file object # to write bytes
The end result is that the file contains my latest GPS NMEA data passed from my char array as expected, but any previous data is overwritten (not good!).
So, in the absence of any parameters to change the write mode to append I started looking through the header for any functions that may help:
FILERESULT SDFopenFile(FILENAME, OPENMODE, WORKSPACEBLOCK); //opens an existing file in READONLY, WRITEONLY or READWRITE mode on the received object # workspace
The code above suggests that I must used READWRITE in order to query the existing data within the file - therefore I am using READWRITE.
SDFsetFilePointer(POINTERPOSITION, WORKSPACEBLOCK); // set/move file pointer of file object # workspace
This seems to suggest that there is a pointer - perhaps I can query the file and set the pointer to the end (and even use ASCII to send a carriage return aka start a new line. Seems to be a bit of a weird way of doing things but maybe this would work?
SDFgetFilePointer(POINTERPOSITION*, WORKSPACEBLOCK); // get file pointer of file object # workspace
I thought that this would be a great way to find the position - however, even in my existing file containing a line of data ii seems to return an empty value. My code shown below for reference (assume all initialisation complete at this point):
String pointerpos="Pointer positioned @: ";
long unsigned int pointer=0;
lcd.SDFgetFilePointer(&pointer, WORKSPACE0); // should return pointer position to my pointer variable
pointerpos+=pointer; // Append my long int from pointer to my String pointerpos
pointerpos.toCharArray(buffer, pointerpos.length()); //convert my String to a char array (SMARTGPU2 expects Char array as an input)
lcd.string(10,row,MAX_X_LANDSCAPE,MAX_Y_LANDSCAPE,buffer,0); row+=15; //write my full string out to the screen for debugging.
Or perhaps this would be an alternative method?
SDFreadFile(char, NUMBEROFBYTES, NUMBEROFBYTES*, WORKSPACEBLOCK); //Bytes to Read, Succesfully Read Bytes, file object # to read bytes from
SDFwriteFile(char, NUMBEROFBYTES,NUMBEROFBYTES*, WORKSPACEBLOCK);
This could work - I could read the contents of the file to a buffer then manually append my new data to the buffer and write the whole lot? Seems like it may be too memory intensive if I start having thousands of logged lines though?
If you've read this far I certainly appreciate it! Any guidance at this point would be fantastic and many thanks in advance.
Hi Captain K!
I new to SMARTGPU2 and crashed at the same point you did. I used the function lcd.SDFgetFilePointer to read the pointer value and always read 0, after increment or decrement the pointer value, always read 0 -It`s normal? - I think that`s the cause data is overwritten on the first file line.
I saw you put a legend "SOLVED" on your post title - so you got the solution?
I appreciate any hint that help with this trouble.
Thanks in advance.
It actually turned out to be pretty simple! The pointer is updated when you read or write to the file, what I did was store the position as a global variable that is updated when opening the file - it the set the pointer to this position when writing. This means it appends to existing data rather than overwrite.
I'll post my code tomorrow as I'm away from my PC right now! :)
Sorry about the delay - here is how I handle the pointer value
// I assume that you have set workingfile variable to the filename
i=workingfile.length() + 1; // first we need to put the filename in a char array (if it isn't already)
char filebuffer[i]; // then create a buffer for the filename
workingfile.toCharArray(filebuffer,i); My string is now in a Char array
res=lcd.SDFopenFile(filebuffer, WRITEONLY, WORKSPACE0); // Try to open the file in filebuffer in write only mode in workspace block 0
lcd.SDFgetFileSize(filebuffer,[color=limegreen]&filepointer[/color]); // Get existing file size and set pointer to append additional data - Notice the[color=limegreen] &filepointer[/color] - this returns the position to my filepointer variable
You can retrieve the filepointer when using the following functions:
You can also retrieve the filepointer once you have written to the file using