How to log data to the SD card

Im using a SNAP-PAC-S2 and would like to know how to save variables to the SD card with a timestamp.

Sorry if i missed this information somewhere.

Shaun

Shaun
you will have to write to the sdcard using a file com handle. something like this should do it:


sFileComm = "file:a,/sdcard0/myfile.txt";  //init the com handle to append the file on the sd card
SetCommunicationHandleValue(sFileComm, file_comm);  //set the com handle

DateToStringDDMMYYYY(curr_date);  //get the controller date
TimeToString(curr_time);  //get the controller time
myString=curr_date + "," + curr_time + ",some data i want to write"+chr(13)+chr(10);  //build the string with a <CR><LF> appended

nFileOpenStatus = OpenOutgoingCommunication(file_comm);  //open the file
status=TransmitString(myString,  file_comm);  //write to the file
CloseCommunication(file_comm);  //close the file


you might want to do some error checking to ensure the handle opened etc…

also, be sure to stick to a 8.3 file name format. ie:thisfilenameistoolong.txt probably will throw an error or not write to that file.

check out the PAC Control user Guide (form 1700) at page 252. it gives an explanation on how the file system on the controller can be utilized.

I hope this helps.
Nick

Thanks for the information on how to write to SD Card. Is there a way to check existence of a file on the SD card?

Hi hnajafi,

There are a few different ways you could check for the existence of a file on your PAC. Which method you choose might depend on what you’re trying to do next. For example:

  1. If the next step is to open that particular file, you might simply attempt to use a file comm handle with the file you hope to see, and check the status from the OpenOutgoingCommunication command. If the file opens okay then you’ll know that file exists. Your likely next step might be to do a GetNumCharsWaiting to determine the number of bytes in that file.

  2. If you want a list of all the files in that directory, you can do something similar to what you might do manually, using ftp via command-line using the “dir” command:


You can do something similar in your strategy to get a list (in a string table) like this:

Perhaps now you have just one file to check for, but maybe in the future you think the name or number of files might change. Here you can perhaps look for that “.txt” extension, as an example, to see what all files are there.

Below I’ve included a picture of my chart (which has both Action Blocks and the equivalent OptoScript block, also included below).


// Block 21 equivalent OptoScript:
// Get the length of this table in code, so that later we can make it
// longer, if need be, and not change any code
nTableLength = GetLengthOfTable(stFilenames);
 
// Block 1 "FTP dir"
nStatus = OpenOutgoingCommunication(chFTPlocal); // where chFTPlocal is "ftp:127.0.0.1:21,user,pass"
nFileCount = SendCommunicationHandleCommand( chFTPlocal, "dir:/sdcard0" );
 
// Condition block 3
if ( IsCommunicationOpen(chFTPlocal) and (nFileCount >= 0) ) then
  // True condition
  // Condition block 11 - check for Too many files to fit in our stFilenames table
  if (nFileCount > nTableLength) then 
 
    // True condition
 
    // Block 8 (red error here, empty now)
  else
    // False condition - we have room in our list of tables
    SetEndOfMessageTerminator( chFTPlocal, 0 );
    nStatus = ReceiveStrTable(nFileCount, 0, stFilenames, chFTPlocal );
  endif 
else // False condition off condition block 8 - didn't open/read directory okay
  // Block 8 (red error here, empty now)
endif

I hope that helps!

-OptoMary

Here’s an exported 9.0 chart you can import into your 9.0-or-new version PAC Control strategy.
FileDirectoryChart.zip (2.16 KB)

Mary,

Thank you for a quick response to the question. Here’s what I’m hoping to accomplish with the controller:

  1. When the operator turns on the controller, the controller creates a new data text file with date(YYYYMMDDDD.txt) as the file name. If there are more than 7 data files on the SD Card, I’d like to be able to delete the oldest file. If a file with the same file name exist, I’d like to append the file name with a 0, 1, 2, …etc.
  2. Then data will be written to this file in 1 second increments.

I tried your first recommendation, on try to open the file. What I found out is that if the file name doesn’t exist, then controller will create a file anyway and still returns a 0. I haven’t tried your second method using FTP yet. Is it possible for me to even do this?

Is there a limit on filename size? I tried creating this filename: DATA04182012.TXT but this is what actually got created DATA4182.TXT Then I tried "DATA041812.TXT but I got “DATA4181.TXT”.
Thanks,
Hamid

Not exactly looking for a specific file, but handy just the same when working with the SDcard is this command;

ReadNumFromIOUnitMemMap(name_of_your_pac,0xF7002204,nFile_Space);

It will return the hex value for the amount of free space. So for example 3CB9C000 was returned when I did that command, a quick conversion shows that I have 1018806272 bytes on the card (yep, it was a 1Gb card).
If you dont have a card inserted, you get 0.
Pretty straight forward.

Cheers,

Ben.

Hi Hamid,

You’ll for sure want to check out form 1700, the PAC Control Users Guide, the Communication Commands section in Chapter 10 - Programming with Commands. (Also under Help > Manuals > Users Guide in PAC Control itself.) As 1700 explains, how the Open behaves depends on if you’re opening for read/write/append, and you’d want the “read” option in this case:
[INDENT]r Opens a file for reading. If the file does not exist or cannot be found, the open call fails.
w Creates a new file and opens it for writing. If the file already exists, its contents are destroyed.
a Opens a file for writing at the end of the file (appending). If the file doesn’t exist, it is created.

[/INDENT]As Nick mentioned above, there is a limit on your filenames, especially for the sd card. As Nick said, you get only 8.3 (8 characters for the first part of the name, 3 for what follows your dot).

For those of you looking for bytes free, there’s the method Ben mentions (I did warn you that there were several ways of doing this). :wink:

Also, check out the GetAvailableFileSpace command, which has even more options if you have firmware version R9.0b or newer. Pass a different parameter to the command to learn:

[INDENT]0 = RAM filesystem bytes
1 = RAM filesystem megabytes
4 = flash filesystem bytes
5 = flash filesystem megabytes
8 = microSD filesystem bytes
9 = microSD filesystem megabytes
[/INDENT]Neat-o!

-OptoMary

Also be sure to check out the Maintenance chapter in your controller’s user guide for basic info on working with the microSD card (for example, the 8.3 filename format).
For an S-series controller, see form 1592.
For an R-series controller, form 1595.
In both cases you can look in the index for microSD or just search the pdf for microSD.
HTH,
Jean

As Ben mentioned, there’s information in the Memory Map about the SD card which can be read from a chart, like this:

There’s also also this section in the Memory Map:

FFFF F030 0248; Result of some Status Area Write commands.
Results apply only to commands 03, 04, 0D, 0E, 0F, and 10.
0 = Operation was successful.
-109 = microSD card is read only.
-110 = microSD card is not inserted.
-111 = Controller doesn’t support microSD cards.

Both are documented in form 1465 just search for “microSD” for all relevant info.

-OptoMary

Update on the 8.3 and 2gig file limitation(s), check out this KB83929 and make sure you’re subscribed to [URL=“http://www.opto22.com/site/register/optonews_subscribe.aspx”]OptoNews for details on how we’ve improved the microSD support! Whoo-hoo!

[QUOTE=mstjohn;833]Hi hnajafi,

There are a few different ways you could check for the existence of a file on your PAC. Which method you choose might depend on what you’re trying to do next. For example:

  1. If the next step is to open that particular file, you might simply attempt to use a file comm handle with the file you hope to see, and check the status from the OpenOutgoingCommunication command. If the file opens okay then you’ll know that file exists. Your likely next step might be to do a GetNumCharsWaiting to determine the number of bytes in that file.

  2. If you want a list of all the files in that directory, you can do something similar to what you might do manually, using ftp via command-line using the “dir” command:


You can do something similar in your strategy to get a list (in a string table) like this:

Perhaps now you have just one file to check for, but maybe in the future you think the name or number of files might change. Here you can perhaps look for that “.txt” extension, as an example, to see what all files are there.

Below I’ve included a picture of my chart (which has both Action Blocks and the equivalent OptoScript block, also included below).


// Block 21 equivalent OptoScript:
// Get the length of this table in code, so that later we can make it
// longer, if need be, and not change any code
nTableLength = GetLengthOfTable(stFilenames);
 
// Block 1 "FTP dir"
nStatus = OpenOutgoingCommunication(chFTPlocal); // where chFTPlocal is "ftp:127.0.0.1:21,user,pass"
nFileCount = SendCommunicationHandleCommand( chFTPlocal, "dir:/sdcard0" );
 
// Condition block 3
if ( IsCommunicationOpen(chFTPlocal) and (nFileCount >= 0) ) then
  // True condition
  // Condition block 11 - check for Too many files to fit in our stFilenames table
  if (nFileCount > nTableLength) then 
 
    // True condition
 
    // Block 8 (red error here, empty now)
  else
    // False condition - we have room in our list of tables
    SetEndOfMessageTerminator( chFTPlocal, 0 );
    nStatus = ReceiveStrTable(nFileCount, 0, stFilenames, chFTPlocal );
  endif 
else // False condition off condition block 8 - didn't open/read directory okay
  // Block 8 (red error here, empty now)
endif

I hope that helps!

-OptoMary

Here’s an exported 9.0 chart you can import into your 9.0-or-new version PAC Control strategy.
FileDirectoryChart.zip (2.16 KB)[/QUOTE

Just tried to import this chart with control basic9.4 and it crashed. Is it posted in another place?

Hello jpoehlma,
Welcome to the OptoForums!
I’m sorry you’re having trouble importing this chart. I just imported it into PAC Control basic R9.4e with no problem.
What version of PAC Control are you using? What was the nature of the crash? (E.g. PAC Control quit working?)
Have you contacted support about this issue?
Thanks,
OptoMary

Did get it to work with R9.4e (on another computer) so I updated to 9.4e! (from 9.4d)

Still struggling to write to SD card, can you point us to a working example?

open_status = OpenOutgoingCommunication(chFTPlocal);

SetCommunicationHandleValue(“file:a,/sdcard0/myfile.txt”,chFTPlocal);

statusXX = TransmitString(“Write some text2!”, chFTPlocal); //statusXX in a number var. string gave errors

CloseCommunication(chFTPlocal);

Above is what we tried but it didn’t create a file

1 Like