Partie du forum pour tout ce qui concerne la partie régulation dans l'industrie. Forum, conseil, astuce et entraide sur les calculs de régulateurs, les différents choix de P, PI ou PID, leur utilisation et la résolution de problèmes..
Le code SCL pour Step7 V5.5 si tu veux intégrer dans le TIA il y a quelques modifs à prévoir (voir les anciens post)
====================================================================================================
Le FB de mesure de fréquence
====================================================================================================
FUNCTION_BLOCK FREQ_MEASURE
TITLE = 'FREQ_MEASURE'
//
//Adaptation du FB FREQ_MEASURE de la lib Util de 3S.
//La mesure ne doit pas dépasser 24D20H31M23S647MS car le débordement de l'horloge système n'est pas testé.
//
VERSION : '1.0'
AUTHOR : Cyril93
NAME : FREQ_MEA
FAMILY : MESURE
//KNOW_HOW_PROTECT
VAR_INPUT
IN: BOOL; (* input signal *)
PERIODS: INT :=1; (* out is the average frequency during PERIODS (number of periods) between 1 to 10 *)
RESET: BOOL; (* reset measurement *)
END_VAR
VAR_OUTPUT
OUT: REAL; (* frequency [Hz]*)
VALID: BOOL; (* FALSE: not yet PERIODS measurements done OR time distance between two rising edges > 3*OUT *)
END_VAR
VAR
OLDIN: BOOL;
INIT: BOOL;
OLDT: TIME;
DIFF: DINT;
ADIFF: ARRAY[0..9] OF DINT;
V: INT;
B:INT;
I: INT;
END_VAR
BEGIN
IF RESET THEN
B:=0;
V:=0;
INIT:=FALSE;
VALID:=FALSE;
OUT:=0;
RETURN;
END_IF;
IF IN AND NOT OLDIN THEN (*rising edge *)
IF INIT THEN
DIFF := TIME_TO_DINT(TIME_TCK()-OLDT);
IF Diff > 0 THEN
ADIFF[B] := DIFF;
B := (B+1) MOD PERIODS;
V:=MIN(IN1:=V+1, IN2:=PERIODS);
IF V=PERIODS THEN
OUT := 0;
FOR I:=0 TO PERIODS-1 DO
OUT := OUT + ADIFF[I];
END_FOR;
OUT := 1000.0 * PERIODS / OUT;
VALID:=TRUE;
ELSE
VALID:=FALSE;
END_IF;
END_IF;
END_IF;
INIT := TRUE;
OLDT := TIME_TCK();
ELSIF INIT AND VALID AND TIME_TO_DINT(TIME_TCK()-OLDT) > 3000*OUT THEN
VALID:=FALSE;
V:=0;
B:=0;
END_IF;
OLDIN:=IN;
END_FUNCTION_BLOCK
====================================================================================================
Le FB de la méthode du relais (c'est ce bloc qu'il faut appelé dans le programme)
====================================================================================================
FUNCTION_BLOCK CALC_PID
TITLE = 'CALC_PID'
//
//Auto-réglage des constantes PID par la méthode du relais de Astrom-Hagglund.
//
VERSION : '1.1'
AUTHOR : Cyril93
NAME : CALC_PID
FAMILY : REGUL
//KNOW_HOW_PROTECT
VAR_INPUT
bEN : BOOL; (* Démarre la séquence par le front montant *)
rSP : REAL; (* Point de consigne *)
rPV: REAL; (* Mesure process *)
iCY: INT:=2; (* Nombre de cycle du réglage automatique (minimum 2)*)
bRST: BOOL; (* Remise à zéro *)
rL_VAL: REAL; (* Valeur basse pour la sortie *)
rH_VAL: REAL; (* Valeur haute pour la sortie *)
iPERF: INT; (* Performances des constantes PID : 0=rapides, 1=normales, 2=lentes *)
END_VAR
VAR_OUTPUT
bEND: BOOL; (* Fin séquence *)
rSQ_VAL: REAL; (* Sortie onde carrée pour l'exitation du process *)
rKP: REAL; (* Gain proportionnel *)
rTN: REAL; (* Temps d'intégrale en s *)
rTV: REAL; (* Temps de dérivée en s *)
END_VAR
VAR
PU: REAL; (* Gain ultime *)
TU: REAL; (* Période ultime *)
b: REAL; (* Amplitude de PV *)
a: REAL; (* Amplitude de SQ_VAL *)
Tu_Freq: FREQ_MEASURE;
b_Min: REAL;
b_Max: REAL;
EdgeEnd: BOOL;
FlagEnd: BOOL;
End: BOOL;
status: INT;
cpt: INT;
old_bEN: BOOL;
RstFreq: BOOL;
PerFreq: INT;
END_VAR
CONST
PI := REAL#3.14159265358979323846264338327950288;
END_CONST
BEGIN
(*** Séquence autotune ***)
IF bRST THEN
status:=0;
END_IF;
CASE status OF
0: (* Attente Démarrage autotune *)
rSQ_VAL:=rL_VAL;
IF bEN AND NOT old_bEN THEN
RstFreq:=TRUE;
b_Min:=3.402823E+38 ;
b_Max:=-3.402823E+38 ;
rKP:=0;
rTN:=0;
rTV:=0;
cpt:=0;
bEND:=FALSE;
status:=1;
End:=FALSE;
END_IF;
1: (* Onde carrée haute *)
rSQ_VAL:=rH_VAL;
IF rPV > rSP THEN
rSQ_VAL:=rL_VAL;
cpt:=cpt+1;
status:=2;
END_IF;
2: (* Onde carrée basse et fin de séquence *)
IF rPV < rSP THEN
cpt:=cpt+1;
IF cpt >= iCY THEN
status:=1;
End:=TRUE;
ELSE
status:=1;
END_IF;
END_IF;
END_CASE;
old_bEN:=bEN;
(*** Calcul des paramètres ***)
(* min/max et freq de PV *)
IF rPV<b_Min THEN
b_Min:=rPV;
END_IF;
IF rPV>b_Max THEN
b_Max:=rPV;
END_IF;
(* Nombre de période pour le bloc FREQ_MEASURE *)
PerFreq:=(iCY/2)-1;
PerFreq:=LIMIT(MN:=1, IN:=PerFreq, MX:=10);
Tu_Freq(
IN := rPV > rSP ,
PERIODS :=PerFreq ,
RESET := RstFreq);
RstFreq:=FALSE;
(* Calcul sur front montant de End et valeur de sortie de FREQ_MEASURE ok *)
EdgeEnd:= End AND Tu_Freq.OUT <> 0 AND NOT FlagEnd;
FlagEnd:= End AND Tu_Freq.OUT <> 0;
IF EdgeEnd THEN
(* amp de SQ_VAL *)
a:=rH_VAL-rL_VAL;
(* amp de PV *)
b:=b_Max-b_Min;
(* Gain et période ultime *)
PU:=(4 * b)/(PI * a);
TU:=1/Tu_Freq.OUT;
(* Valeur PID *)
CASE iPERF OF
0:(* Performances rapides *)
rKP:= 0.6 * PU;
rTN:= 0.5 * TU;
rTV:= 0.125 * TU;
1:(* Performances normales *)
rKP:= 0.25 * PU;
rTN:= 0.5 * TU;
rTV:= 0.125 * TU;
2:(* Performances lentes *)
rKP:= 0.15 * PU;
rTN:= 0.5 * TU;
rTV:= 0.125 * TU;
END_CASE;
bEND:=TRUE;
status:=0;
END_IF;
END_FUNCTION_BLOCK