# FanControl

## `FanControl` (FB)

FUNCTION\_BLOCK FanControl

### Short description

> Control of a variable-speed fan (controlled variables e.g. absolute pressure, differential pressure)\
> Additional functions: manual overrides, service switch, operating hours counter, operation monitoring, air shortage monitoring, limit value monitoring\
> Typical application: control of a fan with a frequency inverter

### Representation

<figure><img src="https://2592874069-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FQR4vCFzt6ixgsqlR3pdR%2Fuploads%2Fgit-blob-18597eb1eb097634006ba8b39d22130bfa40f1fa%2FFanControl_FB.png?alt=media" alt=""><figcaption></figcaption></figure>

### Function description

#### General

This function block controls a variable-speed fan via a continuous control signal *rHA*.\
The general enablement of the fan is effected via the request *xEn* and the enable signal *xHB*.\
The speed control is carried out by a freely parameterizable PI controller, to which the setpoint *rSetPoint* and the actual value *rActValue* are supplied and from which the controller's control signal is generated.\
\
The following function blocks are essentially used:

ControlPI

ManBin

ManNum

TwoPointFun

Ramp

CTime

AirShortage

OperatingHours

#### Enable - fan before manual override *xAB*

The enable - fan before manual override *xAB* is activated ( = TRUE ) if the following conditions are met simultaneously:\
\
Case 1:\
\
\&#xNAN;*xEn* = TRUE\
\&#xNAN;*xMSwitch* = TRUE\
**xAlarmControl** = FALSE\
\
Case 2:\
\
\&#xNAN;*xEn* = TRUE\
\&#xNAN;*xMSwitch* = TRUE\
**xAlarmControl** = TRUE\
\&#xNAN;*xAlarm* = FALSE\
\
In all other situations the enable - fan before manual override is *xAB* is not activated ( = FALSE ).

#### Enable - fan after manual override *xHB*

The enable - fan after manual override *xHB* corresponds to the enable - fan before manual override *xAB*, additionally extended by a manual override module.\
The enablement can generally only occur if the forced lockout of the fan after manual override is not active ( *xForce* = FALSE )\
and the collective fault message 2 is not active ( = FALSE ).

| *xAB* | **eManModeB**  | *xHB* | Notes                                          |
| ----- | -------------- | ----- | ---------------------------------------------- |
| FALSE | eMANBIN.Auto   | FALSE | Manual override module in automatic            |
| TRUE  | eMANBIN.Auto   | TRUE  | Manual override module in automatic            |
| X     | eMANBIN.ManOn  | TRUE  | Manual override module in manual operation On  |
| X     | eMANBIN.ManOff | FALSE | Manual override module in manual operation Off |

Legend: X = any

#### Message of the service switch *xMSwitch*

*xMSwitch* = TRUE: Service switch has not been triggered ( normal state )\
\&#xNAN;*xMSwitch* = FALSE: Service switch has been triggered ( fault state )

#### Forced lockout of the fan after manual override *xForce*

*xForce* = FALSE: no forced lockout ( normal state )\
\&#xNAN;*xForce* = TRUE: forced lockout ( exceptional state )

#### Operating hours and switch-on events *udiOperatingHours* and *udiCountFb*

The number of operating hours and switch-on events are recorded ( = counting process active ) if the operation signal of the fan *xFb* is active and at the same time the collective fault message 2 is not active ( = FALSE ).\
The results are available at the counter outputs **udiOperatingHours** and **udiCountFb** and available.

> **Write access to the counter values**
>
> Via the path ‘InstanceName.\_OperatingHours.udiOperatingHours’ or ‘InstanceName.\_OperatingHours.udiCountFb’, write access to both counter values is possible.\\
>
> **Prerequisite for the use of the FanControl function block**
>
> The use of the TimeRead2 function block is required for correct operation.

#### Date / time of the last operation of the fan *dtLastFb*

At the output *dtLastFb* the current date/time is available during the counting process.\
At the output *dtLastFb* the date/time at the end of the last counting process is available outside the counting process.\
At the output *dtLastFb* is output before the first counting process with the initialization value DT#1970-1-1-0.0.0.

#### Operation monitoring *xAlarmFb*

The operation monitoring can be enabled ( = TRUE ) or inhibited ( = FALSE ) by the setpoint / parameter **xFbControl** When monitoring is inhibited, the fault message of the operation monitoring *xAlarmFb* is always inhibited ( = FALSE ).\
When monitoring is enabled, the fault message of the operation monitoring *xAlarmFb* is activated ( = TRUE ) if the following states are present simultaneously for a minimum duration **udiFbControlTime** :\
\
\&#xNAN;*xHB* and *xFb* = unequal ( enable state and operating state do not match )\
\&#xNAN;*eAOO* = HVACTYPES.eManBin.Auto ( manual override - hardware for the automatic enable )\
**xFbControl** = TRUE ( operation monitoring is enabled )\
\
The fault message of the operation monitoring *xAlarmFb* is reset ( = FALSE ) if at least one of the following conditions is met:\
\
\&#xNAN;*eAOO* = HVACTYPES.eManBin.Auto ( switching back to automatic mode of the manual override - hardware )\
\&#xNAN;*xQuit* = TRUE ( reset of the monitoring is active )\
**xFbControl** = FALSE ( operation monitoring inhibited )

#### Air shortage monitoring *xAlarmPFb*

The air shortage monitoring is performed by evaluating the states at the inputs *xPFb* and *xFb*.\
\
The fault message of the air shortage monitoring *xAlarmPFb* is activated ( = TRUE ) if, with monitoring enabled ( **xPFbControl** = TRUE ) during the air shortage monitoring alarm delay **udiPFbControlTime** the input *xPFb* is continuously not active ( = FALSE ) and the\
input *xFb* is active ( = TRUE ).\
\
The fault message of the air shortage monitoring *xAlarmPFb* is deactivated ( = FALSE ) if the conditions for activation are no longer met and at the same time monitoring is inhibited ( **xPFbControl** = FALSE ) and/or the reset of the fault messages (monitorings) is active ( *xQuit* = TRUE ).

#### Collective fault message 1 - output *xAlarm*

The collective fault message is activated ( = TRUE ) if at least one of the conditions described below is met.\
\
\&#xNAN;*xAlarmIn* = TRUE ( fan fault message is active )\
\&#xNAN;*xAlarmFB* = TRUE ( fault from the operation monitoring )\
\&#xNAN;*xAlarmPFB* = TRUE ( fault from the air shortage monitoring )\
\&#xNAN;*xMSwitch* = FALSE ( service switch in Off position )\
\&#xNAN;*xAlarmMaxValue* = TRUE ( maximum value exceeded )\
\&#xNAN;*xAlarmMinValue* = TRUE ( minimum value undershot )\
\
In all other cases the collective fault is not active ( = FALSE ).

#### Collective fault message 2

The collective fault message is activated ( = TRUE ) if at least one of the conditions described below is met.\
\
\&#xNAN;*xAlarmIn* = TRUE ( fan fault message is active )\
\&#xNAN;*xAlarmFB* = TRUE ( fault from the operation monitoring )\
\&#xNAN;*xAlarmPFB* = TRUE ( fault from the air shortage monitoring )\
\&#xNAN;*xMSwitch* = FALSE ( service switch in Off position )\
\&#xNAN;*xAlarmMaxValue* = TRUE ( maximum value exceeded )\
\
In all other cases the collective fault is not active ( = FALSE ).

#### Resetting the fault messages *xQuit*

Any rising edge ( FALSE > TRUE ) at the input *xQuit* clears any existing fault messages of the following monitoring facilities\
\
Air shortage monitoring\
Operation monitoring\
Minimum value monitoring\
Maximum value monitoring

#### Control process

General\
\
The actual value \*rActValue\* is scaled by a linear characteristic curve and fed to the PI controller.\
The setpoint \*rSetPont\* is filtered by a signal ramp, scaled by a linear characteristic defined by 2 points and fed to the PI controller.\
The output signal of the PI controller is filtered by another signal ramp and fed to the output for the control signal \*rHA\*.\
\
\
Enable\
\
The enablement of the control process takes place with a time delay of \*\*udiWaitControl\*\* after the fan operating signal becomes active ( \*xFb\* = TRUE ).\
The blocking of the control process occurs without time delay after the fan operating signal becomes inactive ( \*xFb\* = FALSE ).\
\
\
Setpoint\
\
The setpoint is fixed to 0.0 if the fan enable is not active ( \*xHB\* = FALSE ).\
The setpoint is taken from the input \*rSetPoint\*, filtered by a signal ramp and scaled by a linear function defined by 2 points ( prerequisite: \*xHB\* = TRUE ).\
The relevant parameters of the signal ramp are individually adjustable ( maximum variation = (\*\*rMaxValue\*\* / 5) per 10s ).\
The relevant parameters of the linear function are individually adjustable ( input range in Pa: 0.0 - \*\*rMaxValue\*\*, output range in %: 0.0 - 100.0 ).\
\
\
Actual value\
\
The actual value is taken from the input \*rActValue\* and scaled by a linear function defined by 2 points.\
The relevant parameters of the linear function are individually adjustable ( input range in Pa: 0.0 - \*\*rMaxValue\*\*, output range in %: 0.0 - 100.0 ).\
\
\
Limitation of the PI controller control signal \*\*rYMin\*\* and \*\*rYMax\*\*\
\
The controller's control signal ( PI controller ) is limited by the adjustable limits \*\*rYMin\*\* and \*\*rYMax\*\* ( minimum value monitoring not active ) or \*\*rSubstitueHA\*\* ( minimum value monitoring active ).\
\
\
Signal ramp of the controller's control signal\
\
The control signal from the PI controller is filtered by a signal ramp.\
The relevant parameters of the signal ramp are individually adjustable ( maximum variation = \*\*rYRampVariation\*\* per \*\*rYRampTime\*\* ).\
\
\
Parameters of the PI controller\
\
The parameters essential for the control behavior can be provided from outside. They must be adapted depending on the control path.\
A sensible basic parameterization has already been made, which is sufficient in many application cases.\
\
\*\*rYMin\*\* = Lower absolute limit of the controller output signal\
\*\*rYMax\*\* = Upper absolute limit of the controller output signal\
\*\*rOffset\*\* = Setpoint offset - controller\
\*\*rKp\*\* = Gain factor - controller\
\*\*rTn\*\* = Reset time - controller in s\
\*\*eAction\*\* = Action direction of the controller ( Inverted, Direct )\
\*\*rInitValue\*\* = Initialization value for the control signal\
\*\*rYDisabled\*\* = Control signal when controller is inactive\
\
\
Signals of the PI controller\
\
The signals calculated during the control process ( before the signal ramp ) are available to monitor the control operation.\
\
\*rPiDiff\* = Control deviation at the controller\
\*rPiPartP\* = Proportional part of the control signal\
\*rPiPartI\* = Integral part of the control signal\
\*xPiLimitActiv\* = Status - limit exceedance - control signal ( FALSE = Off, TRUE = On )\
\
\
Controller control signal\
\
If the controller is not enabled, the switch-off value \*\*rYDisabled\*\* is passed to the controller control signal output ( prerequisite: \*\*ePiManModeN\*\* = eMANNUM.Auto ) and limited by the absolute limits.\
The integral part is set to 0.0.\
\
If the controller is enabled, the controller control signal is calculated ( prerequisite: \*\*ePiManModeN\*\* = eMANNUM.Auto ) and limited by the absolute limits.\
\
With the default action \*\*eAction\*\* ( = eControlMode.Inverted ) a too low actual value ( actual value < setpoint ) causes a continuous increase of the controller control signal value.

#### Control signal fan before manual override *rAA*

The control signal of the fan before manual override *rAA* is primarily taken from the controller output signal after the signal ramp.\
However, this output signal is additionally limited downward during the fan request ( *xHB = TRUE ) by the lower absolute limit \*\*rYMin\** downwards.\
In the event of a minimum value undershoot ( *xAlarmMinValue* = TRUE ) the control signal before manual override *rAA* is replaced by the fixed value **rSubstitueHA** .

#### Control signal fan after manual override *rHA*

The control signal of the fan after manual override *rHA* corresponds to the control signal of the fan before manual override *rAA* additionally extended by a manual override module.

| *rAA* | **eManModeN** | *rHA*         | Notes                                      |
| ----- | ------------- | ------------- | ------------------------------------------ |
| X     | eMANNUM.Auto  | *rAA*         | Manual override module in automatic        |
| X     | eMANNUM.Man   | **eManValue** | Manual override module in manual operation |

Legend: X = any

#### Operating mode for the controller output signal **ePIManModeN**

The parameter **ePiManModeN** allows switching the controller output signal from automatic to manual operation and vice versa.\
In manual operation the controller output signal takes over the manual operation output signal **ePiManValue**.

| **ePiManModeN** | Output signal                                  | Function                       |
| --------------- | ---------------------------------------------- | ------------------------------ |
| eMANNUM.Auto    | Signal according to formula / switch-off value | Automatic mode - output signal |
| eMANNUM.Man     | **ePiManValue**                                | Manual mode - output signal    |

#### Maximum pressure monitoring *xAlarmMaxValue*

The output *xAlarmMaxValue* is activated ( = TRUE ) if the current actual value *rActValue* exceeds the adjustable maximum value **rMaxValue** .\
The output *xAlarmMaxValue* is deactivated ( = FALSE ) if the current actual value *rActValue* exceeds the adjustable maximum value **rMaxValue** falls below and at the same time a rising edge ( FALSE > TRUE ) is detected at the input *xQuit* .

#### Minimum pressure monitoring *xAlarmMinValue*

The output *xAlarmMinValue* is activated ( = TRUE ) if the following conditions are simultaneously permanently fulfilled for a minimum duration of **udiWaitMinValue**  ( 1.0 - 600.0 s ):\
\
\&#xNAN;*xFb* = TRUE ( fan is in operation )\
\&#xNAN;*eAO* = HVACTYPES.eManNum.Auto ( operating mode of the manual override - hardware for the control signal in automatic mode )\
\&#xNAN;*rHA* > **rMinHAValue** ( control signal is greater than the minimum value )\
\&#xNAN;*rActValue* < **rMinValue** ( actual value is smaller than the minimum value )\
No rising edge ( FALSE > TRUE ) was detected at the input *xQuit* recognized\
The output *xAlarmMinValue* is deactivated ( = FALSE ) if the conditions for activation are no longer met and at the same time at the input *xQuit* .

#### Combined message automatic mode *xAuto*

The combined message automatic mode *xAuto* is activated ( = TRUE ) if the following conditions are met simultaneously:\\

* Input *eAOO* = HVACTYPES.eManBin.Auto
* Input *eAO* = HVACTYPES.eManNum.Auto
* Setpoint / parameter **eManModeB** = eMANBIN.Auto
* Setpoint / parameter **eManModeN** = eMANNUM.Auto
* Setpoint / parameter **ePiManModeN** = eMANNUM.Auto

### CODESYS

InOut:

| Scope       | Name                | Type         | Initial               |
| ----------- | ------------------- | ------------ | --------------------- |
| Input       | `xEn`               | `BOOL`       |                       |
| Input       | `xForce`            | `BOOL`       | FALSE                 |
| Input       | `xFb`               | `BOOL`       |                       |
| Input       | `xPFb`              | `BOOL`       |                       |
| Input       | `xMSwitch`          | `BOOL`       | TRUE                  |
| Input       | `xAlarmIn`          | `BOOL`       |                       |
| Input       | `eAOO`              | eManBin      | eManBin.Auto          |
| Input       | `eAO`               | eManNum      | eManNum.Auto          |
| Input       | `rPoti`             | `REAL`       |                       |
| Input       | `rU`                | `REAL`       |                       |
| Input       | `xQuit`             | `BOOL`       | FALSE                 |
| Input       | `rActValue`         | `REAL`       |                       |
| Input       | `rSetPoint`         | `REAL`       |                       |
| Output      | `xHB`               | `BOOL`       |                       |
| Output      | `xAB`               | `BOOL`       |                       |
| Output      | `rHA`               | `REAL`       |                       |
| Output      | `rAA`               | `REAL`       |                       |
| Output      | `xAlarmFb`          | `BOOL`       |                       |
| Output      | `xAlarmPFb`         | `BOOL`       |                       |
| Output      | `xAlarmMinValue`    | `BOOL`       |                       |
| Output      | `xAlarmMaxValue`    | `BOOL`       |                       |
| Output      | `dtLastFb`          | `DT`         |                       |
| Output      | `udiOperatingHours` | `UDINT`      |                       |
| Output      | `udiCountFb`        | `UDINT`      |                       |
| Output      | `xAlarm`            | `BOOL`       |                       |
| Output      | `xAuto`             | `BOOL`       |                       |
| Output      | `rPiDiff`           | `REAL`       |                       |
| Output      | `rPiPartP`          | `REAL`       |                       |
| Output      | `rPiPartI`          | `REAL`       |                       |
| Output      | `xPiLimitActiv`     | `BOOL`       |                       |
| Input Const | `rMaxValue`         | `REAL`       | 490                   |
| Input Const | `rSubstituteHA`     | `REAL`       | 30                    |
| Input Const | `udiWaitMinValue`   | `UDINT`      | 60                    |
| Input Const | `rMinHAValue`       | `REAL`       | 20                    |
| Input Const | `rMinValue`         | `REAL`       | 20                    |
| Input Const | `tYRampTime`        | `TIME`       | TIME#1m0s0ms          |
| Input Const | `rYRampVariation`   | `REAL`       | 30                    |
| Input Const | `udiWaitControl`    | `UDINT`      | 30                    |
| Input Const | `rYMax`             | `REAL`       | 100                   |
| Input Const | `rYMin`             | `REAL`       | 20                    |
| Input Const | `rTn`               | `REAL`       | 60                    |
| Input Const | `rKp`               | `REAL`       | 1                     |
| Input Const | `rOffset`           | `REAL`       | 0                     |
| Input Const | `rInitValue`        | `REAL`       | 20                    |
| Input Const | `rYDisabled`        | `REAL`       | 0                     |
| Input Const | `eAction`           | eControlMode | eControlMode.Inverted |
| Input Const | `ePiManValue`       | `REAL`       |                       |
| Input Const | `ePiManModeN`       | eMANNUM      | eMANNUM.Auto          |
| Input Const | `udiPFbControlTime` | `UDINT`      | 60                    |
| Input Const | `xPFbControl`       | `BOOL`       | TRUE                  |
| Input Const | `xAlarmControl`     | `BOOL`       | TRUE                  |
| Input Const | `udiFbControlTime`  | `UDINT`      | 60                    |
| Input Const | `xFbControl`        | `BOOL`       | TRUE                  |
| Input Const | `rManValue`         | `REAL`       |                       |
| Input Const | `eManModeN`         | eMANNUM      | eMANNUM.Auto          |
| Input Const | `eManModeB`         | eMANBIN      | eMANBIN.Auto          |

Methods:

> mQuit

> mResetOperatingHours

Structure:

* mQuit (Method)
* mResetOperatingHours (Method)
