-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathFbPIDstep.SCL
More file actions
320 lines (300 loc) · 9.4 KB
/
Copy pathFbPIDstep.SCL
File metadata and controls
320 lines (300 loc) · 9.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
FUNCTION_BLOCK "FbPIDstep"
TITLE = 'ÏÈÄ-ðåãóëÿòîð ñ äâóìÿ äèñêðåòíûìè âûõîäàìè.'
{ S7_read_back := 'true' ;
S7_blockview := 'big' }
AUTHOR : SI_DM_VA
FAMILY : LIB_PLC
VERSION : '1.8'
VAR_INPUT
PV :REAL := 0.0 ; // Èçìåðåííîå çíà÷åíèå ðåãóëèðóåìîãî ïàðàìåòðà 0...100[%].
SP :REAL := 0.0 ; // Çàäàííîå çíà÷åíèå ðåãóëèðóåìîãî ïàðàìåòðà 0...100[%].
COM_RST :BOOL := FALSE; // Ïîëíàÿ ïåðåçàãðóçêà.
LMNR_HS :BOOL := FALSE; // Äàò÷èê îáðàííîé ñâÿçè êëàïàí îòêðûò.
LMNR_LS :BOOL := FALSE; // Äàò÷èê îáðàííîé ñâÿçè êëàïàí çàêðûò.
LMNS_ON :BOOL := FALSE; // Âêëþ÷èòü ðóæíîé ðåæèì óïðàâëåíèÿ.
LMNUP :BOOL := FALSE; // Êîìàíäà îòêðûòü â ðó÷íîì ðåæèìå.
LMNDN :BOOL := FALSE; // Êîìàíäà çàêðûòü â ðó÷íîì ðåæèìå.
GAIN :REAL := 2.0 ; // Ïðîïîðöèîíàëüíîå óñèëåíèå îøèáêè ðåãóëèðîâàíèÿ.
TI :REAL := 20.0 ; // Âðåìÿ èíòåãðèðîâàíèÿ [ñ].
DEADB_W :REAL := 0.5 ; // Çîíà íå÷óâñòâèòåëüíîñòè ê îøèáêå ðåãóëèðîâàíèÿ [%].
PULSE_TM :REAL := 1.0 ; // Ìèíèìàëüíîå âðåìÿ âûõîäíîãî èìïóëüñà [ñ].
BREAK_TM :REAL := 1.0 ; // Ìèíèìàëüíî âðåìÿ ìåæäó âûõîäíûìè èìïóëüñàìè [ñ].
MTR_TM :REAL := 55.0 ; // Âðåìÿ îòêðûòèÿ èñïîëíèòåëüíîãî ìåõàíèçìà ñ 0 äî 100 [ñ].
DISV :REAL := 0.0 ; // Âîçìóùàþùåå âîçäåéñòâèå ê îøèáêå ðåãóëèðîâàíèÿ [%].
CYCLE :REAL := 0.1 ; // Øàã äèñêðåòèçàöèè ïî âðåìåíè [ñ].
END_VAR
VAR_OUTPUT
QLMNUP :BOOL := FALSE; // Îòêðûòü çàäâèæêó.
QLMNDN :BOOL := FALSE; // Çàêðûòü çàäâèæêó.
END_VAR
VAR
ER :REAL := 0.0 ; // Îøèáêà ðåãóëèðîâàíèÿ [%].
LMNRS_ON :BOOL := FALSE; //
LMNRSVAL :REAL := 0.0 ; //
LMNR_SIM :REAL := 0.0 ; //
sFbPVal :REAL := 0.0 ; // Ìåíÿåòñÿ âî âðåìÿ ðåãóëèðîâàíèÿ.
sThrOn :REAL := 0.0 ; // Èíîãäà ìåíÿåòñÿ âî âðåìÿ ðåãóëèðîâàíèÿ (ïîõîæå íà àäàïòèâíûé ãèñòåðåçèñ).
siImpAus :INT := 0 ; // -100...0...+100
stImpDauer :REAL := 0.0 ; //
stPausDauer :REAL := 0.0 ; //
END_VAR
VAR_TEMP
Hvar :REAL ; // Âñïîìîãàòåëüíàÿ ïåðåìåííàÿ.
ErKp :REAL ; // Âñïîìîãàòåëüíàÿ ïåðåìåííàÿ.
rTi :REAL ; // Âðåìÿ èíòåãðèðîâàíèÿ â real !!! íå óäàëÿòü !!!
AdapIn1 :REAL ; // Eingang 1 der Adaption der Ansprechschwelle.
AdapIn2 :REAL ; // Eingang 2 der Adaption der Ansprechschwelle.
iImpEin :INT ; // Eingang des Impulsformers.
rThrOff :REAL ; // Abschaltschwelle.
dInteg :REAL ; // Eingang des Integrierers in der Rückführung.
dThrStIn :REAL ; // Three - step element input.
LmnrSim :REAL ; // Simulierte Stellungsrückmeldung.
END_VAR
BEGIN
// ÏÈÄ-ðåãóëÿòîð ñ äâóìÿ äèñêðåòíûìè âûõîäàìè.
// DbPIDstep
// +-------------------------+
// | FbPIDstep |
// ->-|PV QLMNUP|->-
// -|SP QLMNDN|->-
// -|COM_RST |
// -|LMNR_HS |
// -|LMNR_LS |
// -|LMNS_ON |
// -|LMNUP |
// -|LMNDN |
// -|GAIN |
// -|TI |
// -|DEADB_W |
// -|PULSE_TM |
// -|BREAK_TM |
// -|MTR_TM |
// -|DISV |
// -|CYCLE |
// +-------------------------+
IF COM_RST
THEN
LMNR_SIM := LMNRSVAL;
QLMNUP := 0 ;
QLMNDN := 0 ;
PV := 0.0 ;
ER := 0.0 ;
LMNRS_ON := 0 ;
LMNRSVAL := 0.0 ;
LMNR_SIM := 0.0 ;
sFbPVal := 0.0 ;
sThrOn := 0.0 ;
siImpAus := 0 ;
stImpDauer := 0.0 ;
stPausDauer := 0.0 ;
ELSE
ErKp := SP - PV;
IF ErKp < ( -DEADB_W) THEN ER := ErKp + DEADB_W;
ELSIF ErKp > DEADB_W THEN ER := ErKp - DEADB_W;
ELSE ER := 0.0; END_IF;
ErKp := ER * GAIN;
rTi := TI;
IF rTi < CYCLE * 0.5 THEN rTi := CYCLE * 0.5; END_IF;
Hvar := rTi - ABS(0.01 * ErKp * MTR_TM);
IF Hvar < (rTi * 0.1)THEN rTi := rTi * 0.1; ELSE rTi := Hvar; END_IF;
IF LMNS_ON
THEN
sFbPVal := 0.0;
ELSE
IF siImpAus <> 0
THEN
dInteg := DINT_TO_REAL(INT_TO_DINT(siImpAus)) * CYCLE / MTR_TM;
ELSE
IF (ErKp > 0.0 AND LMNR_HS) OR (ErKp < 0.0 AND LMNR_LS) OR (TI = 0.0)
THEN
dInteg := 0.0;
ELSE
dInteg := (-ErKp) * CYCLE / rTi;
END_IF;
END_IF;
sFbPVal := sFbPVal + dInteg;
IF TI = 0.0
THEN
IF sFbPVal > 100.0 THEN sFbPVal := 100.0;
ELSIF sFbPVal < 0.0 THEN sFbPVal := 0.0;
END_IF;
END_IF;
END_IF;
dThrStIn := ErKp - sFbPVal + DISV;
AdapIn1 := ErKp;
AdapIn2 := sFbPVal;
rThrOff := 55.0 / MTR_TM * CYCLE;
IF PULSE_TM > CYCLE
THEN
Hvar := PULSE_TM;
ELSE
Hvar := CYCLE;
END_IF;
Hvar := 100.0 * Hvar / MTR_TM;
IF NOT(LMNR_HS OR LMNR_LS)
THEN
IF NOT (QLMNUP OR QLMNDN)
THEN
IF TI <> 0.0
THEN
IF ABS(AdapIn1) < ABS(AdapIn2)
THEN
sThrOn := AdapIn1;
ELSE
sThrOn := AdapIn2;
END_IF;
ELSE
IF PV = 0.0
THEN
sThrOn := Hvar;
ELSE
sThrOn := ABS(ErKp) * 0.5;
END_IF;
END_IF;
IF sThrOn > 10.0 THEN sThrOn := 10.0; END_IF;
IF sThrOn < Hvar THEN sThrOn := Hvar; END_IF;
END_IF;
ELSE
sThrOn := Hvar;
END_IF;
IF (siImpAus = 100 AND dThrStIn > rThrOff) OR (dThrStIn >= sThrOn) THEN iImpEin := 100;
ELSIF (siImpAus = -100 AND dThrStIn < ( -rThrOff)) OR (dThrStIn <= ( -sThrOn)) THEN iImpEin := -100;
ELSE iImpEin := 0;
END_IF;
IF LMNS_ON
THEN
IF LMNUP XOR LMNDN
THEN
IF LMNUP
THEN
iImpEin := 100;
ELSE
iImpEin := -100;
END_IF;
ELSE
iImpEin := 0;
END_IF;
END_IF;
IF (iImpEin = 100 AND LMNR_HS) OR (iImpEin = -100 AND LMNR_LS) THEN iImpEin := 0; END_IF;
IF (siImpAus = -100 AND iImpEin = 100) OR (siImpAus = 100 AND iImpEin = -100)THEN iImpEin := 0; END_IF;
IF siImpAus <> iImpEin
THEN
IF iImpEin = 0
THEN
IF stImpDauer <= 0.0
THEN
siImpAus := 0;
stPausDauer := BREAK_TM;
END_IF;
ELSE
siImpAus := iImpEin;
stImpDauer := PULSE_TM;
END_IF;
END_IF;
IF stImpDauer > 0.0
THEN
stImpDauer := stImpDauer - CYCLE;
ELSE
stImpDauer := 0.0;
END_IF;
IF stPausDauer > 0.0
THEN
stPausDauer := stPausDauer - CYCLE;
ELSE
stPausDauer := 0.0;
END_IF;
IF ((siImpAus = 100) AND LMNR_HS) OR ((siImpAus = -100) AND LMNR_LS)
THEN
siImpAus := 0;
stImpDauer := 0.0;
END_IF;
IF NOT LMNRS_ON
THEN
LmnrSim := LMNRSVAL;
ELSE
LmnrSim := DINT_TO_REAL(INT_TO_DINT(siImpAus)) * CYCLE / MTR_TM + LMNR_SIM;
IF LmnrSim >= 100.0
THEN
LmnrSim := 100.0;
ELSIF LmnrSim <= 0.0
THEN
LmnrSim := 0.0;
END_IF;
END_IF;
LMNR_SIM := LmnrSim;
IF siImpAus = 0
THEN
QLMNUP := 0;
QLMNDN := 0;
ELSIF siImpAus = 100
THEN
QLMNUP := 1;
QLMNDN := 0;
ELSE
QLMNUP := 0;
QLMNDN := 1;
END_IF;
END_IF;
// src CONT_S FB42
// reversed by komatic
// cross platforms by VA
// https://web.archive.org/web/20220322202418/http://plc4good.org.ua/view_post.php?id=65
// https://github.com/komatic1/SCL_regulation_control/blob/main/CONT_S.scl
(*
Äîáàâëåí: 1exan Äàòà: 2020-04-26
 ýòîì ìåñòå åñòü îòëè÷èÿ îò TCONT è òàì ïîõîæå ðåàëèçàöèÿ áîëåå ïðàâèëüíàÿ:
Çäåñü:
IF iImpEin=0
THEN
IF stImpDauer<=T#0MS
THEN
siImpAus:=0;
stPausDauer:=BREAK_TM;
END_IF;
ELSE
siImpAus:=iImpEin;
stImpDauer:=PULSE_TM;
END_IF;
 TCONT:
IF iImpEin = 0 THEN
IF stImpDauer <= 0.0 THEN
siImpAus := 0 ; stPausDauer := BREAK_TM ;
END_IF ;
ELSIF stPausDauer <= 0.0 THEN
siImpAus := iImpEin ; stImpDauer := PULSE_TM ; END_IF ;
Äîáàâëåí: 1exan Äàòà: 2020-04-26
Êîíêðåòíî âîò ýòà ñòðîêà:
ELSIF stPausDauer <= 0.0 (èëè T#0s) THEN
äîëæíà áûòü âìåñòî ïðîñòîãî
ELSE
Äîáàâëåí: Roman Äàòà: 2021-12-02
Ïðàâèëüíûå ñòðîêè:
sThrOn:=ABS(AdapIn1);
sThrOn:=ABS(AdapIn2);
IF iImpEin=0
THEN
IF stImpDauer<=T#0MS
THEN
siImpAus:=0;
stPausDauer:=BREAK_TM;
END_IF;
ELSE IF stPausDauer<=T#0MS
THEN
siImpAus:=iImpEin;
stImpDauer:=PULSE_TM;
END_IF; END_IF;
*)
// @COPYLEFT ALL WRONGS RESERVED :)
// Author: VA
// Contacts: DIY.PLC.314@gmail.com
// Date start LIB_PLC: 2014
// License: GNU GPL-2.0-or-later
// https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
// https://www.youtube.com/watch?v=n1F_MfLRlX0
// https://www.youtube.com/@DIY_PLC
// https://github.com/DIYPLC/LIB_PLC
// https://oshwlab.com/diy.plc.314/PLC_HW1_SW1
// https://3dtoday.ru/3d-models/mechanical-parts/body/korpus-na-din-reiku
// https://t.me/DIY_PLC
// https://drive.google.com/drive/folders/16GDX0i07rwDrl_oPzL-lQAqMiAz3ouJV?usp=sharing
END_FUNCTION_BLOCK