I am forced to really learn how to program a S7

Join Date
Apr 2002
Location
No income tax, no capital gains tax. Freedom!
Posts
8,391
Code:
1 // TITLE=RK4    // The compiler doesn't like my title statement, why?
2
3 DATA_BLOCK db_RK4
4 STRUCT
5    A: INT;
6     B: INT;
7    C: INT;
8 END_STRUCT
9 END_DATA_BLOCK
I get an.....****, the SCL editor will not even let me cut and paste an error message....
E Ln 000009 Col 000: Unexpect input end
error.
I had to manually type that.
Also SCL doesn't like my TITLE statement if I remove the // before it.

I have read the document SCL_e.pdf. It doesn't say I need to put semi colons after the END_STRUCT or the END_DATA_BLOCK.

Does any body know what is going on?

BTW, RK4 is a Runge-Kutte ODE integrator. The math part will be easy after I learn how to jump through the Siemens hoops.

I also will be writing an Ethernet interface to our controller.
From what I gather the PN/DP T blocks just send raw packets with no application layer inside so one can make up any protocol they like. However, this also means tha a PLC program is required to do even the simplest data transfers.

Note, I refused to be assimilated.
 
You can have templates inserted, also for DBs.
But, there seems to be an error in the standard template for DBs. An ";" is missing after the END_STRUCT !

You also need a "BEGIN" statement.
Code:
DATA_BLOCK "db_RK4"
[COLOR=red][B]TITLE=RK4[/B][/COLOR][COLOR=black] // TITLE must be after start of DATA_BLOCK[/COLOR]
STRUCT
   A: INT;
   B: INT;
   C: INT;
END_STRUCT [COLOR=red][B];[/B][/COLOR][COLOR=black] // need a ";" here[/COLOR]
[COLOR=red][B]BEGIN[/B][/COLOR][COLOR=black] // need a BEGIN here[/COLOR]
[COLOR=red][COLOR=black]// if you want to initialise values, this is where you do it:[/COLOR][/COLOR]
[COLOR=red][COLOR=#000000]// A:=1 ;[/COLOR][/COLOR]
[COLOR=red][COLOR=#000000][/COLOR][COLOR=red][COLOR=#000000]// B:=2 ;[/COLOR][/COLOR]
[COLOR=red][COLOR=#000000]// C:=3 ;[/COLOR][/COLOR]
[/COLOR]END_DATA_BLOCK
 
My RK4 routine is coming along nicely but.

Code:
DATA_BLOCK "db_RK4"
TITLE=RK4 // TITLE must be after start of DATA_BLOCK
STRUCT
   A1: REAL;
   A2: REAL;
   C:  REAL;
   K:  REAL;
   h: REAL;                 // Simulation update time interval
END_STRUCT;
BEGIN
    h:=0.01;                // Update time 0.01 seconds or minutes but stay consistent
END_DATA_BLOCK
FUNCTION fc_RK4 : REAL
CONST
    N:=2;                    // The Number of state variables-1
END_CONST
VAR_INPUT
    I: INT;
    X: REAL;
    Y: ARRAY[0..N] OF REAL;
END_VAR
    CASE I OF
        0: fc_RK4:=Y[1];
        1: fc_RK4:=Y[2];
        2: fc_RK4:=-"db_RK4".A2*Y[2]-"db_RK4".A1*Y[1]+"db_RK4".A1*"db_RK4".K* + "db_RK4".C;
    END_CASE;
END_FUNCTION

FUNCTION_BLOCK fb_RK4
// TITLE=RK4    // The compiler doesn't like my title statement, why?
VAR_INPUT
    Xi: REAL;       // TIME
    Yi: ARRAY[0..2] OF REAL;
END_VAR
VAR_TEMP
    K1: ARRAY[0..2] OF REAL;
    K2: ARRAY[0..2] OF REAL;
    K3: ARRAY[0..2] OF REAL;
    K4: ARRAY[0..2] OF REAL;
    Ytemp: ARRAY[0..2] OF REAL;
    h: REAL;
    I: INT;
END_VAR;
    h:="db_RK4".h;
    FOR I:=0 TO 2 BY 1 DO
        K1[I]:=h*fc_RK4(I:=I,X:=Xi,Y:=Yi);
        Ytemp[I]:=Yi[I]+0.5*K1[I];
    END_FOR;
    FOR I:=0 TO 2 BY 1 DO
        K2[I]:=h*fc_RK4(I:=I,X:=Xi+0.5*h,Y:=Ytemp);
        Ytemp[I]:=Yi[I]+0.5*K2[I];
    END_FOR;
    FOR I:=0 TO 2 BY 1 DO
        K3[I]:=h*fc_RK4(I:=I,X:=Xi+0.5*h,Y:=Ytemp);
        Ytemp[I]:=Yi[I]+0.5*K3[I];
    END_FOR;
    FOR I:=0 TO 2 BY 1 DO
        K4[I]:=h*fc_RK4(I:=I,X:=Xi+h,Y:=Ytemp);
    END_FOR;
    FOR I:=0 TO 2 BY 1 DO
        Yi[I]:=Yi[I]+(K1[I]+2*K2[I]+2*K3[I]+K4[I])/6.0;
    END_FOR;
END_FUNCTION_BLOCK
There are too many places where I use the number 2. I can define a
Code:
CONST
   N:=2;
END_CONST
within each block and that will work but I would like to declare N to be at least global to the RK4 text file. The SCL_e.pdf doesn't say how to define global constants. In C I can define a
Code:
#define N 2   // OR
at the beginning of the file or include it in a header file and include it for all c files to use. In Java I would import the module with the definition.

So how do I declare a global constant in SCL? Actually, I bet the real problem is how does one access a global constant in SCL.

BTW, this RK4 file will allow one to simulate complex systems once I am done. I still need to add some more code and test it but I will share it with everyone on my ftp site.

Thanks.
 
Sadly, there are no global constants per se.

Of course, you can set aside some variables to be used as constants, that be Merkers or a shared DB.

I looked into it once. My idea was to have some global configuration values that would take effect through all blocks, and without having to set aside variables for that purpose. But no can-do.

Are there global constants in IEC ST ?

I am interested in your simulation code. Maybe I can use it.
 
Are there global constants in IEC ST ?
I don't know. I will need to look that up. I have the specification around at work. I do know that not being able to adjust the side all the arrays in a project by changing just one constant is a major flaw for system integrators that have the need to change array sizes based on the project or machine.

I could define global constants back in the 1970s. ST and SCL appears to be a big step backwards.

I am interested in your simulation code. Maybe I can use it.
It will be put here:
http://www.deltamotion.com/peter/S7/
You can see there are previous efforts from the late 90s there. The problem is that I never used the S7 enough to get past the learning curve.

Unfortunately you will have to change the array lengths in every function and DB. The other option is to make each array 8 items long hoping no one uses more states and then pass N as parameter to each function or store N in the DB where each function can get at it. I think I will do that until I find a better solution.

What would you use it for? I am trying to make a better version of the FOPDT and SOPDT simulator that Pandiani and I worked on a few years back. This new simulator should be more general. The previous versions couldn't simulate non-linear systems and didn't handle simulating the dead time in smooth increments as nicely as this version will. Also FOPDT and SOPDT are two separate hard coded modules instead of one.

What kind of little functions would be handy? Once I get started I can kick out all sorts of finding bits, counting bits, random number routines and put them in my s7 ftp site.
 
Are there global constants in IEC ST ?

Code:
(* GLOBAL CONSTANTS *)
VAR_GLOBAL CONSTANT
 nFLT_WORDS: UINT := 4;    (*Number of fault words*)
 nPROBE_WORDS: UINT := 40;  (*Probes map size in words*)
 nJOBS: UINT := 10;       (*Number of stored jobs*)
END_VAR

I have just copied this fragment from an actual TwinCAT program. Or did you mean something else?
 
Code:
(* GLOBAL CONSTANTS *)
VAR_GLOBAL CONSTANT
 nFLT_WORDS: UINT := 4;    (*Number of fault words*)
 nPROBE_WORDS: UINT := 40;  (*Probes map size in words*)
 nJOBS: UINT := 10;       (*Number of stored jobs*)
END_VAR

I have just copied this fragment from an actual TwinCAT program. Or did you mean something else?
I think this is what we mean.
Can you declare an array like this:
myRealARRAY : ARRAY[0..iSize] OF REAL ;
?
It is exactly this that you cannot do in Siemens SCL (as far as I know).

I have seen some other advantages with TwinCat and CoDeSys that has made me want to change. Unfortunately, it is totally impossible to switch platforms.
I am waiting to see what the new SCL in the next generation STEP7 will give us.
 
I think Iunderstand why it is that way. New question

I think this is what we mean.
Can you declare an array like this:
myRealARRAY : ARRAY[0..iSize] OF REAL ;
?
It is exactly this that you cannot do in Siemens SCL (as far as I know).
I just tried using LadderLogic's example. It didn't work. SCL doesn't understand VAR_GLOBAL CONSTANT.

I can understand why. Changing the constant that defines the array length would required all the other modules downloaded in the S7 to change the array sizes. That can't happen on-the-fly. The global constant feature is what you give up if you want to change modules on-the-fly.

This one I will not hold against Siemens.......for now. Meanwhile I will allocate 4 states for now and make N a variable in the DB that all routines can access.

If I want to export modules to my ftp directory what is the best way to export just one source file at a time? The Save As doesn't let me put the files on my desk top. I can't drag the RK4 file to the desk top. The RK4 file must be burried deep in the S7Proj database. I just archived the whole project in the past. I know it is easy enough to open two projects and copy files between them how do I export just the source code to put in the S7 ftp site? Right now it appears that copy and paste is the way to do it.

The stupid Simatic manager seems to only let me save whole projects even when I clicked on RK4 in the sources area.
 
To export stl and scl sources:
In sources area, press right mouse button and then from list export.

About global constants. I myself consider shared DB:s as global constants. It does not take many extra steps to use them that way. Ofcourse it limits their use. But as you said its trade off to make for ability to donwload single blocks.

In CoDeSys there is nothing like DB:s so they actually have to use global variable declaration.

I have one question also, does anyone know what SCL compile control file is, what is its use and how to use one?
 
Last edited:
I think this is what we mean.
Can you declare an array like this:
myRealARRAY : ARRAY[0..iSize] OF REAL ;

In TwinCAT, I can:
Code:
arrProbeMap: ARRAY[1..nPROBE_WORDS] OF WORD;

This line is taken from the global variables declaration of the same program as above.

The question was about the ability to do that in IEC ST. Since TwinCAT (i.e. CoDeSys 2) is usually considered a de-facto the closest implementation of the standard, the answer is yes.

Sorry for Siemens troubles.
 
Re code library suggestions.

Here are some that I could use:

1. Linear approximation, on something more advanced than least squares method.

2. Exponential approximation.

At the moment, I have a fairly simply linear approximation based on least squares. Works OK, but the method puts too much weight on "outliers".

3. Various filters.

4. Alternative timer.
Sporting functions such as memorizing the last time clocked, "pause" input, "reset" input. And based on DINT milliseconds rather than TIME, for easy calculation of the setpoint in other functions.

5. Alternative analog scaling.
With integral alarm levels, and filtering.

6. Alarm system.
Scanning of alarms, with memory, acknowledge, acknowledge to/from HMI.
To fit nicely into WinCC Flex and Protool alarm system.

I have some of the above already. But they could do with a complete rewrite.
 
I am really begining to hate this

Code:
(* CONTROL *)
DATA_BLOCK dbControl
TITLE='dbControl'
STRUCT
   Kc:  REAL;                                   // Controller gain
   Ti:  REAL;                                   // Integrator gain
   Td:  REAL;                                   // Derivative gain
   DeltaT:  REAL;                               // Simulation update time interval
   CO:  REAL;                                   // Control Output -100 to 100% 
   ER:  ARRAY[0..2] OF REAL;                    // Engineering units
   K:   ARRAY[0..2] OF REAL;                    // Gains
   MinCO: REAL;
   MaxCO: REAL;
END_STRUCT;
BEGIN
    DeltaT:=0.01;                               // Update time 0.01 seconds or minutes but stay consistent
    ER[0]:=0.0;
    ER[1]:=0.0;
    K[0]:=0.0;
END_DATA_BLOCK
 
FUNCTION_BLOCK fbControl
TITLE='fbControl'
VAR_INPUT
    SP: REAL;
    PV: REAL; 
END_VAR
VAR_TEMP
    CO: REAL;
END_VAR
IF dbControl.K[0]=0.0 THEN
    dbControl.K[0]:=dbControl.Kc*(dbControl.DeltaT/dbControl.Ti+1.0+dbControl.Td/dbControl.DeltaT);
    dbControl.K[1]:=-dbControl.Kc-2*dbControl.Td/dbControl.DeltaT;
    dbControl.K[2]:=dbControl.Kc*dbControl.Td/dbControl.DeltaT;
END_IF;
dbControl.ER[2]:=dbControl.ER[1];
dbControl.ER[1]:=dbControl.ER[0];
dbControl.ER[0]:=SP-PV;
CO:=dbControl.CO+dbControl.K[0]*dbControl.ER[0]+dbControl.K[1]*dbControl.ER[1]+dbControl.K[2]*dbControl.ER[2];
CO:=LIMIT(MN:=0.0, IN:=CO, MX:=100.0);
dbControl.CO:=CO;
END_FUNCTION_BLOCK

Code:
(* SYSTEM OF DIFFERENTIAL EQUATIONS *)
DATA_BLOCK dbSODE
TITLE='dbSODE'
STRUCT
   K:  REAL;                                    // System gain
   A0: REAL;
   A1: REAL;
   A2: REAL;
   DeadTime: REAL;
   PVss:  REAL;                                 // ******t PV
   dydt: REAL;
END_STRUCT;
BEGIN
END_DATA_BLOCK
 
FUNCTION_BLOCK fbSODE
TITLE='fbSODE'
VAR_INPUT
    I: INT;
    X: REAL;
    Y: ARRAY[0..3] OF REAL;
END_VAR
CASE I OF
    0: dbSODE.dydt:=Y[1];
    1: dbSODE.dydt:=Y[2];
    2: fbControl.dbControl(SP:=100.0, PV:=Y[0]);   // ERRORS HERE
       dbSODE.dydt:=-dbSODE.A2*Y[2]-dbSODE.A1*Y[1]+dbSODE.A1*db_RK4.K*dbControl.CO+dbSODE.PVss;
END_CASE;
END_FUNCTION_BLOCK

The CONTROL module compiles. The SODE module gives me an error at line 29 saying the system table enetry for instance DB or DB of type UDT does not match the called FB or UDT.

I compile the CONTROL module first. That should define the dbControl. However, the SODE module doesn't seem to understand that the dbControl has been defined.

I am begining to hate this. I have seen nothing in the documentation that say that modules must be compiled in a certain order but that seems to be the case and even so the Simatic manager appears to not update the symbol table.

There is definitely something wrong. I deleted fbControl and dbControl from the symbol table and recompile Control again. The symbol table should have been updated with new entries for fbControl and dbControl but it wasn't. Does the symbol table know about the fields in the DB?


1. Linear approximation, on something more advanced than least squares method.
Least squares is the way to go if you want linear approximation. I provided an example of second order or quadratic AND cubic approximation last week and no one but Norm seemed to care. How many points are going to be used in the approximation? Start a thread on this topic.

2. Exponential approximation.

At the moment, I have a fairly simply linear approximation based on least squares. Works OK, but the method puts too much weight on "outliers".
Do you need the approximation over a wide range? That is when it gets difficult. It is best if one know around which point the approximation is going to be over. It is easy to do smoothing after the fact where there are N points before and N points after the point that is being smoothed and then the smoothing filter is moved over all the data. There is an algoithm called Savitsky-Golay which is basically what I was trying to show last week in my movie.


3. Various filters.
A four pole Butterworth filter should be easy.

4. Alternative timer.
Sporting functions such as memorizing the last time clocked, "pause" input, "reset" input. And based on DINT milliseconds rather than TIME, for easy calculation of the setpoint in other functions.
That isn't hard IF one can find a real time clock. I know real time clock has been mentioned above but I have had my head up Siemen's a$$ trying to figure this **** put.

5. Alternative analog scaling.
Making a Rockwell like SCP function is easy.

With integral alarm levels, and filtering.
I think I know what you mean.

6. Alarm system.
Scanning of alarms, with memory, acknowledge, acknowledge to/from HMI.
To fit nicely into WinCC Flex and Protool alarm system.

I have some of the above already. But they could do with a complete rewrite
I am thinking more along the lines of tricky math algorithms.
 
Last edited:

Similar Topics

is it possible to external read the Forced_value list from a PLC using UnityPRO? I need to get this data. It could be via modbus, ops... or even...
Replies
5
Views
2,444
So View SE 10 was the last to support HMI alarm tags. View SE 11 says you must migrate them to Alarm and Events. The View SE alarm summary will...
Replies
0
Views
1,895
I'm using an L33 PLC with an Ethernet I/P Point IO 1734-VHSC24 high speed counter to read in from an encoder, then calculating the counts per...
Replies
5
Views
1,752
So I have a dryer project that connects to the PLC and says "equal". When I connect it shows there are forced bits, but when I double-click on the...
Replies
3
Views
2,186
Hello All, I am using Allen Bradley Control Logix system, from the machine supplier I got the controller program developed in RS Logix 5000...
Replies
2
Views
2,034
Back
Top Bottom