Red Lion CompactFlash code?

jfls45

Member
Join Date
Mar 2012
Location
Pennsylvania
Posts
76
I am up against a wall trying to figure out how to retrieve saved recipe values from the CompactFlash in my Red Lion G315. I have been successfull saving to the CF card but trying to retrieve these same values back to the HMI has been daunting. I trying to learn C programming to do this task by reading the included Reference Manual in Crimson 3. I have downloaded the sample files from Red Lions website, most of them are in Crimson 2. I converted them to Crimson 3 and downloaded into the HMI, and they don't work.

Here is the code I am using to save to the card. Keep in mind, this does work:

int hfile; //file opened index
int i; //array scanning index

// Create a new folder if it doesn't exist
CreateDirectory("/recipes");

//Create the file if it doesn't exist
CreateFile("/recipes/recipe.csv");

//open the file
hfile= OpenFile("/recipes/recipe.csv",1);

//Write each recipe as a line in the file
//Copy each array index as a file line beginning by the recipe index
for (i=0;i<100;i++){
WriteFileLine(hfile,AsText(i)+","
+OutsideDiameter.AsText+";"
+RecipeOD.AsText+";"
+WallThickness.AsText+";"
+RecipeWall.AsText+";"
+GapRoll1.AsText+";"
+GapRoll3.AsText+";"
+GapRoll5.AsText+";"
+GapRoll7.AsText+";"
+GapRoll9.AsText+";"
+AngleRoll1.AsText+";"
+AngleRoll3.AsText+";"
+AngleRoll5.AsText+";"
+AngleRoll7.AsText+";"
+AngleRoll9.AsText+";"
+AngleRoll2.AsText+";"
+AngleRoll4.AsText+";"
+AngleRoll6.AsText+";"
+AngleRoll8.AsText+";"
+AngleRoll10.AsText+";"
+DeflectRoll4.AsText+";"
+DeflectRoll6.AsText+";"
+DeflectRoll8.AsText);
}

//Close the file
CloseFile(hfile);

Now I am trying to retrieve these same values and have had no luck trying to do this. Can someone help me out here? I've tried using the "ReadFileLine" function in place of the "WriteFileLine" but it doesn't work. I know there is probably alot of syntax changes so anyone who is willing to help please feel free to make some suggestions.

thanks in advance,

jfls45
 
This is a code I use to read a file with Set Points that is on the CF Card. I hope it helps!

//Open file
Hfile := OpenFile("/param/param.txt", 1);
//Read a line of the file
line := ReadFileLine(Hfile);

//While the line read from the files retrieves something, keep reading
while (Len(line)>0)
{
//Read the position of the first and second space occurrence
//Example of line: Polisher_System.Polisher.Vibration 22 mm/s
space1 := Find(line,' ',0);
space2 := Find(line,' ',1);
//The tag name is the section before the first space
TagName := Left(line, space1);
//The tag value is located between the first and the second spaces
Value := TextToInt(Mid(line, space1+1, space2-space1),10);

//Write the value to the corresponding tag in Crimson
tagindex = FindTagIndex(TagName);
SetIntTag(tagindex,Value);

//Read a new line from the file
line := ReadFileLine(Hfile);
}

//Close the file
CloseFile(Hfile);
 
Are you using Crimson 2 or 3? What does Len mean? Length I presume?

Is this a .txt file or .csv file?





This is a code I use to read a file with Set Points that is on the CF Card. I hope it helps!

//Open file
Hfile := OpenFile("/param/param.txt", 1);
//Read a line of the file
line := ReadFileLine(Hfile);

//While the line read from the files retrieves something, keep reading
while (Len(line)>0)
{
//Read the position of the first and second space occurrence
//Example of line: Polisher_System.Polisher.Vibration 22 mm/s
space1 := Find(line,' ',0);
space2 := Find(line,' ',1);
//The tag name is the section before the first space
TagName := Left(line, space1);
//The tag value is located between the first and the second spaces
Value := TextToInt(Mid(line, space1+1, space2-space1),10);

//Write the value to the corresponding tag in Crimson
tagindex = FindTagIndex(TagName);
SetIntTag(tagindex,Value);

//Read a new line from the file
line := ReadFileLine(Hfile);
}

//Close the file
CloseFile(Hfile);
 
Are you using Crimson 2 or 3? What does Len mean? Length I presume?

Is this a .txt file or .csv file?

Crimson 3.
Len is the length of the string.
You can see in the code that the file is has txt extension.
 
Here is an example that I wrote years ago in Crimson 2. It should work in 3 also but there are probably some new functions available that would make it simpler.

There is a 1000-element array tag for each recipe parameter. (There are only about 90 recipes in this application but our job number is a seemingly random 3-digit integer in the range 001-999.) The Fill() commands simply zero out all the array elements prior to importing. The first data element in each row is the job number (fabnum); this is used as the pointer for each recipe array when the data from that row is imported. The Find(), Mid(), and Len() functions are the workhorses of data import. The basic process is to locate text between delimiters, while skipping the necessary number of delimiters so the same data isn't imported twice. (Yes, importing is much more complicated than exporting.)

Code:
// This program reads data from a file on the CF card and stores
// it in the appropriate arrays on the G3.

cstring fname, linetxt;
int i, ofile, fabnum, delim1, delim2;

fname := "/" + filename + ".csv";    // Generate filename.
ofile := OpenFile(fname,0);        // Open the file.

// Clear all recipe arrays before importing.
Fill(recipe_PileHeight[0],0,1000);
for(i:=0; i<1000; i++) recipe_Description[i] := "";
Fill(recipe_BuffActive[0],false,1000);
Fill(recipe_CardActive[0],false,1000);
Fill(recipe_BevelActive[0],false,1000);
Fill(recipe_TrimActive[0],false,1000);
Fill(recipe_BufferSpeed[0],0,1000);
Fill(recipe_CardingSpeed[0],0,1000);
Fill(recipe_FBUFF_ExtPos[0],0,1000);
Fill(recipe_RBUFF_ExtPos[0],0,1000);
Fill(recipe_FCARD_ExtPos[0],0,1000);
Fill(recipe_RCARD_ExtPos[0],0,1000);
Fill(recipe_FTRIM_ExtPos[0],0,1000);
Fill(recipe_RTRIM_ExtPos[0],0,1000);
Fill(recipe_BuffDwell[0],0,1000);
Fill(recipe_CardDwell[0],0,1000);

linetxt := ReadFileLine(ofile);        // Read first line of file (headers).
linetxt := ReadFileLine(ofile);        // Read second line of file (first line of data).

while(linetxt != "")    // Loop until all lines are read
{
    delim2 := Find(linetxt,',',0);
    fabnum := TextToInt(Mid(linetxt,0,delim2),10);    // Get fabric number from first item

    delim1 := delim2;
    delim2 := Find(linetxt,',',1);
    recipe_PileHeight[fabnum] := TextToInt(Mid(linetxt,delim1+1,delim2-delim1-1),10);

    delim1 := delim2;
    delim2 := Find(linetxt,',',2);
    recipe_Description[fabnum] := Mid(linetxt,delim1+1,delim2-delim1-1);

    delim1 := delim2;
    recipe_BuffActive[fabnum] := TextToInt(Mid(linetxt,delim1+1,1),10);
    recipe_CardActive[fabnum] := TextToInt(Mid(linetxt,delim1+3,1),10);
    recipe_BevelActive[fabnum] := TextToInt(Mid(linetxt,delim1+5,1),10);
    recipe_TrimActive[fabnum] := TextToInt(Mid(linetxt,delim1+7,1),10);

    delim1 := delim1 + 8;
    delim2 := Find(linetxt,',',7);
    recipe_BufferSpeed[fabnum] := TextToInt(Mid(linetxt,delim1+1,delim2-delim1-1),10);

    delim1 := delim2;
    delim2 := Find(linetxt,',',8);
    recipe_CardingSpeed[fabnum] := TextToInt(Mid(linetxt,delim1+1,delim2-delim1-1),10);

    delim1 := delim2;
    delim2 := Find(linetxt,',',9);
    recipe_FBUFF_ExtPos[fabnum] := TextToInt(Mid(linetxt,delim1+1,delim2-delim1-1),10);

    delim1 := delim2;
    delim2 := Find(linetxt,',',10);
    recipe_RBUFF_ExtPos[fabnum] := TextToInt(Mid(linetxt,delim1+1,delim2-delim1-1),10);

    delim1 := delim2;
    delim2 := Find(linetxt,',',11);
    recipe_FCARD_ExtPos[fabnum] := TextToInt(Mid(linetxt,delim1+1,delim2-delim1-1),10);

    delim1 := delim2;
    delim2 := Find(linetxt,',',12);
    recipe_RCARD_ExtPos[fabnum] := TextToInt(Mid(linetxt,delim1+1,delim2-delim1-1),10);

    delim1 := delim2;
    delim2 := Find(linetxt,',',13);
    recipe_FTRIM_ExtPos[fabnum] := TextToInt(Mid(linetxt,delim1+1,delim2-delim1-1),10);

    delim1 := delim2;
    delim2 := Find(linetxt,',',14);
    recipe_RTRIM_ExtPos[fabnum] := TextToInt(Mid(linetxt,delim1+1,delim2-delim1-1),10);

    delim1 := delim2;
    delim2 := Find(linetxt,',',15);
    recipe_BuffDwell[fabnum] := TextToInt(Mid(linetxt,delim1+1,delim2-delim1-1),10);

    delim1 := delim2;
    recipe_CardDwell[fabnum] := TextToInt(Mid(linetxt,delim1+1,Len(linetxt)-delim1-1),10);

    linetxt := ReadFileLine(ofile);        // Read next line of file.
}

CloseFile(ofile);    // Close the file.
 
cstring simply defines a local string variable to be used within a program.

Any variables you use in a program must be defined somewhere, either by a data tag or locally in the program. (Locally defined variables cannot be used outside the program.) In my code, the linetxt variable holds the current row of text being processed. It is only used within that program so there's no need to create a tag for it. But it still must be defined with cstring.
 
Last edited:
Yes, delim1 and delim2 are just local variables that I used to hold the character positions of the delimiters (commas in this case). Each TextToInt(Mid(...)) function is extracting the text between those two positions.
 
When you're thinking about this, it helps to write down one row of your recipe data with the commas and everything. Then number each character from left to right starting with zero. This is how the characters are counted by the Mid() function, and it will help you figure out the math necessary for the arguments.
 
I just write each value on it's own line.

e.g.
to save it:
// can add description after value
WriteFileLine( hfile, Seg1.Temp.AsText + " segment 1 temp" )

to get it back:
Seg1.Time := TextToInt( ReadFileLine( hfile), 10)
// TextToInt will ignore non-digits so descriptions after value is OK

you can add other 'notes' in the file as needed, just ReadFileLine() pass them.
 
It is the assignment operator. Whatever is calculated to the right of := is stored in the variable to the left of := .

In Crimson 3 I believe you can eliminate the colon and just use = .
 
Ken, what does the 10 do in your code:

Seg1.Time := TextToInt( ReadFileLine( hfile), 10)




I just write each value on it's own line.

e.g.
to save it:
// can add description after value
WriteFileLine( hfile, Seg1.Temp.AsText + " segment 1 temp" )

to get it back:
Seg1.Time := TextToInt( ReadFileLine( hfile), 10)
// TextToInt will ignore non-digits so descriptions after value is OK

you can add other 'notes' in the file as needed, just ReadFileLine() pass them.
 

Similar Topics

Hi. Last two days I was trying to get Red Lion Crimson Data Logger to write to Transcend 2GB Flashcard. I tried two of these - no luck. Crimson...
Replies
1
Views
1,592
I'm looking to purchase a large quantity of CompactFlash cards to have on hand for our G3 panels. Since the G3 seems to be picky about card brands...
Replies
5
Views
3,051
Okay, I finally got the noise issue under control on my checkweigher project and it is weighing boxes and logging them to compact flash. When I...
Replies
6
Views
2,934
Hey all, ive got a problem on a remote red lion G3 unit. The units have been working fine, but today when I tried to make a change to them, I got...
Replies
10
Views
8,769
While they came up quickly with a fix for the alarm date issue quickly I will have to drive around for a week or so, burning up a lot of fuel...
Replies
4
Views
271
Back
Top Bottom