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 12:28  |
Eclipse User |
|
|
|
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: Sat, 10 February 2024 20:29] by Moderator
|
|
| |
Re: How to create IEC 61131-3 callable function in 4diac? [message #1863572 is a reply to message #1863571] |
Sun, 11 February 2024 12:59   |
Eclipse User |
|
|
|
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: Sun, 11 February 2024 20:31] by Moderator
|
|
| | | | | |
Re: How to create IEC 61131-3 callable function in 4diac? [message #1872407 is a reply to message #1872395] |
Wed, 30 October 2024 07:30   |
Eclipse User |
|
|
|
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 #1872482 is a reply to message #1872437] |
Fri, 01 November 2024 04:20  |
Eclipse User |
|
|
|
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.
|
|
|
Goto Forum:
Current Time: Mon Jun 16 04:11:48 EDT 2025
Powered by FUDForum. Page generated in 0.26995 seconds
|