📦 Archived documentation: r1 (committed 2026-08-05) View current documentation →

PID

Available on: Flexs Q5M

PID Loop Reference

ISA-style constants, derivative on measurement:

e  = SP − PV
CO = Kp·( e + (1/Ti)·∫e dt − Td·dPV/dt )

Kp is the overall gain; Ti and Td are times in seconds. Internally Kp/Ti and Kp·Td are cached when tuning is written (pidSetTuning() / pidRefreshTuning()), so nothing is divided at runtime.

What each constant does

A PID loop looks at the error — how far the measurement (PV) is from the target (SP) — three different ways, and adds the results together. Using a pump loop as the example: PV is flow in L/min, CO is drive frequency in Hz.

Kp — react to the error right now. The bigger the error, the harder the loop pushes: Kp = 5 means every 1 L/min of error adds 5 Hz to the output. This does most of the work, but it can't finish the job alone — as PV approaches SP the error shrinks, so the push shrinks too, and the loop settles just short of target (a permanent offset). Too low: sluggish, big offset. Too high: the loop overreacts to its own corrections and oscillates.

Ti — patiently work off whatever error remains. The integral term keeps nudging the output as long as any error persists, which is what finally lands PV exactly on SP. Ti is how patient it is: it's the time the I term takes to repeat the P term's correction on a constant error. Ti = 20 means "take about 20 seconds to double down." Smaller Ti = less patient = stronger action — note the direction, it trips people up. Too large: the last bit of error takes forever to clear. Too small: the loop keeps pushing after PV has started moving, overshoots, then hunts back and forth.

Td — anticipate where PV is heading. The derivative term watches how fast the measurement is moving and pushes against that motion — braking before arrival rather than after. Td = 2 means the loop acts as if PV were already where its current trend puts it 2 seconds from now. It tames overshoot on slow processes (temperature especially), but it amplifies sensor noise, so most flow and level loops simply run Td = 0 (PI control).

Rule of thumb: Kp responds to the present error, Ti cleans up the accumulated past, Td braces for the predicted future.

Parameters

Parameter Units Example Notes
kp CO units / PV unit 5 Primary control action. Higher = harder response, eventually instability.
ti s 20 Integral (reset) time; smaller = stronger. 0 = no reset, loop sits at permanent offset.
td s 2 Derivative lookahead. 0 = PI, correct for most flow/level loops.
outMin / outMax CO units 0 / 60 Output span in engineering units (e.g. Hz).
outRateLimit CO units / s 10 Max CO slew. 0 = off. Derive from the actuator, not preference.
dFilterTau s 0.05 D-term low-pass. Size as Td/10. 0 = off. Default 0.05.
setpoint PV units 25 Target.
mode AUTO DISABLED / MANUAL / AUTO.
manualOutput CO units CO forced (clamped) while in MANUAL.

Converting gains from other controllers

From To ours
ISA Kc, Ti, Td Drop straight in: Kp = Kc, Ti/Td unchanged
Parallel gains Kp, Ki, Kd Ti = Kp/Ki · Td = Kd/Kp
Proportional band Kp = 100/PB% (only if PV and CO are both % of span)
Ziegler-Nichols Ku, Pu Kp = 0.6·Ku · Ti = 0.5·Pu · Td = 0.125·Pu (aggressive; detune)

Built-in behavior (not configurable)

  • Derivative on PV — setpoint steps never kick the output; D always runs through the LPF when dFilterTau > 0.
  • Anti-windup — the integrator is clamped every cycle so P+I+D lands inside [outMin, outMax]; it cannot wind past the output span. The slew limiter runs downstream, so keep rate limits generous.
  • Bumpless transfer — in MANUAL the integrator tracks the output, so switching to AUTO starts from the CO already at the actuator.
  • Reverse-acting loops — no direction flag; negate Kp only. Ti and Td stay positive and inherit the direction automatically.
  • Fault handling — NaN/Inf PV holds the last output; a scan gap over 0.5 s resyncs state instead of integrating it.

Manual tuning quickstart

  1. Ti = Td = 0. Raise Kp until the loop just oscillates, then back off.
  2. Bring in Ti (start near the oscillation period) and shrink it until offset clears without hunting.
  3. Add Td last, only if overshoot is still a problem.

Functions

setPID()

setPID(id,target)

Set PID target

Arguments

NameTypeRequiredDefaultDescription
id yes PID Index #
value number | boolean yes Setpoint | true/false for enable/disable

Returns

number CO value

Example

setPID(0,80); // target 80% pid output