As I'm just in the flow of typing along (have to get a new backspace key soon)...
I tried to write a function block in CoDeSys that what somewhat behave like the ones I use in RSLogix every other day - Didn't turn out well and this might turn into a rant
Writing the basic functionality for a fixed lenght array of a data type that is defined in the function block was easy, but in RSLogix I can feed the FFL & FFU with an array of every data type know to man (+UDTs) that can be as long as the controller memory can make it.
I remembered using pointers during my last exposure to Step 7 programming in technical college. I looked into the laughable helpfile that is supplied with the software and spent some time on google. I came up with something that can handle an array of variable length for a data type that fits in a DWORD. Thats nice, and probably as far as I will take it now.
I asked in a german forum if there is another way to do it, or a way to use this function with a UDT without having to rewrite the funtions defintion each time I wanted to use another UDT. I wanted to abstract the function as much as possible.
The answer was that pointers are not defined in IEC 61131-3 and are a general No-No and should be used only if absolutely needed. Also the implementation is not mandatory for different CoDeSys packages.
Basically that answer is fine for me, the problem is not solvable within the technical boundarys of CoDeSys - or is it? Maybe some of you folks here know a way to do it
What I personally took from it is the knowledge that I have to thank my boss for every buck he pays for RSLogix licenses. Working 10+ years with RSLogix I tend to find Step 7 and CoDeSys really clumsy to work with, its a trip into history, '98 when I first used Step 7 after using a field programmer on a Kloeckner-Moeller PS3 before... Something like the strong binding to data types (when I want to COP a REAL into a DINT and create a mess its my problem, isn't it?) makes me think about what Rockwell is doing different, and for my part better.
Done. Delete if unsuitable
Maybe I should add some code:
I tried to write a function block in CoDeSys that what somewhat behave like the ones I use in RSLogix every other day - Didn't turn out well and this might turn into a rant
Writing the basic functionality for a fixed lenght array of a data type that is defined in the function block was easy, but in RSLogix I can feed the FFL & FFU with an array of every data type know to man (+UDTs) that can be as long as the controller memory can make it.
I remembered using pointers during my last exposure to Step 7 programming in technical college. I looked into the laughable helpfile that is supplied with the software and spent some time on google. I came up with something that can handle an array of variable length for a data type that fits in a DWORD. Thats nice, and probably as far as I will take it now.
I asked in a german forum if there is another way to do it, or a way to use this function with a UDT without having to rewrite the funtions defintion each time I wanted to use another UDT. I wanted to abstract the function as much as possible.
The answer was that pointers are not defined in IEC 61131-3 and are a general No-No and should be used only if absolutely needed. Also the implementation is not mandatory for different CoDeSys packages.
Basically that answer is fine for me, the problem is not solvable within the technical boundarys of CoDeSys - or is it? Maybe some of you folks here know a way to do it
What I personally took from it is the knowledge that I have to thank my boss for every buck he pays for RSLogix licenses. Working 10+ years with RSLogix I tend to find Step 7 and CoDeSys really clumsy to work with, its a trip into history, '98 when I first used Step 7 after using a field programmer on a Kloeckner-Moeller PS3 before... Something like the strong binding to data types (when I want to COP a REAL into a DINT and create a mess its my problem, isn't it?) makes me think about what Rockwell is doing different, and for my part better.
Done. Delete if unsuitable
Maybe I should add some code:
Code:
[SIZE="1"]FUNCTION_BLOCK FIFO
VAR_INPUT
LoadValue: POINTER TO DWORD;
UnloadValue: POINTER TO DWORD;
FirstElement: POINTER TO DWORD;
END_VAR
VAR
i: INT;
Size: UDINT;
DestPointer: POINTER TO DWORD;
SourcePointer: POINTER TO DWORD;
END_VAR
VAR_IN_OUT
Ctrl: ST_CTRL;
END_VAR
Size := SIZEOF(FirstElement^);
IF Ctrl.Full AND Ctrl.Autounload AND Ctrl.Load THEN
SourcePointer := FirstElement + ((Ctrl.Position - 1) * Size);
UnloadValue^ := SourcePointer^;
Ctrl.Position := Ctrl.Position - 1;
END_IF;
IF Ctrl.Load AND (Ctrl.Position < Ctrl.Length) THEN
Ctrl.Done := FALSE;
FOR i := (Ctrl.Position) TO 1 BY -1 DO
DestPointer := FirstElement + (i * Size);
SourcePointer := FirstElement + ((i-1) * Size);
DestPointer^ := SourcePointer^;
END_FOR;
FirstElement^ := LoadValue^;
Ctrl.Position := Ctrl.Position + 1;
Ctrl.Done := TRUE;
END_IF;
IF Ctrl.Unload AND (Ctrl.Position > 0) THEN
Ctrl.Done := FALSE;
SourcePointer := FirstElement + ((Ctrl.Position - 1) * Size);
UnloadValue^ := SourcePointer^;
SourcePointer^ := 0;
Ctrl.Position := Ctrl.Position - 1;
Ctrl.Done := TRUE;
END_IF;
IF Ctrl.Position = 0 THEN
Ctrl.Empty := TRUE;
ELSE
Ctrl.Empty := FALSE;
END_IF;
IF Ctrl.Position < Ctrl.Length THEN
Ctrl.Full := FALSE;
ELSE
Ctrl.Full := TRUE;
END_IF;
[/SIZE]
Last edited: