The operations to be carried out by the DSP module are specified
directly in the matplc.conf file (or in a separate file, using
*include filename
), in the fblock
table.
The fblock
table has the usual stepladder semantics: at the
top, register values and contacts are read from the rest of the MatPLC
(inputs, HMI, or other logic modules). The table is then scanned from top
to bottom, with the operations being done in order. At the bottom of the
table, register values and coils are written to the MatPLC core, to be used
by the rest of the system (outputs, HMI or other logic modules).
fblock
).
The fblock
table is used to configure the function blocks
the dsp module will execute.
The main parameter is:
out_time_pt = <plc_pt> where plc_pt is where the dsp will store the current time out_time_pt = timeThe scan_period parameter is valid for any module, but it will probably be used extensively by the dsp module.
scan_period = x time in seconds scan_period = 0.1
The fblock
table is used to configure the function blocks
the dsp module will execute. The function blocks are executed in the same
order in which they are configured (ie top to bottom). In the usual
stepladder way, inputs are read once at the top of the table and results
are not available to other modules until the bottom of the table.
#fblock typeconv <in_pt1> <in_pt1_type> <out_pt1> <out_pt1_type> [<in_pt2> <in_pt2_type> <out_pt2> <out_pt2_type>] ... <in_pt_type> <out_pt_type> : How to interpret the bits in the previous point. = {i32 | u32 | f32}
#fblock add <out_pt> <in_pt1> <in_pt1_mult> [<in_pt2> <in_pt2_mult>] ... out_pt = (in_pt1 * in_pt1_mult) + (in_pt2 * in_pt2_mult) + ... Note: currently a maximum of 10 in_pt are supported.
#fblock mult <out_pt> <in_pt1> <in_pt1_ofs> [<in_pt2> <in_pt2_ofs>] ... out_pt = (in_pt1 + in_pt1_ofs) * (in_pt2 + in_pt2_ofs) * ... Note: currently a maximum of 10 in_pt are supported.
#fblock pow <out_pt> <in_pt> <in_pt_pow> where: out_pt : matplc point to be used as output in_pt : matplc point to be used as input in_pt_pow : raise in_pt to in_pt_pow (f32 value) in_pt_pow out_pt = (in_pt)
fblock pid <in_pt> <out_pt> [<P> [<I> [<D>]]] [max_out <upper_limit>] [min_out <lower_limit>]
[man_mode <manual_mode_pt>] [man_out <manual_value_pt>]
This block implements a parallel PID controler.
out_pt = P*in_pt + I*integral(in_pt, dt) + D*din_pt/dt
The output is guaranteed to stay within the configured limits (lower_limit <= output <= upper_limit) in automatic mode. This is achieved by adjusting the integral, which means that the pid will not 'wind up' when the output is saturated.
The man_mode and man_out settings work together to provide bumpless manual-to-automatic transfer. See the bumpless transfer section for more details.
When man_mode_pt is ON, the block is in manual mode:
out_pt = manual_value_pt
In manual mode, the integral is adjusted in such a way that when
man_mode_pt goes OFF, the PID block will smoothly take over from the
operator.
Note that manual mode ignores the upper and lower limits; if necessary, pass the operator's setting through a nonlinear block to clip it to the limits (and perhaps also through the ramp block). This also means that if the operator sets the process outside the limits and switches to automatic, there will be a bump as the PID immediately jumps to within the limits.
Also note that bumpless transfers are only supported when I is non-zero.
setting | meaning | default value |
---|---|---|
P | proportional coefficient of PID | 1 |
I | integral coefficient of PID | 0 |
D | derivative coefficient of PID | 0 |
upper_limit | maximum output value for automatic mode | none |
lower_limit | minimum output value for automatic mode | none |
manual_mode_pt | manual/automatic selection | none (always automatic) |
manual_value_pt | value to be output in manual mode | none (always zero) |
fblock filter iir [<C> [<A1> [<A2> [<B1> [<B2>]]]] ...
fblock filter <filter_type> <filter_shape> <gain> <passband_tol> <stopband_tol> <f1> <f2> [<f3> <f4>]
Where:
C, A1, A2, B1, B2 | second order iir filter parameters directly | Please see below for an explanation of what an iir filter is. These five parameters completely specify the filter, so no further parameters are necessary. | ||||||||||||||||||||||||||||||||||||||||||||||||
filter_type | {butterworth | chebyshev | elliptic} | This method is used to configure the filter as an equivalent to an analog filter. At setup these parameters are transformed into the equivalent iir filter, which will be executed at run-time. | ||||||||||||||||||||||||||||||||||||||||||||||||
filter_shape | {lowpass | highpass | bandpass | bandstop} | NOTE: These transformations have not been completely debuged. lowpass and highpass *should* be working correctly. bandpass and bandstop are known to be buggy. | ||||||||||||||||||||||||||||||||||||||||||||||||
gain | the gain of the filter for the passband frequencies |
| ||||||||||||||||||||||||||||||||||||||||||||||||
passband_tol (stopband_tol) | max(min) atenuation for pass(stop)band | maximum(minimum) atenuation, in positive dB, for the passband(stopband) frequencies | ||||||||||||||||||||||||||||||||||||||||||||||||
fX | frequency limits in Hz | NOTE: The meaning of f1, f2, f3 and f4 depends on the
filter shape. The idea is to have valid frequencies always in increasing
value.
|
The filter block implements X second order iir filters in series. A second order iir filter:
|\ | \ in >----|C >-->(+)-->(+)----------------------->(+)-->(+)---> out | / ^ ^ | ^ ^ |/ | | | | | | | v | | | | (z-1) | | | | /| /| | |\ | | | | / | / | | | \ | | | --<-1|--<B1|<---|--->|A1>--- | | \ | \ | | | / | | \| \| v |/ | | (z-1) | | /| /| | |\ | | / | / | | | \ | |-------<-1|--<B2|<---|--->|A2>--------| \ | \ | | / \| \| |/ |
fblock ramp <in_pt> <out_pt> [dxdt <xx>] [pos_dxdt
<xx>] [neg_dxdt <xx>] [d2xdt2 <xx>] [pos_d2xdt2
<xx>] [neg_d2xdt2 <xx>]
Where:
in_pt | : | the plc_pt where the input value (x) is stored |
out_pt | : | the plc_pt where to store the output value |
dxdt | : | maximum speed with which x may change (both positive and negative changes). |
pos_dxdt | : | maximum speed with which x may rise. Defaults to no limit. |
neg_dxdt | : | maximum speed with which x may fall. Defaults to no limit. |
d2xdt2 | : | maximum speed with which dx/dt may change (both positive and negative changes). |
pos_d2xdt2 | : | maximum speed with which dx/dt may rise. Defaults to no limit. |
neg_d2xdt2 | : | maximum speed with which dx/dt may fall. Defaults to no limit. |
fblock nonlinear <in_pt> <out_pt> [cutoff_top <xx>]
[cutoff_bot <xx>] [deadband_top <xx>] [deadband_bot <xx>]
[deadband_out <xx>] [gain <xx>]
Defaults are:
cutoff_top | : | f32_MAX |
cutoff_bot | : | -f32_MAX |
deadband_top | : | 0 |
deadband_bot | : | 0 |
deadband_out | : | 0 |
gain | : | 1 |
The nonlinear part, implements the following function:
out = nl_f(in): # out # ^ # | # | # co_top |.............................-------- # | / # | / # | / # | / # | / # | / # | / # | / inclination = 1 # | / # | / # db_out |...---------------- # | /. . # | / . . # |/ . . # | . . # /| . . # / | . . # / | . . # / | . . <--------------------------------------------------------------> in # / | db_bot db_top # / | # / | # / | ----------------.........| co_bot # | # | # | # v # (co = cutoff db = deadband)
The linear part implements the following function:
out = l_f(in) = in * gain
The output of the complete nonlinear block is:
out = nl_f( in * gain )
#fblock alarm <in_pt> {true_val|abs_val} <out_pt1> <comp1> <limit1> [<out_pt2> <comp2> <limit2>] ... where: in_pt : matplc point to be used as input for the alarm block true_val: use the value in in_pt without any changes abs_val : use the absolute value in in_pt for determining the alarms out_pt : matplc point to be used as output for the alarm block limitl : f32 value used for the alarm comparison comp : specifies when the alarm should be set. one of: {less | lt | smaller | st | less_or_equal | le | smaller_or_equal | se | greater | gt | greater_or_equal | ge | equal | eq | not_equal | ne} Note: less, lt, smaller, and st, are all equivalent greater and gt are equivalent greater_or_equal and ge are equivalent etc... Example: fblock alarm in_pt true_val out_1 10 lt out_2 10 gt out_3 20.55 eq (consider in_pt_val the value currently stored in the in_pt PLC point) then the above config line will have the efect of: - out_1 being true (1) when in_pt_val < 10, and (false) 0 otherwise - out_2 being true (1) when in_pt_val > 10, and (false) 0 otherwise - out_1 being true (1) when in_pt_val = 20.55, and (false) 0 otherwise
#fblock multiplexor <out_pt> <ctrl_pt> <in_pt1> [<limit1> <in_pt2>] ... where: out_pt : matplc point to be used as output for the multiplexor block ctrl_pt: matplc point used to decide which input to copy to the output in_ptX : matplc point to be used as input for the multiplexor block limitX : limit value at which the output switches from one input to another out_pt = in_pt1 -> if (ctrl_pt < limit1) out_pt = in_pt2 -> if (ctrl_pt >= limit1) AND (ctrl_pt < limit2) out_pt = in_pt3 -> if (ctrl_pt >= limit2) AND (ctrl_pt < limit3) ...
$Date: 2006/07/20 16:59:02 $