Commit 95e99d16 authored by Claes Sjofors's avatar Claes Sjofors

Plc control, new algorithm for PID and CompPID, and windup limit in Inc3P-object (refs #177)

parent 16ed5c5d
...@@ -240,6 +240,11 @@ void CompPID_Fo_init( pwr_sClass_CompPID_Fo *o) ...@@ -240,6 +240,11 @@ void CompPID_Fo_init( pwr_sClass_CompPID_Fo *o)
#define DALG 8 /* Derivative part exists */ #define DALG 8 /* Derivative part exists */
#define DAVV 16 /* Derivative part working on control difference */ #define DAVV 16 /* Derivative part working on control difference */
#define IWUP 1 /* Windup limitation on I part */
#define BIWUP 2 /* Windup limitation on Bias and I part */
#define BPIWUP 4 /* Windup limitation on Bias PI part */
#define BPIDWUP 8 /* Windup limitation on Bias and PID part (Default, old funcionality */
void CompPID_Fo_exec( plc_sThread *tp, void CompPID_Fo_exec( plc_sThread *tp,
pwr_sClass_CompPID_Fo *o) pwr_sClass_CompPID_Fo *o)
{ {
...@@ -252,6 +257,9 @@ void CompPID_Fo_exec( plc_sThread *tp, ...@@ -252,6 +257,9 @@ void CompPID_Fo_exec( plc_sThread *tp,
float ut; float ut;
float dut; float dut;
float kd; float kd;
float absut;
float gain;
pwr_sClass_CompPID *co = (pwr_sClass_CompPID *) o->PlcConnectP; pwr_sClass_CompPID *co = (pwr_sClass_CompPID *) o->PlcConnectP;
if ( !co) if ( !co)
...@@ -284,104 +292,120 @@ void CompPID_Fo_exec( plc_sThread *tp, ...@@ -284,104 +292,120 @@ void CompPID_Fo_exec( plc_sThread *tp,
ddiff = ((co->PidAlg & DAVV) != 0) ? ddiff = ((co->PidAlg & DAVV) != 0) ?
(co->ControlDiff - eold) / *o->ScanTime: (co->ControlDiff - eold) / *o->ScanTime:
(co->ProcVal - xold) / *o->ScanTime; (co->ProcVal - xold) / *o->ScanTime;
if ((co->DerGain <= 0.0) || (co->DerTime <= 0)) if (((co->DerGain * *o->ScanTime) >= co->DerTime) || (co->DerTime <= 0))
co->FiltDer = ddiff; /* No Filter */ co->FiltDer = ddiff; /* No Filter */
else { else {
kd = 1.0 / (1.0 + co->DerGain * *o->ScanTime / co->DerTime); kd = 1.0 / (1.0 + co->DerGain * *o->ScanTime / co->DerTime);
co->FiltDer += (ddiff - derold) * (1.0 - kd); co->FiltDer += (ddiff - derold) * (1.0 - kd);
} }
if (co->Inverse == 0) gain = co->Gain;
else gain = -co->Gain;
if ( co->Force ) { if ( co->Force ) {
/* Force */ /* Force */
dut = co->OutVal; co->OutChange = co->ForcVal - co->OutVal;
co->OutVal = co->ForcVal; co->OutVal = co->OutWindup = co->ForcVal;
co->OutChange = co->OutVal - dut;
co->EndMin = FALSE; co->EndMin = FALSE;
co->EndMax = FALSE; co->EndMax = FALSE;
/* Adjust for bumpless transfer to auto */
co->PDManOffset = co->OutVal -
gain * co->ControlDiff - co->BiasGain * co->Bias;
if ((co->PidAlg & IALG) != 0) co->AbsOut = 0.0;
else co->AbsOut = co->OutVal;
if (co->WindupMask < BIWUP)
co->OutWindup -= co->BiasGain * co->Bias;
if (co->WindupMask < BPIWUP)
co->OutWindup -= gain * co->ControlDiff;
co->AbsOut = co->OutVal - co->OutWindup;
} }
else { else {
/* Auto mode */ /* Auto mode */
if ((co->PidAlg & IALG) != 0) {
/* Incremental algorithm */ dut = absut = 0.0;
if ((co->PidAlg & IALG) != 0)
/* Incremental algorithm */
{
/* Integral-part */ /* Integral-part */
if ((*o->IntOffP == FALSE) && (co->IntTime > 0)) if ((*o->IntOffP == FALSE) && (co->IntTime > 0))
dut = co->ControlDiff * *o->ScanTime / co->IntTime; dut = co->ControlDiff * *o->ScanTime / co->IntTime;
if ((co->PidAlg & PALG) != 0) dut *= gain;
else gain = 0.0; /* Pure I-controller */
/* Bias */
if (co->WindupMask >= BIWUP) /* Windup on Bias */
dut += co->BiasGain * (co->Bias - bfold);
else absut = co->BiasGain * co->Bias;
/* P-part */
if (co->WindupMask >= BPIWUP) /* Windup on P */
dut += ((co->PidAlg & PAVV) != 0) ?
gain * (co->ControlDiff - eold) :
gain * (co->ProcVal - xold) ;
else else
dut = 0; absut += gain * co->ControlDiff;
if ((co->PidAlg & PALG) != 0) {
/* Not pure I-controller */ /* Derivative-part */
/* Derivative-part */ if ((co->PidAlg & DALG) != 0) {
if ((co->PidAlg & DALG) != 0) if (co->WindupMask >= BPIDWUP) /* Windup on D */
dut += (co->FiltDer-derold) * co->DerTime; dut += gain * (co->FiltDer - derold) * co->DerTime;
/* P-part */ else
dut += ((co->PidAlg & PAVV) != 0) ? absut += gain * co->FiltDer * co->DerTime;
co->ControlDiff - eold :
co->ProcVal - xold ;
dut *= co->Gain;
} }
if (co->Inverse != 0) dut = - dut;
/* Bias */
dut += co->BiasGain * (co->Bias - bfold);
/* Limit output */ /* Limit output */
ut = co->OutVal + dut; co->OutWindup += dut;
if (co->MaxOut > co->MinOut) {
if (ut > co->MaxOut) { if (co->OutWindup > co->MaxWindup) {
ut = co->MaxOut; co->OutWindup = co->MaxWindup;
co->EndMin = FALSE; co->EndMax = TRUE;
co->EndMax = TRUE; } else if (co->OutWindup < co->MinWindup) {
} co->OutWindup = co->MinWindup;
else if (ut < co->MinOut) { co->EndMin = TRUE;
ut = co->MinOut;
co->EndMin = TRUE;
co->EndMax = FALSE;
}
else {
if (co->EndMin && (ut >= (co->MinOut + co->EndHys)))
co->EndMin = FALSE;
if (co->EndMax && (ut <= (co->MaxOut - co->EndHys)))
co->EndMax = FALSE;
}
} }
ut = co->OutWindup + absut;
if (ut > co->MaxOut) ut = co->MaxOut;
else if (ut < co->MinOut) ut = co->MinOut;
dut += absut - co->AbsOut;
} }
else { else
/* Nonincremental algorithm */ /* Nonincremental algorithm */
{
/* P-part */ /* P-part */
ut = co->ControlDiff; ut = co->ControlDiff;
/* Derivative-part */ /* Derivative-part */
if ((co->PidAlg & DALG) != 0) if ((co->PidAlg & DALG) != 0)
ut += co->FiltDer * co->DerTime; ut += co->FiltDer * co->DerTime;
/* Gain */ /* Gain */
ut *= co->Gain; ut *= gain;
if (co->Inverse != 0) ut = - ut;
/* Bias */ /* Bias and Man offset*/
ut += co->BiasGain * co->Bias; if (co->PDAbsFlag) co->PDManOffset = 0;
ut += co->BiasGain * co->Bias + co->PDManOffset;
/* Limit output */ /* Limit output */
if (co->MaxOut > co->MinOut) { if (co->MaxOut > co->MinOut)
if (ut > co->MaxOut) { {
ut = co->MaxOut; if (ut > co->MaxOut) ut = co->MaxOut;
co->EndMin = FALSE; else if (ut < co->MinOut) ut = co->MinOut;
co->EndMax = TRUE;
}
else if (ut < co->MinOut) {
ut = co->MinOut;
co->EndMin = TRUE;
co->EndMax = FALSE;
}
else {
if (co->EndMin && (ut >= (co->MinOut + co->EndHys)))
co->EndMin = FALSE;
if (co->EndMax && (ut <= (co->MaxOut - co->EndHys)))
co->EndMax = FALSE;
}
} }
dut = ut - co->OutVal; dut = ut - co->OutVal;
absut = ut;
} }
/* Output Auto */ /* Output Auto */
co->OutChange = dut; co->OutChange = dut;
co->OutVal = ut; co->OutVal = ut;
co->AbsOut = absut;
} }
/* Transfer outputs */ /* Transfer outputs */
......
This diff is collapsed.
...@@ -44,7 +44,6 @@ ...@@ -44,7 +44,6 @@
#include "pwr_baseclasses.h" #include "pwr_baseclasses.h"
#include "rt_plc.h" #include "rt_plc.h"
#include "rt_plc_timer.h" #include "rt_plc_timer.h"
#include "rt_plc_pid.h"
/* PLC RUTINER */ /* PLC RUTINER */
...@@ -53,9 +52,13 @@ ...@@ -53,9 +52,13 @@
function: accumulate output change from controller function: accumulate output change from controller
and convert to Open or Close orders. and convert to Open or Close orders.
2014-02-18 Werner Limit acc to new attribute "MaxWindup"
@aref inc3p Inc3p @aref inc3p Inc3p
*/ */
void inc3p_init( pwr_sClass_inc3p *object)
void inc3p_init(
pwr_sClass_inc3p *object)
{ {
object->Acc = 0; object->Acc = 0;
} }
...@@ -157,6 +160,13 @@ void inc3p_exec( ...@@ -157,6 +160,13 @@ void inc3p_exec(
} }
} }
} }
/* Limit output 2014-02-18 / Werner */
if ((object->Acc > object->MaxWindup) && (object->MaxWindup > 0.0))
object->Acc = object->MaxWindup;
if ((object->Acc < -object->MaxWindup) && (object->MaxWindup > 0.0))
object->Acc = -object->MaxWindup;
} }
/*_* /*_*
...@@ -355,15 +365,19 @@ void mode_exec( ...@@ -355,15 +365,19 @@ void mode_exec(
Possible to turn off integration and to force Possible to turn off integration and to force
output to desired value. output to desired value.
Revision: 2011-01-18 / Werner New Attributes 2014-02-18 / Werner:
Error in filtered derivate part corrected. WindupMask Config
MinWindup Config
MaxWindup Config
PDManOffset Internal
OutWindup Internal
@aref pid Pid @aref pid Pid
*/ */
void pid_exec( void pid_exec(
plc_sThread *tp, plc_sThread *tp,
pwr_sClass_pid *object) pwr_sClass_pid *object)
{ {
/* Define Algoritm bitmask */ /* Define Algoritm bitmask */
...@@ -373,6 +387,11 @@ void pid_exec( ...@@ -373,6 +387,11 @@ void pid_exec(
#define DALG 8 /* Derivative part exists */ #define DALG 8 /* Derivative part exists */
#define DAVV 16 /* Derivative part working on control difference */ #define DAVV 16 /* Derivative part working on control difference */
#define IWUP 1 /* Windup limitation on I part */
#define BIWUP 2 /* Windup limitation on Bias and I part */
#define BPIWUP 4 /* Windup limitation on Bias PI part */
#define BPIDWUP 8 /* Windup limitation on Bias and PID part (Default, old funcionality */
float xold; /* Local variables */ float xold; /* Local variables */
float eold; float eold;
float bfold; float bfold;
...@@ -381,6 +400,8 @@ void pid_exec( ...@@ -381,6 +400,8 @@ void pid_exec(
float ut; float ut;
float dut; float dut;
float kd; float kd;
float absut;
float gain;
/* Save old values */ /* Save old values */
xold=object->ProcVal; xold=object->ProcVal;
...@@ -402,73 +423,93 @@ object->ControlDiff = object->ProcVal - object->SetVal; ...@@ -402,73 +423,93 @@ object->ControlDiff = object->ProcVal - object->SetVal;
ddiff = ((object->PidAlg & DAVV) != 0) ? ddiff = ((object->PidAlg & DAVV) != 0) ?
(object->ControlDiff - eold) / *object->ScanTime: (object->ControlDiff - eold) / *object->ScanTime:
(object->ProcVal - xold) / *object->ScanTime; (object->ProcVal - xold) / *object->ScanTime;
if ((object->DerGain <= 0.0) || (object->DerTime <= 0)) if (((object->DerGain * *object->ScanTime) >= object->DerTime) || (object->DerTime <= 0))
object->FiltDer = ddiff; /* No Filter */ object->FiltDer = ddiff; /* No Filter */
else { else {
kd = 1.0 / (1.0 + object->DerGain * *object->ScanTime / object->DerTime); kd = 1.0 / (1.0 + object->DerGain * *object->ScanTime / object->DerTime);
object->FiltDer += (ddiff - derold) * (1.0 - kd); object->FiltDer += (ddiff - derold) * (1.0 - kd);
} }
if (object->Inverse == 0) gain = object->Gain;
else gain = -object->Gain;
if ( object->Force ) if ( object->Force )
/* Force */ /* Force */
{ {
dut = object->OutVal; object->OutChange = object->ForcVal - object->OutVal;
object->OutVal = object->ForcVal; object->OutVal = object->OutWindup = object->ForcVal;
object->OutChange = object->OutVal - dut;
object->EndMin = FALSE; object->EndMin = FALSE;
object->EndMax = FALSE; object->EndMax = FALSE;
/* Adjust for bumpless transfer to auto */
object->PDManOffset = object->OutVal -
gain * object->ControlDiff - object->BiasGain * object->Bias;
if ((object->PidAlg & IALG) != 0) object->AbsOut = 0.0;
else object->AbsOut = object->OutVal;
if (object->WindupMask < BIWUP)
object->OutWindup -= object->BiasGain * object->Bias;
if (object->WindupMask < BPIWUP)
object->OutWindup -= gain * object->ControlDiff;
object->AbsOut = object->OutVal - object->OutWindup;
} }
else else
/* Auto mode */ /* Auto mode */
{ {
dut = absut = 0.0;
if ((object->PidAlg & IALG) != 0) if ((object->PidAlg & IALG) != 0)
/* Incremental algorithm */ /* Incremental algorithm */
{ {
/* Integral-part */ /* Integral-part */
if ((*object->IntOffP == FALSE) && (object->IntTime > 0)) if ((*object->IntOffP == FALSE) && (object->IntTime > 0))
dut = object->ControlDiff * *object->ScanTime / object->IntTime; dut = object->ControlDiff * *object->ScanTime / object->IntTime;
else
dut = 0; if ((object->PidAlg & PALG) != 0) dut *= gain;
if ((object->PidAlg & PALG) != 0) else gain = 0.0; /* Pure I-controller */
/* Not pure I-controller */
{ /* Bias */
/* Derivative-part */ if (object->WindupMask >= BIWUP) /* Windup on Bias */
if ((object->PidAlg & DALG) != 0) dut += object->BiasGain * (object->Bias - bfold);
dut += (object->FiltDer-derold) * object->DerTime; else absut = object->BiasGain * object->Bias;
/* P-part */
/* P-part */
if (object->WindupMask >= BPIWUP) /* Windup on P */
dut += ((object->PidAlg & PAVV) != 0) ? dut += ((object->PidAlg & PAVV) != 0) ?
object->ControlDiff - eold : gain * (object->ControlDiff - eold) :
object->ProcVal - xold ; gain * (object->ProcVal - xold) ;
dut *= object->Gain; else
absut += gain * object->ControlDiff;
/* Derivative-part */
if ((object->PidAlg & DALG) != 0) {
if (object->WindupMask >= BPIDWUP) /* Windup on D */
dut += gain * (object->FiltDer - derold) * object->DerTime;
else
absut += gain * object->FiltDer * object->DerTime;
} }
if (object->Inverse != 0) dut = - dut;
/* Bias */
dut += object->BiasGain * (object->Bias - bfold);
/* Limit output */ /* Limit output */
ut = object->OutVal + dut; object->OutWindup += dut;
if (object->MaxOut > object->MinOut)
{ if (object->OutWindup > object->MaxWindup) {
if (ut > object->MaxOut) object->OutWindup = object->MaxWindup;
{ object->EndMax = TRUE;
ut = object->MaxOut; } else if (object->OutWindup < object->MinWindup) {
object->EndMin = FALSE; object->OutWindup = object->MinWindup;
object->EndMax = TRUE; object->EndMin = TRUE;
}
else if (ut < object->MinOut)
{
ut = object->MinOut;
object->EndMin = TRUE;
object->EndMax = FALSE;
}
else
{
if (object->EndMin && (ut >= (object->MinOut + object->EndHys)))
object->EndMin = FALSE;
if (object->EndMax && (ut <= (object->MaxOut - object->EndHys)))
object->EndMax = FALSE;
}
} }
ut = object->OutWindup + absut;
if (ut > object->MaxOut) ut = object->MaxOut;
else if (ut < object->MinOut) ut = object->MinOut;
dut += absut - object->AbsOut;
} }
else else
...@@ -480,39 +521,27 @@ else ...@@ -480,39 +521,27 @@ else
if ((object->PidAlg & DALG) != 0) if ((object->PidAlg & DALG) != 0)
ut += object->FiltDer * object->DerTime; ut += object->FiltDer * object->DerTime;
/* Gain */ /* Gain */
ut *= object->Gain; ut *= gain;
if (object->Inverse != 0) ut = - ut;
/* Bias */ /* Bias and Man offset */
ut += object->BiasGain * object->Bias; if (object->PDAbsFlag) object->PDManOffset = 0;
ut += object->BiasGain * object->Bias + object->PDManOffset;
/* Limit output */ /* Limit output */
if (object->MaxOut > object->MinOut) if (object->MaxOut > object->MinOut)
{ {
if (ut > object->MaxOut) if (ut > object->MaxOut) ut = object->MaxOut;
{ else if (ut < object->MinOut) ut = object->MinOut;
ut = object->MaxOut;
object->EndMin = FALSE;
object->EndMax = TRUE;
}
else if (ut < object->MinOut)
{
ut = object->MinOut;
object->EndMin = TRUE;
object->EndMax = FALSE;
}
else
{
if (object->EndMin && (ut >= (object->MinOut + object->EndHys)))
object->EndMin = FALSE;
if (object->EndMax && (ut <= (object->MaxOut - object->EndHys)))
object->EndMax = FALSE;
}
} }
dut = ut - object->OutVal; dut = ut - object->OutVal;
absut = ut;
} }
/* Output Auto */ /* Output Auto */
object->OutChange = dut; object->OutChange = dut;
object->OutVal = ut; object->OutVal = ut;
object->AbsOut = absut;
} }
} }
...@@ -52,7 +52,8 @@ SObject pwrb:Class ...@@ -52,7 +52,8 @@ SObject pwrb:Class
! The input signal OutChange is regarded as a control ! The input signal OutChange is regarded as a control
! error. This error is transformed into a time by ! error. This error is transformed into a time by
! multiplication with Gain. The product is added to ! multiplication with Gain. The product is added to
! accumulator Acc. ! accumulator Acc. The absolute value of Acc is limited
! to MaxWindup.
! !
! If the absolute value of Acc > MinTim either the output ! If the absolute value of Acc > MinTim either the output
! Open or Close is set. If Acc > MinTim an incremental ! Open or Close is set. If Acc > MinTim an incremental
...@@ -193,6 +194,18 @@ SObject pwrb:Class ...@@ -193,6 +194,18 @@ SObject pwrb:Class
Attr GraphName = "MaxTim" Attr GraphName = "MaxTim"
EndBody EndBody
EndObject EndObject
!/**
! Maximum windup in seconds
! The absolute value of Acc will never be greater than MaxWindup
! Typically less or equal than running time from open to closed
! Default 30 seconds. Lessor equal to zero means no limitation.
!*/
Object MaxWindup $Intern 19
Body SysBody
Attr TypeRef = "pwrs:Type-$Float32"
Attr GraphName = "MaxWindup"
EndBody
EndObject
Object OpenP $Intern 8 Object OpenP $Intern 8
Body SysBody Body SysBody
Attr Flags |= PWR_MASK_POINTER Attr Flags |= PWR_MASK_POINTER
...@@ -387,6 +400,7 @@ SObject pwrb:Class ...@@ -387,6 +400,7 @@ SObject pwrb:Class
Object Template Inc3P Object Template Inc3P
Body RtBody Body RtBody
Attr Gain = 1.0 Attr Gain = 1.0
Attr MaxWindup = 30.0
EndBody EndBody
EndObject EndObject
EndObject EndObject
......
...@@ -175,8 +175,6 @@ SObject pwrb:Class ...@@ -175,8 +175,6 @@ SObject pwrb:Class
Object SetVal $Output 7 Object SetVal $Output 7
Body SysBody Body SysBody
Attr PgmName = "SetVal" Attr PgmName = "SetVal"
Attr Flags |= PWR_MASK_STATE
Attr Flags |= PWR_MASK_NOEDIT
Attr TypeRef = "pwrs:Type-$Float32" Attr TypeRef = "pwrs:Type-$Float32"
Attr GraphName = "SV" Attr GraphName = "SV"
EndBody EndBody
...@@ -380,16 +378,26 @@ SObject pwrb:Class ...@@ -380,16 +378,26 @@ SObject pwrb:Class
! Mode object display. The values may be changed in the ! Mode object display. The values may be changed in the
! more info form of the Mode object. ! more info form of the Mode object.
!*/ !*/
Object SetMinShow $Intern 21
Body SysBody
Attr TypeRef = "pwrs:Type-$Float32"
Attr GraphName = "SetMinShow"
EndBody
EndObject
Object SetMaxShow $Intern 20 Object SetMaxShow $Intern 20
Body SysBody Body SysBody
Attr TypeRef = "pwrs:Type-$Float32" Attr TypeRef = "pwrs:Type-$Float32"
Attr GraphName = "SetMaxShow" Attr GraphName = "SetMaxShow"
EndBody EndBody
EndObject EndObject
Object SetMinShow $Intern 21 !/**
! Specifies the engineering unit of XSetVal / SetVal / SetMinShow /
! SetMaxShow, e.g. kg. Used in the Mode object display.
!*/
Object SetEngUnit $Intern 24
Body SysBody Body SysBody
Attr TypeRef = "pwrs:Type-$Float32" Attr TypeRef = "pwrs:Type-$String16"
Attr GraphName = "SetMinShow" Attr GraphName = "SetEngUnit"
EndBody EndBody
EndObject EndObject
!/** !/**
...@@ -398,32 +406,22 @@ SObject pwrb:Class ...@@ -398,32 +406,22 @@ SObject pwrb:Class
! object in the Mode display. The values may be changed ! object in the Mode display. The values may be changed
! in the more info form of the Mode object. ! in the more info form of the Mode object.
!*/ !*/
Object OutMaxShow $Intern 22
Body SysBody
Attr TypeRef = "pwrs:Type-$Float32"
Attr GraphName = "OutMaxShow"
EndBody
EndObject
Object OutMinShow $Intern 23 Object OutMinShow $Intern 23
Body SysBody Body SysBody
Attr TypeRef = "pwrs:Type-$Float32" Attr TypeRef = "pwrs:Type-$Float32"
Attr GraphName = "OutMinShow" Attr GraphName = "OutMinShow"
EndBody EndBody
EndObject EndObject
!/** Object OutMaxShow $Intern 22
! Specifies the engineering unit of SetMinShow /
! SetMaxShow, e.g. kg. Used in the Mode object display.
! OutEngUnit
!*/
Object SetEngUnit $Intern 24
Body SysBody Body SysBody
Attr TypeRef = "pwrs:Type-$String16" Attr TypeRef = "pwrs:Type-$Float32"
Attr GraphName = "SetEngUnit" Attr GraphName = "OutMaxShow"
EndBody EndBody
EndObject EndObject
!/** !/**
! Specifies the engineering unit of OutMinShow / ! Specifies the engineering unit of XForcVal / OutVal /
! OutMaxShow e.g. %. Used in the Mode object display. ! ForcVal / OutMinShow / OutMaxShow e.g. %.
! Used in the Mode object display.
!*/ !*/
Object OutEngUnit $Intern 25 Object OutEngUnit $Intern 25
Body SysBody Body SysBody
......
This diff is collapsed.
...@@ -7509,14 +7509,15 @@ satta under en tid som ...@@ -7509,14 +7509,15 @@ satta under en tid som
@image orm_en1-100.gif @image orm_en1-100.gif
Insignalen OutChange betraktas som ett reglerfel. Detta fel överförs till en tid Insignalen OutChange betraktas som ett reglerfel. Detta fel överförs till en tid
genom multiplikation med Gain . Produkten adderas till ackumulatorn Acc . genom multiplikation med Gain . Produkten adderas till ackumulatorn Acc.
Absolutvärdet av Acc begränsas till MaxWindup.
Om absolut värdet av Acc är större än MinTim sätts någon av utgångarna Open Om absolut värdet av Acc är större än MinTim sätts någon av utgångarna Open
eller Close till TRUE. eller Close till TRUE.
Om Acc > MinTim sätts 'öka' signalen (= Open ) så länge som Acc = 0 , om, å Om Acc > MinTim sätts 'öka' signalen (= Open ) så länge som Acc > 0 , om, å
andra sidan, Acc < - MinTim sätts 'minska' signalen (= Close ) så länge som andra sidan, Acc < - MinTim sätts 'minska' signalen (= Close ) så länge som
Acc = 0. Vid varje exekvering räknas värdet av Acc ned respektive upp med ett Acc < 0. Vid varje exekvering räknas värdet av Acc ned respektive upp med ett
tidsbelopp av ScanTime , beroende på om 'öka' eller 'minska' signalen satts. tidsbelopp av ScanTime , beroende på om 'öka' eller 'minska' signalen satts.
För att undvika 'obefogade' styringrepp, som skulle kunna skada ställdon vid För att undvika 'obefogade' styringrepp, som skulle kunna skada ställdon vid
...@@ -7608,6 +7609,12 @@ Ackumulerad styrsignal - ingrepp i form av tid. ...@@ -7608,6 +7609,12 @@ Ackumulerad styrsignal - ingrepp i form av tid.
Ackumulerad löptid utan ingrepp. Ackumulerad löptid utan ingrepp.
</attr> </attr>
<attr>MaxWindup
Absolutvärdet av Acc begränsas till MaxWindupsekunder, för att undvika oändlig
uppvridning vid felsatta parametrar. Negativt eller noll ger ingen begränsning.
Bör vara nära gångtid från helt stängd till helt öppen. Default 30 sek.
</attr>
<attr>TimerFlag <attr>TimerFlag
Markerar aktiv timer. Markerar aktiv timer.
</attr> </attr>
...@@ -8922,13 +8929,13 @@ objektets objektbild. Gr ...@@ -8922,13 +8929,13 @@ objektets objektbild. Gr
</attr> </attr>
<attr>SetEngUnit <attr>SetEngUnit
Anger ingenjörsenheten för SetMinShow / SetMaxShow , t.ex kg. Används i Anger ingenjörsenheten för XSetVal / SetVal / SetMinShow / SetMaxShow, t.ex kg.
Mode-objektets objektbild. Används i Mode-objektets objektbild.
</attr> </attr>
<attr>OutEngUnit <attr>OutEngUnit
Anger ingenjörsenheten för OutMinShow / OutMaxShow , t.ex %. Används i Anger ingenjörsenheten för XForcVal / OutVal /ForcVal / OutMinShow / OutMaxShow, t.ex %.
Mode-objektets objektbild. Används i Mode-objektets objektbild.
</attr> </attr>
<attr>PidObjDid <attr>PidObjDid
...@@ -10361,10 +10368,14 @@ bara genom att det st ...@@ -10361,10 +10368,14 @@ bara genom att det st
Vid P- och PD-algoritm används en absolut algoritm. Utsignalen kan då alltså inte Vid P- och PD-algoritm används en absolut algoritm. Utsignalen kan då alltså inte
ligga stabilt skilt från noll utan regleravvikelse, annat än om man använder en ligga stabilt skilt från noll utan regleravvikelse, annat än om man använder en
framkopplingssignal. framkopplingssignal. Om flaggan PDAbsFlag sitter, så beräknas en offset i manuell mod,
Vid alla algoritmer med I-del baseras hela tiden förändringar i utsignalen på så att vi får en stötfri övergång till auto.
förändringar i insignalerna. Man kan fortfarande stänga av integrereringen med Vid alla algoritmer med I-del delas utsignalen upp i två delar ned hjälp av masken WindupMask.
en insignal till objektet. I-delen ingår alltid i OutWindup, medanBias, P-delen och D-delen kan tillhöra antingen OutWindup
eller AbsOut.
OutWindup begränsas av MinWindup och MaxWindup, vilket sätter flaggorna EndMin och EndMax.
Resten av utsignalen lagras i AbsOut, och total utsignal begränsas med MinOut och MaxOut
Man kan även stänga av integrereringen med en insignal till objektet.
Pid-objektet har två utgångar som båda kan användas som styrsignal. Vilken som Pid-objektet har två utgångar som båda kan användas som styrsignal. Vilken som
används i det enskilda fallet beror på hur regleringen är ordnad: används i det enskilda fallet beror på hur regleringen är ordnad:
...@@ -10388,25 +10399,35 @@ s ...@@ -10388,25 +10399,35 @@ s
skulle bli utan filtrering. skulle bli utan filtrering.
En framkopplingssignal, Bias, kan inkluderas i algoritmen genom en ingångssignal En framkopplingssignal, Bias, kan inkluderas i algoritmen genom en ingångssignal
till objektet. till objektet. Förstärkning framkoppling anges med BiasGain.
Utvärdet, OutVal, begränsas till intervallet { MinOut, MaxOut }. Det innebär att Regulatorns utsignal OutVal är uppdelad i två delar, OutWindup och AbsOut.
I-delen innefattas alltid i OutWindup. Med WindupMask kan man styra även Bias,
P-delen och D-delen till OutWindup.
OutWindup, begränsas till intervallet { MinWindup, MaxWindup }. Det innebär att
man kan tappa det stabila läget vid en orolig reglering, speciellt vid inkopplad man kan tappa det stabila läget vid en orolig reglering, speciellt vid inkopplad
D-del. D-del. Om man sätter flaggan WindupMask till BIP, så tar man bort D-delens inflytande
på OutWindup. Man kan även sätta den till BI eller I för att ta bort P-delen och
Bias från OutWindup.
Den totala utsignalen OutVal begränsas till intervallet { MinOut , MaxOut }.
Exempel: Vi har en ganska orolig flödesreglering (utsignal 0-100 %) och reglerar Exempel: Vi har en ganska orolig flödesreglering (utsignal 0-100 %) och reglerar
nära maxvarvet för pumpen. Vi behöver styra ut i snitt 98 % för att nå önskat nära maxvarvet för pumpen. WindupMask = BPID. Vi behöver styra ut i snitt 98 % för
börvärde. Utsignalen fladdrar ca +- 5 % pga störningar. Om MaxOut är 100 %, så att nå önskat börvärde. Utsignalen fladdrar ca +- 5 % pga störningar.
innebär det att regulatorn bottnar regelbundet. Utsignalen kommer då att svänga Om MaxWindup är 100 %, så innebär det att regulatorn bottnar regelbundet. Utsignalen
mellan 90 och 100 % med en medelutsignal på ca 95%, och vi når inte önskat kommer då att svänga mellan 90 och 100 % med en medelutsignal på ca 95%, och vi når inte önskat
börvärde. börvärde.
Lösning: Sätt MinOut och MaxOut till -10 % resp 110 %. Utsignalen kommer att Lösning: Sätt WindupMask till I eller BI. Störningarna kommer inte att påverka MaxWindup.
svänga mellan 93 och 103% med ett medel på 98%, och vi uppnår önskat börvärde.
Utsignalen får sedan begränsas till 0 - 100 % utanför PID-regulatorn. För en servoventil med positionsreglering, kan man vilja ha en långsam I-del för läckagekontroll,
begränsad till +- 20 %. Sätt WindupMask till I eller BI.
Sätt MinWindup = -20% och MaxWindup till +20%, MinOutput = -100 %, MaxOutput = 100 %
EndMin och EndMax kan användas för läckagelarm.
Regulatorn har stötfri omkoppling AUTO / MANUAL och efter annan tvångsstyrning av Regulatorn har stötfri omkoppling AUTO / MANUAL och efter annan tvångsstyrning av
regulatorn. regulatorn.
Dock ej vid P- eller PD-reglering. Dock ej vid P- eller PD-reglering, om man har PDAbsFlag satt.
EXEMPEL 1 EXEMPEL 1
...@@ -10638,8 +10659,8 @@ operat ...@@ -10638,8 +10659,8 @@ operat
</attr> </attr>
<attr>OutChange <attr>OutChange
Regulatorns syrsignal baserad på 'incremental form'. Regulatorns syrsignal baserad på 'incremental form', eller förändring i styrsignalen
vid 'positional form'.
Attributet avser styrsignalsförändringen mellan två konsekutiva exekveringar; Attributet avser styrsignalsförändringen mellan två konsekutiva exekveringar;
dvs. OutVal t - OutVal t-1 . dvs. OutVal t - OutVal t-1 .
</attr> </attr>
...@@ -10649,14 +10670,14 @@ Reglerfelet (= ProcVal - SetVal ). ...@@ -10649,14 +10670,14 @@ Reglerfelet (= ProcVal - SetVal ).
</attr> </attr>
<attr>EndMin <attr>EndMin
Om beräknat värde på OutVal inte tillhör intervallet { MinOut , MaxOut } ska Om beräknat värde på OutWindup inte tillhör intervallet { MinWindup , MaxWindup } ska
begränsning ske till motsvarande intervallgräns. Attributet anger om sådan begränsning ske till motsvarande intervallgräns. Attributet anger om sådan
begränsning skett vid den senaste exekveringen eller ej. begränsning skett vid den senaste exekveringen eller ej.
Om begränsning görs mot Om begränsning görs mot
-- MinOut , ska EndMin sättas TRUE -- MinWindup , ska EndMin sättas TRUE
-- MaxOut , ska EndMax sättas TRUE -- MaxWindup , ska EndMax sättas TRUE
annars är de FALSE. annars är de FALSE.
...@@ -10748,11 +10769,10 @@ V ...@@ -10748,11 +10769,10 @@ V
<attr>MinOut <attr>MinOut
I driftläge AUTO och CASCADE ska den utställda styrsignlaen OutVal vara i I driftläge AUTO och CASCADE ska den utställda styrsignlaen OutVal vara i
intervallet { MinOut , MaxOut }. Flaggorna EndMin / EndMax används för att intervallet { MinOut , MaxOut }.
signalera då begränsning sker.
Om OutVal är större än MaxOut eller mindre än MinOut , begränsas OutVal Om OutVal är större än MaxOut eller mindre än MinOut , begränsas OutVal
till värdet av motsvarande intervallgräns. till värdet av motsvarande intervallgräns.
Om MinOut = MaxOut sker ingen begränsning. Om MinOut >= MaxOut sker ingen begränsning.
</attr> </attr>
<attr>MaxOut <attr>MaxOut
...@@ -10909,6 +10929,45 @@ EndMin / EndMax flaggorna. ...@@ -10909,6 +10929,45 @@ EndMin / EndMax flaggorna.
Filtrerad derivata sparas till nästa exekevering. Filtrerad derivata sparas till nästa exekevering.
</attr> </attr>
<attr>PDAbsFlag
Anger att utsignalen beräknas direkt med regleravvikelsen.
Vid nollvärde beräknas en offset i manuell mod, så att vi får stötfri övergång till auto.
</attr>
<attr>WindupMask
Möjliga värden är:
1 -- I Bara I-delen begränsas i OutWindup
2 -- BI I-delen och Bias begränsas i OutWindup
4 -- BIP Också P-delen begränsas i OutWindup
8 -- BIPD Hela utsignalen, även D-delen begränsas i OutWindup
</attr>
<attr>MinWindup
I driftläge AUTO och CASCADE ska den utställda styrsignalen OutWindup vara i
intervallet { MinWindup , MaxWindup }. Flaggorna EndMin / EndMax används för att
signalera då begränsning sker.
Om OutWindup är större än MaxWindup eller mindre än MinWindup , begränsas OutWindup
till värdet av motsvarande intervallgräns.
Om MinWindup >= MaxWindup sker ingen begränsning.
</attr>
<attr>MaxWindup
Se MinOut
</attr>
<attr>PDManOffset
Offset beräknas i manuell mod, och används vid P och PD-algoritm
för att få stötfri övergång till auto.
</attr>
<attr>OutWindup
Utsignal som begränsas av MinWindup och MaxWindup
</attr>
<attr>AbsOut
Utsignaldel som ligger utanför OutWindup
</attr>
<attr>OpMod <attr>OpMod
OpMod = MANUAL (=1) OpMod = MANUAL (=1)
Då Mode-objektets for-utgång blir TRUE tvingas Pid-objekt utgång Då Mode-objektets for-utgång blir TRUE tvingas Pid-objekt utgång
......
!
! Proview Open Source Process Control.
! Copyright (C) 2005-2014 SSAB EMEA AB.
!
! This file is part of Proview.
!
! This program is free software; you can redistribute it and/or
! modify it under the terms of the GNU General Public License as
! published by the Free Software Foundation, either version 2 of
! the License, or (at your option) any later version.
!
! This program is distributed in the hope that it will be useful
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! GNU General Public License for more details.
!
! You should have received a copy of the GNU General Public License
! along with Proview. If not, see <http://www.gnu.org/licenses/>
!
! Linking Proview statically or dynamically with other modules is
! making a combined work based on Proview. Thus, the terms and
! conditions of the GNU General Public License cover the whole
! combination.
!
! In addition, as a special exception, the copyright holders of
! Proview give you permission to, from the build function in the
! Proview Configurator, combine Proview with modules generated by the
! Proview PLC Editor to a PLC program, regardless of the license
! terms of these modules. You may copy and distribute the resulting
! combined work under the terms of your choice, provided that every
! copy of the combined work is accompanied by a complete copy of
! the source code of Proview (the version used to produce the
! combined work), being distributed under the terms of the GNU
! General Public License plus this exception.
!
! pwrb_windupmaskenum.wb_load -- Defines the mask type WindupMaskEnum
!
SObject pwrb:Type
!/**
! @Version 1.0
! @Group Types
! Enumeration for PID WindupMask.
!
! @b See also
! @classlink PID pwrb_pid.html
!*/
Object WindupMaskEnum $TypeDef 75
Body SysBody
Attr TypeRef = "pwrs:Type-$Enum"
Attr PgmName = "WindupMaskEnum"
EndBody
!/**
! Integral part only
!*/
Object IWUP $Value
Body SysBody
Attr PgmName = "IWUP"
Attr Text = "I"
Attr Value = 1
EndBody
EndObject
!/**
! Bias and Integral part
!*/
Object BIWUP $Value
Body SysBody
Attr PgmName = "BIWUP"
Attr Text = "BI"
Attr Value = 2
EndBody
EndObject
!/**
! Bias, Integral and Proportional part
!*/
Object BPIWUP $Value
Body SysBody
Attr PgmName = "BPIWUP"
Attr Text = "BPI"
Attr Value = 4
EndBody
EndObject
!/**
! All parts of the controller are limited in OutWindup
!*/
Object BPIDWUP $Value
Body SysBody
Attr PgmName = "BPIDWUP"
Attr Text = "BPID"
Attr Value = 8
EndBody
EndObject
EndObject
EndSObject
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment