Hello,and welcome back to techme. Today we will present a special lesson of How to use PID controller for Siemens SCL Tia-Portal.
We've always had a lot to do with the Tia Portal's control technology and we've never been satisfied with our Siemens units. We need PI controllers for pressure control and PID controllers for temperature control. Here are some of the problems:
- Different devices between different CPUs use different lib.
- It cannot be simulated.
- The source cannot be read and changed.
- Very complex with a high level of familiarity.
- Very high integration at TIA.
- Do a lot of repairs and testing until something finally worked.
instructionhe controller produce a outputs from 0 to 100. If used with a binary actor you shoud use the clock generator for pulse width modulation. The PI controller is disigned to run alone. Usefull for pressure regulation. The controller should alwasys stoped with the reset input is the regulation loop is disturbed. This prevents the integral to windup.
ir_Input = The mesuered value of pressure or themperature ir_Setpoint = The demanded value of pressure or themperature ir_ProportionalGain = The proportional gain, a tuning parameter ir_IntegrationGain = The integral gain, a tuning parameter ir_DifferentialGain = The derivative gain, a tuning parameter itime_DifferezialActionTime = The length of the derivative action, a tuning parameter ib_Reset = Empty the integral and sets the output to zero or_Output = Output value in % from 0 to 100
Installing
Installation is very simple. Enter the SLC file under "External Source Files" and then execute the "Create blocks from source" menu item.
FUNCTION_BLOCK "fb_PI-Regler_TIA300_V15.0.2" { S7_Optimized_Access := 'FALSE' } VERSION : 0.1 VAR_INPUT ir_Istwert { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Real; // Istwert ir_Sollwert { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Real; // Sollwert ir_ProportionalVerstärkung { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Real := 20.0; // Proportional-Verstärkung ir_IntegralVerstärkung { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Real := 5.0; // Integral-Verstärkung ib_Reset { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool := FALSE; // Reset ii_OB1_PREV_CYCLE { ExternalVisible := 'False'} : Int := 5; // Cycle time of previous OB1 scan (milliseconds) END_VAR VAR_OUTPUT or_Reglerantwort { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Real; // Regler Ausgang END_VAR VAR Reglerantwort_Integral { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Real; Reglerantwort_Proportional { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Real; VergangeneZeit { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Real; // in s END_VAR VAR CONSTANT UnteresLimit : Real := 0.0; // unteres Limit OberesLimit : Real := 100.0; // oberes Limit END_VAR BEGIN //read elpsed Time in s since last Time from OB1 Temp #VergangeneZeit := INT_TO_REAL(#ii_OB1_PREV_CYCLE)/1000; //initialize at power_up IF #ib_Reset THEN #Reglerantwort_Integral := 0.0; #or_Reglerantwort := 0.0; ELSE // calculate proportional part #Reglerantwort_Proportional := #ir_ProportionalVerstärkung * (#ir_Sollwert - #ir_Istwert); //run integrator only IF Time makes sens IF #VergangeneZeit > 0 AND #VergangeneZeit < 0.1 THEN #Reglerantwort_Integral := #Reglerantwort_Integral + #ir_IntegralVerstärkung * (#ir_Sollwert - #ir_Istwert) * #VergangeneZeit; END_IF; // calculate output #or_Reglerantwort := #Reglerantwort_Proportional + #Reglerantwort_Integral; // check output FOR limits IF #or_Reglerantwort >= #OberesLimit THEN #or_Reglerantwort := #OberesLimit; #Reglerantwort_Integral := #OberesLimit - #Reglerantwort_Proportional; ELSIF #or_Reglerantwort <= #UnteresLimit THEN #or_Reglerantwort := #UnteresLimit; #Reglerantwort_Integral := #UnteresLimit - #Reglerantwort_Proportional; END_IF; END_IF; END_FUNCTION_BLOCK
PI-Regler_S7_300_V15.0.2.SCL
FUNCTION_BLOCK fb001
VAR_INPUT
ir_Istwert : Real; // Istwert
ir_Sollwert : Real; // Sollwert
ir_ProportionalVerstaerkung : Real := 20.0; // Proportional-Verstaerkung
ir_IntegralVerstaerkung : Real := 5.0; // Integral-Verstaerkung
ib_Reset : Bool := FALSE; // Reset
ii_OB1_PREV_CYCLE : Int := 5; // Cycle time of previous OB1 scan (milliseconds)
END_VAR
VAR_OUTPUT
or_Reglerantwort : Real; // Regler Ausgang
END_VAR
VAR
Reglerantwort_Integral : Real;
Reglerantwort_Proportional : Real;
VergangeneZeit : Real; // in s
END_VAR
CONST
UnteresLimit := 0.0; // unteres Limit
OberesLimit := 100.0; // oberes Limit
END_CONST
BEGIN
//read elpsed Time in s since last Time from OB1 Temp
VergangeneZeit := INT_TO_REAL(ii_OB1_PREV_CYCLE)/1000;
//initialize at power_up
IF ib_Reset THEN
Reglerantwort_Integral := 0.0;
or_Reglerantwort := 0.0;
ELSE
// calculate proportional part
Reglerantwort_Proportional := ir_ProportionalVerstaerkung * (ir_Sollwert - ir_Istwert);
//run integrator only IF Time makes sens
IF VergangeneZeit > 0 AND VergangeneZeit < 0.1 THEN
Reglerantwort_Integral := Reglerantwort_Integral + ir_IntegralVerstaerkung *
(ir_Sollwert - ir_Istwert) * VergangeneZeit;
END_IF;
// calculate output
or_Reglerantwort := Reglerantwort_Proportional + Reglerantwort_Integral;
// check output FOR limits
IF or_Reglerantwort >= OberesLimit THEN
or_Reglerantwort := OberesLimit;
Reglerantwort_Integral := OberesLimit - Reglerantwort_Proportional;
ELSIF or_Reglerantwort <= UnteresLimit THEN
or_Reglerantwort := UnteresLimit;
Reglerantwort_Integral := UnteresLimit - Reglerantwort_Proportional;
END_IF;
END_IF;
END_FUNCTION_BLOCK