FUNCTION_BLOCK FB_ZylinderSteuerung
VAR_INPUT
bStart : BOOL;
bReset : BOOL;
fDruck : REAL;
END_VAR
VAR_OUTPUT
bVorfahren : BOOL;
bZurueck : BOOL;
bFehler : BOOL;
END_VAR
VAR
nSchritt : INT := 0;
tVerzögerung : TON;
END_VAR
NETWORK 1
TITEL: Bandsteuerung
A "Start_Taster"
AN "Not_Aus"
A "LS_Eingang_OK"
= "Motor_Ein"
NETWORK 2
TITEL: Fehlererkennung
L "Temp_Motor"
L 85.0
>R
= "Temp_Warnung"
NOP 0
(* PID-Regler Berechnung *)
fFehler := fSollwert - fIstwert;
fIntegral := fIntegral
+ fFehler * fAbtastzeit;
fAbleitung := (fFehler - fFehlerAlt)
/ fAbtastzeit;
fStellgröße := fKp * fFehler
+ fKi * fIntegral
+ fKd * fAbleitung;
fFehlerAlt := fFehler; ┌─────────┐
I0.0 ───┤ │
│ AND ├──── Q0.0
I0.1 ───┤ │
└─────────┘
│
┌────┴────┐
│ TON ├──── Q_Timer
PT ──┤ T#5s │
└─────────┘FOR i := 0 TO nPufferGröße - 1 DO
aPuffer[i MOD nPufferGröße]
:= fNeuerWert;
fSumme := fSumme + aPuffer[i];
END_FOR;
fMittelwert := fSumme
/ INT_TO_REAL(nPufferGröße);CASE nSchritt OF
0: (* Initialisierung *)
bVorfahren := FALSE;
bZurueck := FALSE;
IF bStart THEN
nSchritt := 10;
END_IF;
10: (* Vorfahren *)
bVorfahren := TRUE;
tVerzög(IN:=TRUE, PT:=T#2S);
IF tVerzög.Q THEN
tVerzög(IN:=FALSE);
nSchritt := 20;
END_IF;
20: (* Endlage prüfen *)
IF fDruck > 150.0 THEN
nSchritt := 30;
ELSIF fDruck < 10.0 THEN
bFehler := TRUE;
nSchritt := 99;
END_IF;
END_CASE;(* Analogwert skalieren *)
L PIW 256
ITD
DTR
L 3.2764e+1
*R
L -1.0e+1
+R
T MD 40
L MD 40
L 1.0e+2
>R
JCN OK
L 1.0e+2
T MD 40
OK: NOP 0
(* Skalierung Analogeingang *)
fRohwert := INT_TO_REAL(nADC);
fSkaliert := (fRohwert - 4096.0)
/ (32767.0 - 4096.0)
* (fMaxWert - fMinWert)
+ fMinWert;
IF fSkaliert > fMaxWert THEN
fSkaliert := fMaxWert;
bUeberlauf := TRUE;
ELSIF fSkaliert < fMinWert THEN
fSkaliert := fMinWert;
END_IF; ┌──────────┐
M0.1 ───┤ IN │
│ TOF ├──── bFreigabe
PT ──┤ T#500ms │
└──────────┘
┌──────────┐
I0.2 ───┤ S │
│ SR ├──── Q_Merker
I0.3 ───┤ R1 │
└──────────┘(* Servoachse Positionierung *)
IF bEnable AND NOT bFehler THEN
fbAchse(
Enable := bEnable,
Execute := bStart,
Position := fZielPosition,
Velocity := fGeschwindigkeit,
Acceleration := fBeschleunigung
);
IF fbAchse.Done THEN
bPositionErreicht := TRUE;
nSchritt := nSchritt + 10;
ELSIF fbAchse.Error THEN
nFehlerCode := fbAchse.ErrorID;
bFehler := TRUE;
END_IF;
END_IF;NETWORK 5
TITEL: Drucküberwachung
L MW 100 // Ist-Druck
L MW 102 // Schwelle_Hi
>I
S M 10.0 // Druck_Hoch
L MW 100
L MW 104 // Schwelle_Lo
<I
R M 10.0
A M 10.0
= Q 1.3 // Ventil_Auf
TYPE ST_Achsparameter :
STRUCT
fMaxGeschwindigkeit : REAL := 100.0;
fMaxBeschleunigung : REAL := 500.0;
fSoftwareEndschalter_Pos : REAL;
fSoftwareEndschalter_Neg : REAL;
bReferenziert : BOOL;
nAchsNummer : INT;
END_STRUCT
END_TYPE
┌──────────┐ ┌──────────┐
I0.0 ───┤ │ │ │
│ AND ├───┤ SR ├── Q1.0
I0.1 ───┤ │ │ │
└──────────┘ │ │
│ │
I0.4 ──────────────────┤ R1 │
└──────────┘WHILE nVersuch < nMaxVersuche DO
fbKomm.Execute := TRUE;
IF fbKomm.Done THEN
bVerbunden := TRUE;
EXIT;
ELSIF fbKomm.Error THEN
nVersuch := nVersuch + 1;
fbKomm.Execute := FALSE;
END_IF;
END_WHILE;(* OPC-UA Datenpunkt schreiben *)
fbOpcWrite(
Execute := bSchreiben,
NodeID := sNodeID,
Value := fAktuelleDruck,
TimeStamp := dtZeitstempel
);
IF fbOpcWrite.Done THEN
bSchreiben := FALSE;
nZyklusZeit := nZyklusZeit + 1;
ELSIF fbOpcWrite.Error THEN
nOpcFehler := fbOpcWrite.ErrorID;
END_IF;
(* Schrittkette Spritzguss *)
L #nSchritt
L 10
==I
JCN S020
S010:
A #bFormZu
AN #bStörer
= #bEinspritzen
A #bEnddruckOK
S #xSchritt20
R #xSchritt10
JU ENDE
S020:
A #bNachdruck
L #tNachdruck
SD T5
ENDE: NOP 0
(* Energiemonitoring *)
fLeistung := fSpannung * fStrom
* fLeistungsfaktor;
fEnergie := fEnergie
+ fLeistung * fZykluszeit
/ 3600000.0; // Wh
IF fEnergie > fEnergieLimit THEN
bEnergieAlarm := TRUE;
fbAlarm(
ID := 16#0A01,
State := TRUE
);
END_IF; ┌──────────┐
MW10 ───┤ │
│ ADD ├──── MW14
MW12 ───┤ │
└──────────┘
┌──────────┐
MW14 ───┤ IN │
│ LIMIT ├──── MW16
MN ───┤ 0 │
MX ───┤ 1000 │
└──────────┘IF bNotaus OR bTüroffen THEN
bSicherheitskreis := FALSE;
fbAntrieb.Enable := FALSE;
fbBremse.Set := TRUE;
ELSIF bReset AND
bBereitschaft THEN
bSicherheitskreis := TRUE;
END_IF;VAR_GLOBAL
gfSollDruck : REAL;
gfIstDruck : REAL;
gnBetriebsMode : INT;
gbAnlageAktiv : BOOL;
gatAchsen : ARRAY[1..6]
OF ST_Achsparameter;
gfZykluszeit : REAL;
gdtLetzterStart : DATE_AND_TIME;
END_VARNETWORK 8
TITEL: Hydraulik Druckregelung
CALL FB_Regler, DB_Regler (
fSollwert := MD 60,
fIstwert := MD 64,
fKp := 1.5,
fKi := 0.3,
fKd := 0.05,
fStellgröße => MD 68
)
L MD 68
T PAW 256(* Rezeptverwaltung *)
CASE nRezeptNummer OF
1: fTemperatur := 180.0;
fDruck := 120.0;
tZykluszeit := T#45S;
2: fTemperatur := 200.0;
fDruck := 145.0;
tZykluszeit := T#38S;
3: fTemperatur := 165.0;
fDruck := 105.0;
tZykluszeit := T#52S;
ELSE
bRezeptFehler := TRUE;
END_CASE; ┌──────────┐
MD40 ───┤ IN │
│ CTU ├──── bZählerVoll
R ───┤ │
PV ────┤ 500 ├──── nZählerWert
└──────────┘(* Modbus TCP Kommunikation *)
fbModbus(
Execute := TRUE,
UnitID := 1,
FuncCode := 16#03,
Quantity := 10,
pData := ADR(aRegister),
IPAddress := '192.168.0.10',
Port := 502
);