Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » 4DIAC - Framework for Distributed Industrial Automation and Control » How to create IEC 61131-3 callable function in 4diac?
How to create IEC 61131-3 callable function in 4diac? [message #1863567] Sat, 10 February 2024 17:28 Go to next message
Ketut Kumajaya is currently offline Ketut KumajayaFriend
Messages: 26
Registered: January 2024
Junior Member
IEC 61131-3 SECANTF function:
FUNCTION SECANTF : REAL
  VAR_INPUT
    X : REAL;
    Y : REAL;
    P : UINT;
  END_VAR

  (* Ketut Kumajaya, 20/08/2018 *)
  (* Reference: https://lar.bnl.gov/properties/basic.html *)
  (* Reference: http://edge.rit.edu/edge/P07106/public/Nox.pdf *)

  IF (P = 3) THEN SECANTF := -Y + 4.863 * EXP((-5.9409785*(1.0 - X) + 1.3553888*EXPT(1.0 - X,1.5) - 0.46497607*EXPT(1.0 - X,2) - 1.5399043*EXPT(1.0 - X,4.5))/X);
    ELSE IF (P = 5) THEN SECANTF := -Y + 7251.0 * EXP((-6.71893 * (1.0 - X) + 1.35966 * EXPT((1.0 - X),1.5) - 1.3779 * EXPT((1.0 - X),2.5) - 4.051 * EXPT((1.0 - X),5))/X);
      ELSE SECANTF := 0.0;
    END_IF;
  END_IF;
END_FUNCTION


IEC 61131-3 SECANT function than call SECANTF function:
FUNCTION SECANT : REAL
  VAR_INPUT
    X1 : REAL;
    X2 : REAL;
    E1 : REAL;
    Y1 : REAL;
    P1 : UINT;
  END_VAR
  VAR
    XM1 : REAL;
    X0 : REAL;
    C1 : REAL;
  END_VAR

  (* Ketut Kumajaya, 20/08/2018 *)
  (* Adapted from: https://www.geeksforgeeks.org/program-to-find-root-of-an-equations-using-secant-method/ *)

  XM1 := E1 + 0.1; (* make sure to initially enter the loop *)

  IF (SECANTF(X1,Y1,P1) * SECANTF(X2,Y1,P1) < 0.0) THEN
    (* repeat the loop until the convergence *)
    WHILE (ABS(XM1 - X0) >= E1) DO
      (* calculate the intermediate value *)
       X0 := (X1 * SECANTF(X2,Y1,P1) - X2 * SECANTF(X1,Y1,P1)) / (SECANTF(X2,Y1,P1) - SECANTF(X1,Y1,P1));

      (* check if x0 is root of equation or not *)
      C1 := SECANTF(X1,Y1,P1) * SECANTF(X0,Y1,P1);

      (* update the value of interval *)
      X1 := X2;
      X2 := X0;

      (* if x0 is the root of equation then break the loop *)
      IF (C1 = 0.0) THEN
        EXIT;
      END_IF;
      XM1 := (X1 * SECANTF(X2,Y1,P1) - X2 * SECANTF(X1,Y1,P1)) / (SECANTF(X2,Y1,P1) - SECANTF(X1,Y1,P1));
    END_WHILE;
    SECANT := X0;
  ELSE
    SECANT := 0.0;
  END_IF;
END_FUNCTION


IEC 61499 SECANTF FB:
ALGORITHM calculate
(* Ketut Kumajaya, 20/08/2018 *)
(* Reference: https://lar.bnl.gov/properties/basic.html *)
(* Reference: http://edge.rit.edu/edge/P07106/public/Nox.pdf *)

IF (QI = 3) THEN (* argon function *)
	OUT := -Y + 4.863 * EXP((-5.9409785 * (1.0 - X) + 1.3553888 * EXPT(1.0 - X, 1.5) - 0.46497607 * EXPT(1.0 - X, 2) - 1.5399043 * EXPT(1.0 - X, 4.5)) / X);
ELSE
	IF (QI = 5) THEN (* nitrous oxide function *)
		OUT := -Y + 7251.0 * EXP((-6.71893 * (1.0 - X) + 1.35966 * EXPT((1.0 - X), 1.5) - 1.3779 * EXPT((1.0 - X), 2.5)	- 4.051 * EXPT((1.0	- X), 5)) / X);
	ELSE
		OUT := 0.0;
	END_IF;
END_IF;
END_ALGORITHM


IEC 61499 SECANT FB that call SECANTF FB. SECANTF1 is a SECANTF function block type registered inside SECANT FB:
ALGORITHM calculate
(* Ketut Kumajaya, 20/08/2018 *)
(* Adapted from: https://www.geeksforgeeks.org/program-to-find-root-of-an-equations-using-secant-method/ *)

XM1 := E1 + 0.1; (* make sure to initially enter the loop *)

(* IF (SECANTF(QI, X1, Y1) * SECANTF(QI, X2, Y1) < 0.0) THEN *)
SECANTF1(QI := QI, X := X1, Y := Y1);
Z1 := SECANTF1.OUT;
SECANTF1(QI := QI, X := X2, Y := Y1);
Z1 := Z1 * SECANTF1.OUT;
IF (Z1 < 0.0) THEN
	(* repeat the loop until the convergence *)
	WHILE (ABS(XM1 - X0) >= E1) DO
		(* calculate the intermediate value *)
		(* X0 := (X1 * SECANTF(QI, X2, Y1) - X2 * SECANTF(QI, X1, Y1)) / (SECANTF(QI, X2, Y1) - SECANTF(QI, X1, Y1)); *)
		SECANTF1(QI := QI, X := X2, Y := Y1);
		Z1 := X1 * SECANTF1.OUT;
		SECANTF1(QI := QI, X := X1, Y := Y1);
		Z1 := Z1 - X2 * SECANTF1.OUT;
		SECANTF1(QI := QI, X := X2, Y := Y1);
		X0 := SECANTF1.OUT;
		SECANTF1(QI := QI, X := X1, Y := Y1);
		X0 := X0 - SECANTF1.OUT;
		X0 := Z1 / X0;

		(* check if x0 is root of equation or not *)
		(* C1 := SECANTF(QI, X1, Y1) * SECANTF(QI, X0, Y1) *)
		SECANTF1(QI := QI, X := X1, Y := Y1);
		C1 := SECANTF1.OUT;
		SECANTF1(QI := QI, X := X0, Y := Y1);
		C1 := C1 * SECANTF1.OUT;

		(* update the value of interval *)
		X1 := X2;
		X2 := X0;

		(* if x0 is the root of equation then break the loop *)
		IF (C1 = 0.0) THEN
			EXIT;
		END_IF;
		(* XM1 := (X1 * SECANTF(QI, X2, Y1) - X2 * SECANTF(QI, X1, Y1)) / (SECANTF(QI, X2, Y1) - SECANTF(QI, X1, Y1)); *)
		SECANTF1(QI := QI, X := X2, Y := Y1);
		Z1 := X1 * SECANTF1.OUT;
		SECANTF1(QI := QI, X := X1, Y := Y1);
		Z1 := Z1 - X2 * SECANTF1.OUT;
		SECANTF1(QI := QI, X := X2, Y := Y1);
		XM1 := SECANTF1.OUT;
		SECANTF1(QI := QI, X := X1, Y := Y1);
		XM1 := XM1 - SECANTF1.OUT;
		XM1 := Z1 / XM1;
	END_WHILE;
	OUT := X0;
ELSE
	OUT := 0.0;
END_IF;
END_ALGORITHM


Is my implementation above correct or is there any a simpler way? It looks complicated but works.

EDIT:
I can make a C function call inside exported FB easily but I just want to write my FB completely in ST language.

[Updated on: Sun, 11 February 2024 01:29]

Report message to a moderator

Re: How to create IEC 61131-3 callable function in 4diac? [message #1863571 is a reply to message #1863567] Sun, 11 February 2024 11:27 Go to previous messageGo to next message
Alois Zoitl is currently offline Alois ZoitlFriend
Messages: 1639
Registered: January 2014
Senior Member

I think having the code in ST is definitely the better solution then in C. Especially from a maintainability and portability perspective.

As there is lot of math involved I have a hard time to say if it is correct. But I would have some general observations that may help you making your code more readable:

- Functions and Function blocks may not have the same name
- if your function is only used by one function block you can define the function as method inside of the function block.
- It loooks like your SECANTF Function is rather expensive. From what I see you always invoke it with two different parameter sets. Doing this once before all your ifs and storing the results in two variables leads to better performance but also to better readable code.
- why is SECANTF an FB and not a method of SECANT FB? A method can access inputs and outputs of the FB. In your case this means you could avoid the QI parameter which again results in a bit better readability of your code.

I hope this helps.
Re: How to create IEC 61131-3 callable function in 4diac? [message #1863572 is a reply to message #1863571] Sun, 11 February 2024 17:59 Go to previous messageGo to next message
Ketut Kumajaya is currently offline Ketut KumajayaFriend
Messages: 26
Registered: January 2024
Junior Member
METHOD SECANT_FUNC : REAL
VAR_INPUT
	SECANT_FUNC_X : REAL;
END_VAR

(* Ketut Kumajaya, 20/08/2018 *)
(* Reference: https://lar.bnl.gov/properties/basic.html *)
(* Reference: http://edge.rit.edu/edge/P07106/public/Nox.pdf *)
IF (SECANT_F = 3) THEN (* argon function *)
	SECANT_FUNC := -SECANT_Y + 4.863 * EXP((-5.9409785 * (1.0 - SECANT_FUNC_X) + 1.3553888 * EXPT(1.0 - SECANT_FUNC_X,
	1.5) - 0.46497607 * EXPT(1.0 - SECANT_FUNC_X, 2.0) - 1.5399043 * EXPT(1.0 - SECANT_FUNC_X, 4.5)) / SECANT_FUNC_X);
ELSE
	IF (SECANT_F = 5) THEN (* nitrous oxide function *)
		SECANT_FUNC := -SECANT_Y + 7251.0 * EXP((-6.71893 * (1.0 - SECANT_FUNC_X) + 1.35966 * EXPT((1.0 - SECANT_FUNC_X)
		, 1.5) - 1.3779 * EXPT((1.0 - SECANT_FUNC_X), 2.5) - 4.051 * EXPT((1.0 - SECANT_FUNC_X), 5)) / SECANT_FUNC_X);
	ELSE
		SECANT_FUNC := 0.0; (* for future function *)

	END_IF;
END_IF;
END_METHOD

METHOD SECANT : REAL
VAR_INPUT
	SECANT_X1 : REAL;
	SECANT_X2 : REAL;
	SECANT_E : REAL;
END_VAR

VAR_TEMP
	SECANT_XM : REAL;
	SECANT_X0 : REAL;
	SECANT_C : REAL;
	SECANT_X11 : REAL;
	SECANT_X21 : REAL;
END_VAR

(* Ketut Kumajaya, 20/08/2018 *)
(* Adapted from: https://www.geeksforgeeks.org/program-to-find-root-of-an-equations-using-secant-method/ *)
SECANT_X11 := SECANT_X1; (* to avoid writing to input variable *)

SECANT_X21 := SECANT_X2; (* to avoid writing to input variable *)

SECANT_XM := SECANT_E + 0.1; (* make sure to initially enter the loop *)

IF (SECANT_FUNC(SECANT_X11) * SECANT_FUNC(SECANT_X21) < 0.0) THEN
	(* repeat the loop until the convergence *)
	WHILE (ABS(SECANT_XM - SECANT_X0) >= SECANT_E) DO
		(* calculate the intermediate value *)
		SECANT_X0 := (SECANT_X11 * SECANT_FUNC(SECANT_X21) - SECANT_X21 * SECANT_FUNC(SECANT_X11)) / (SECANT_FUNC(
		SECANT_X21)
			- SECANT_FUNC(SECANT_X11));

		(* check if SECANT_X0 is root of equation or not *)
		SECANT_C := SECANT_FUNC(SECANT_X11) * SECANT_FUNC(SECANT_X0);

		(* update the value of interval *)
		SECANT_X11 := SECANT_X21;
		SECANT_X21 := SECANT_X0;

		(* if SECANT_X0 is the root of equation then break the loop *)
		IF (SECANT_C = 0.0) THEN
			EXIT;
		END_IF;

		SECANT_XM := (SECANT_X11 * SECANT_FUNC(SECANT_X21) - SECANT_X21 * SECANT_FUNC(SECANT_X11)) / (SECANT_FUNC(
		SECANT_X21)
			- SECANT_FUNC(SECANT_X11));
	END_WHILE;
	SECANT := SECANT_X0;
ELSE
	SECANT := 0.0;
END_IF;
END_METHOD

ALGORITHM calculate
...
Y1 := Y1 + 1.01325; (* absolute pressure *)
SECANT_Y := Y1 / 10.0;
SECANT_F := 3;
Y1 := -273.15 + SECANT(0.55615813, 1.0, 0.000001) * 150.687;
...
END_ALGORITHM


My function block implementation much better now. I set SECANT_F and SECANT_Y variable first and then call SECANT method per as your recommendation. Thank you very much.

[Updated on: Mon, 12 February 2024 01:31]

Report message to a moderator

Re: How to create IEC 61131-3 callable function in 4diac? [message #1863573 is a reply to message #1863572] Sun, 11 February 2024 20:44 Go to previous messageGo to next message
Alois Zoitl is currently offline Alois ZoitlFriend
Messages: 1639
Registered: January 2014
Senior Member

Great! Happy to help!
Re: How to create IEC 61131-3 callable function in 4diac? [message #1872288 is a reply to message #1863573] Sun, 27 October 2024 11:19 Go to previous messageGo to next message
Guido Piasenza is currently offline Guido PiasenzaFriend
Messages: 17
Registered: October 2024
Junior Member
Hello everyone, I feel enormously dumb, but where do you define FUNCTIONs, METHODs and ALGORITHMs ? I don't find any place in the interface to do that ! It seems you can define global functions and local (i.e. FB local) methods... how ?
Re: How to create IEC 61131-3 callable function in 4diac? [message #1872291 is a reply to message #1872288] Sun, 27 October 2024 12:09 Go to previous messageGo to next message
Alois Zoitl is currently offline Alois ZoitlFriend
Messages: 1639
Registered: January 2014
Senior Member

Hi,

you do that as part of the textual syntax. in IEC 61131-3 where this syntax is coming from you define blocks of VAR_INPUT ... END_VAR VAR_OUTPUT ... END_VAR. Our code completion should guide you. Or you can also find quite some information on IEC 61131-3 interface specification in Structured TExt in the web.

[Updated on: Sun, 27 October 2024 18:14]

Report message to a moderator

Re: How to create IEC 61131-3 callable function in 4diac? [message #1872383 is a reply to message #1872291] Wed, 30 October 2024 08:00 Go to previous messageGo to next message
Guido Piasenza is currently offline Guido PiasenzaFriend
Messages: 17
Registered: October 2024
Junior Member
Ah, now I see the problem ! I was using the official version of the IDE (the one provided on the download page), which lacks a lot of features !

Now I built the "develop" branch from source, and I find all the features you mention.

I have a question about branches though... I see the following:

develop
freeze
release
3.0.x

What is the meaning of these branches ? I suppose "develop"is the curring edge branch, what's the difference between freeze and release ?

I hope you will provide updated binary installers soon, the new version is way better than the "official" one.

Ah, final question: is there some sort of compatibility mapping between IDE and FORTE branches / commits ?
Re: How to create IEC 61131-3 callable function in 4diac? [message #1872395 is a reply to message #1872383] Wed, 30 October 2024 10:05 Go to previous messageGo to next message
Alois Zoitl is currently offline Alois ZoitlFriend
Messages: 1639
Registered: January 2014
Senior Member

Yes the develop branch is the branch where we do all the developments. There it can happen that stuff break or are not working.

The release branch is the current release.

The freeze branch is a branch which we use to test and stabilize features for our prerelease branch. This is the 3.0.x which holds the rather stable version for the next release.

The 4diac FORTE branches with the same name should be compatible to the 4diac IDE branches.

We are heavily working on the upcoming 3.0.0 release. The reason why it is not yet a public release is that there are a few breaking changes upcoming for 4diac FORTE and the 3.0.0 release should have a stable 4diac FORTE API that will be fixed for many years.

I hope this clarifies the situation.
Re: How to create IEC 61131-3 callable function in 4diac? [message #1872407 is a reply to message #1872395] Wed, 30 October 2024 11:30 Go to previous messageGo to next message
Guido Piasenza is currently offline Guido PiasenzaFriend
Messages: 17
Registered: October 2024
Junior Member
Ok, thanks !

When trying to build the release branch I see a strange problem, the build process freezes after a few seconds:

[INFO] Scanning for projects...
[WARNING] The POM for org.apache.commons:commons-lang3:jar:3.8.1 is invalid, transitive dependencies (if any) will not be available: 1 problem was encountered while building the effective model for org.apache.commons:commons-lang3:3.8.1
[FATAL] Non-parseable POM /home/gpiasenza/.m2/repository/org/apache/commons/commons-parent/47/commons-parent-47.pom: UTF-8 BOM plus xml decl of ISO-8859-1 is incompatible (position: START_DOCUMENT seen <?xml version="1.0" encoding="ISO-8859-1"... @1:42) @ /home/gpiasenza/.m2/repository/org/apache/commons/commons-parent/47/commons-parent-47.pom, line 1, column 42

[WARNING] The POM for commons-io:commons-io:jar:2.5 is invalid, transitive dependencies (if any) will not be available: 1 problem was encountered while building the effective model for commons-io:commons-io:2.5
[FATAL] Non-parseable POM /home/gpiasenza/.m2/repository/org/apache/commons/commons-parent/39/commons-parent-39.pom: UTF-8 BOM plus xml decl of ISO-8859-1 is incompatible (position: START_DOCUMENT seen <?xml version="1.0" encoding="ISO-8859-1"... @1:42) @ /home/gpiasenza/.m2/repository/org/apache/commons/commons-parent/39/commons-parent-39.pom, line 1, column 42

[WARNING] The POM for commons-io:commons-io:jar:2.6 is invalid, transitive dependencies (if any) will not be available: 1 problem was encountered while building the effective model for commons-io:commons-io:2.6
[FATAL] Non-parseable POM /home/gpiasenza/.m2/repository/org/apache/commons/commons-parent/42/commons-parent-42.pom: UTF-8 BOM plus xml decl of ISO-8859-1 is incompatible (position: START_DOCUMENT seen <?xml version="1.0" encoding="ISO-8859-1"... @1:42) @ /home/gpiasenza/.m2/repository/org/apache/commons/commons-parent/42/commons-parent-42.pom, line 1, column 42

[WARNING] The POM for org.apache.commons:commons-compress:jar:1.20 is invalid, transitive dependencies (if any) will not be available: 1 problem was encountered while building the effective model for org.apache.commons:commons-compress:1.20
[FATAL] Non-parseable POM /home/gpiasenza/.m2/repository/org/apache/commons/commons-parent/48/commons-parent-48.pom: UTF-8 BOM plus xml decl of ISO-8859-1 is incompatible (position: START_DOCUMENT seen <?xml version="1.0" encoding="ISO-8859-1"... @1:42) @ /home/gpiasenza/.m2/repository/org/apache/commons/commons-parent/48/commons-parent-48.pom, line 1, column 42

[WARNING] The POM for org.apache.commons:commons-exec:jar:1.3 is invalid, transitive dependencies (if any) will not be available: 1 problem was encountered while building the effective model for org.apache.commons:commons-exec:1.3
[FATAL] Non-parseable POM /home/gpiasenza/.m2/repository/org/apache/commons/commons-parent/35/commons-parent-35.pom: UTF-8 BOM plus xml decl of ISO-8859-1 is incompatible (position: START_DOCUMENT seen <?xml version="1.0" encoding="ISO-8859-1"... @1:42) @ /home/gpiasenza/.m2/repository/org/apache/commons/commons-parent/35/commons-parent-35.pom, line 1, column 42

[WARNING] The POM for org.apache.commons:commons-compress:jar:sources:1.20 is invalid, transitive dependencies (if any) will not be available: 1 problem was encountered while building the effective model for org.apache.commons:commons-compress:1.20
[FATAL] Non-parseable POM /home/gpiasenza/.m2/repository/org/apache/commons/commons-parent/48/commons-parent-48.pom: UTF-8 BOM plus xml decl of ISO-8859-1 is incompatible (position: START_DOCUMENT seen <?xml version="1.0" encoding="ISO-8859-1"... @1:42) @ /home/gpiasenza/.m2/repository/org/apache/commons/commons-parent/48/commons-parent-48.pom, line 1, column 42

[INFO] Computing target platform for MavenProject: org.eclipse.fordiac:org.eclipse.fordiac.ide.product:2.0.1-SNAPSHOT @ /home/gpiasenza/WinShare/Download/Automazione/Source/4diac-ide/plugins/org.eclipse.fordiac.ide.product/pom.xml
[WARNING] No system packages found in profile nor toolchain for JRE-1.1, using current JRE system packages.
This can cause faulty dependency resolution, consider adding a definition for a 'jdk' with id=JRE-1.1 in your toolchains.xml
[WARNING] No system packages found in profile nor toolchain for JavaSE-11, using current JRE system packages.
This can cause faulty dependency resolution, consider adding a definition for a 'jdk' with id=JavaSE-11 in your toolchains.xml
[WARNING] No system packages found in profile nor toolchain for JavaSE-15, using current JRE system packages.
This can cause faulty dependency resolution, consider adding a definition for a 'jdk' with id=JavaSE-15 in your toolchains.xml
[WARNING] No system packages found in profile nor toolchain for JavaSE-16, using current JRE system packages.
This can cause faulty dependency resolution, consider adding a definition for a 'jdk' with id=JavaSE-16 in your toolchains.xml
[WARNING] No system packages found in profile nor toolchain for JavaSE-17, using current JRE system packages.
This can cause faulty dependency resolution, consider adding a definition for a 'jdk' with id=JavaSE-17 in your toolchains.xml

This does not happen with other branches.
Re: How to create IEC 61131-3 callable function in 4diac? [message #1872431 is a reply to message #1872407] Wed, 30 October 2024 20:27 Go to previous messageGo to next message
Alois Zoitl is currently offline Alois ZoitlFriend
Messages: 1639
Registered: January 2014
Senior Member

I fear that the release branch is currently not building anymore. Fixing that would be more work then we currently think it is worth spending on it. Especially as the upcoming version will be so much better. So we would like to spend our effort in getting the remaining bits and pieces fixed. Therefore we would appreciate especially people testing and evaluating the 3.0.x branch and providing feedback there.
Re: How to create IEC 61131-3 callable function in 4diac? [message #1872437 is a reply to message #1872431] Thu, 31 October 2024 08:44 Go to previous messageGo to next message
Guido Piasenza is currently offline Guido PiasenzaFriend
Messages: 17
Registered: October 2024
Junior Member
Ok, I will try the 3.0.x branch. Which FORTE release should I use with that ? I see the following branches:

remotes/origin/1.10.x
remotes/origin/1.11.x
remotes/origin/1.12.x
remotes/origin/1.13.x
remotes/origin/1.14.x
remotes/origin/1.8.x
remotes/origin/1.9.x
remotes/origin/2.0.x
remotes/origin/HEAD -> origin/release
remotes/origin/develop
remotes/origin/feature/opcua/pubsub
remotes/origin/feature/plcdiac
remotes/origin/freeze
remotes/origin/jcabralmt7/updateCI
remotes/origin/release

So there's no 3.0.x branch on the runtime, should I use "develop" ?
Re: How to create IEC 61131-3 callable function in 4diac? [message #1872482 is a reply to message #1872437] Fri, 01 November 2024 08:20 Go to previous message
Alois Zoitl is currently offline Alois ZoitlFriend
Messages: 1639
Registered: January 2014
Senior Member

As not so much 4diac FORTE development is happening you can either use develop or freeze. As an major change is coming to 4diac FORTE in he next days you maybe better of with freeze. But as you are also working on the code develop should also be fine. But maybe you then want to switch also your IDE to develop so that you get the according code generator changes as well.
Previous Topic:Analysis of LUA problems on IDE 3.0.x + Forte develop
Next Topic:"Internal FBs" in a Basic Function Blocks
Goto Forum:
  


Current Time: Wed Feb 05 16:57:23 GMT 2025

Powered by FUDForum. Page generated in 0.04991 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top