-> Hier kostenlos registrieren
Für die Interessierten hier mal die Code-Version, mit der ich an den Start gegangen bin. Vermutlich werden wir noch ein paar Anpassungen vornehmen, wie beispielsweise, dass bei Eingangswerten < 0,2 der Ausgangswert fest auf 0 gesetzt wird, um ein Offenstehen durch Offset zu verhindern.
Code:
FUNCTION "FC_BadValves" : Void
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR_INPUT
setpointFromPID : Real;
END_VAR
VAR_OUTPUT
setpointToValve : Real;
END_VAR
VAR_IN_OUT
data : "typeBacklashCompensation";
END_VAR
VAR_TEMP
tempOutput : Real;
tempDirDef : Bool;
END_VAR
VAR CONSTANT
DIR_OPENING : Int := 1;
DIR_INIT : Int := 0;
DIR_CLOSING : Int := -1;
END_VAR
BEGIN
REGION Header
// FC_BadValves
// Stellwertanpassung für Umkehrlosekompensation
END_REGION
REGION Initialize
// Init last value
IF NOT #data.init THEN
#data.lastExtreme := #setpointFromPID;
#data.initialDir := #DIR_INIT;
#data.init := TRUE;
END_IF;
// Init direction
IF TRUE
AND (#data.initialDir <> #DIR_OPENING)
AND (#data.initialDir <> #DIR_CLOSING)
THEN
IF (#setpointFromPID - #data.lastExtreme > #data.config.deadband) THEN
#data.initialDir := #DIR_OPENING;
#data.currentDir := #DIR_OPENING;
ELSIF (#data.lastExtreme - #setpointFromPID > #data.config.deadband) THEN
#data.initialDir := #DIR_CLOSING;
#data.currentDir := #DIR_CLOSING;
END_IF;
END_IF;
// Init temps
#tempOutput := #setpointFromPID; // move input to output
#tempDirDef := (#data.initialDir = #DIR_OPENING) OR (#data.initialDir = #DIR_CLOSING); // Check, if initial direction is defined
END_REGION
REGION Code
// Check if valve is closing or opening
CASE #data.currentDir OF
#DIR_CLOSING: // Valve is currently closing
// track minimum
IF (#setpointFromPID < #data.lastExtreme) THEN
#data.lastExtreme := #setpointFromPID;
END_IF;
// If input is greater than minimum + deadband, detect change in direction
IF (#setpointFromPID > #data.lastExtreme + #data.config.deadband) THEN
#data.currentDir := #DIR_OPENING;
#data.lastExtreme := #setpointFromPID;
END_IF;
#DIR_OPENING: // Valve is currently opening
// track maximum
IF (#setpointFromPID > #data.lastExtreme) THEN
#data.lastExtreme := #setpointFromPID;
END_IF;
// If input is less than minimum - deadband, detect change in direction
IF (#setpointFromPID < #data.lastExtreme - #data.config.deadband) THEN
#data.currentDir := #DIR_CLOSING;
#data.lastExtreme := #setpointFromPID;
END_IF;
ELSE // do nothing, if current direction is undefined
;
END_CASE;
// Check if offset is to be added
IF TRUE
AND #tempDirDef
AND #data.currentDir <> #data.initialDir
THEN
// If offset is to be added
IF #data.initialDir = #DIR_OPENING THEN
// And initial direction was opening
#tempOutput := #setpointFromPID - #data.config.offset;
ELSIF #data.initialDir = #DIR_CLOSING THEN
// And initial direction was closing
#tempOutput := #setpointFromPID + #data.config.offset;
END_IF;
END_IF;
END_REGION
REGION Outputs
#setpointToValve := #tempOutput;
END_REGION
END_FUNCTION



