PID Controllers

Last updated March 19, 2026


PID Controllers

PID controllers are software parts in the LoopString Configurator that automatically hold a sensor reading at a target value by continuously adjusting an actuator's output. They run entirely on your Raspberry Pi and do not require a cloud connection to operate.

Before You Start: Is PID Right for Your Setup?

This is the most important question to answer before adding a PID controller.

PID controllers require an actuator that can operate at partial power. A PWM fan that can spin at 30%, 60%, or 100% is a perfect match. A 0–10V variable speed drive is perfect. A PWM-capable heating mat controller is perfect.

PID controllers do not work well with binary (on/off) actuators such as smart plugs, relays, or standard contactors. These devices are either fully on or fully off — they cannot run at 47% power. If you wire a PID output to a relay-controlled device, the controller will rapidly switch it on and off as it tries to hit the target. This causes excessive wear, premature failure, and poor temperature control.

If your actuator is a smart plug, a Wi-Fi outlet, a relay, or any other on/off switch: use a Hysteresis Controller instead. Hysteresis controllers are designed specifically for binary actuators.

A quick way to decide:

  • Your actuator has a speed dial, a 0–10V input, or a PWM input — use PID.
  • Your actuator plugs into a wall outlet or is controlled by a relay — use Hysteresis.

How PID Control Works

A PID controller calculates an output percentage every time it receives a new sensor reading. The calculation is based on three terms:

Proportional (P): The output responds proportionally to how far the sensor reading is from the target. If you are 2 degrees below target, the output might be 40%. If you are 5 degrees below target, the output might be 100%. The Proportional Band setting controls how wide this response zone is.

Integral (I): Over time, if the sensor stays slightly off target, the integral term slowly increases the output to close that remaining gap. This eliminates the small steady-state error that proportional control alone cannot fix. The Integral Time setting controls how aggressively this correction accumulates.

Derivative (D): The derivative term anticipates where the sensor is heading based on its rate of change and applies a counteracting output to slow down overshoot. It is rarely needed for environmental control and is set to zero by default.

All three terms together give the algorithm its name: Proportional-Integral-Derivative.

Dashboard Controls

Every PID controller part appears as a card on your dashboard once deployed. You interact with it through the PID settings modal, which opens when you tap the gear icon on the card.

Inside the modal you will find:

Setpoint: The target value you want the controller to maintain. For temperature controllers this is in your preferred unit (°C or °F). Changes to the setpoint take effect immediately without re-deploying flows.

Output Limits: Clamp the controller output between a minimum and maximum percentage. The defaults are 0% minimum and 100% maximum. Reducing the maximum prevents an actuator from running at full power even during large errors, which is useful for protecting sensitive equipment.

Enabled toggle: Pauses or resumes the controller. When disabled, the output is held at 50% (the neutral midpoint), which corresponds to neither heating nor cooling in a split-output controller.

Card Display: Choose which output indicators appear on the dashboard card. For split-output controllers (Heat/Cool PID, Humidity PID) you can show or hide the heat/cool or humidify/dehumidify percentages independently.

Tuning Parameters (advanced): A collapsible section containing Proportional Band, Integral Time, Derivative Time, and Sample Time. Changes here require re-deploying flows to the device to take effect.


Heat/Cool PID (pid-heatcool)

The Heat/Cool PID is a bi-directional temperature controller with two separate outputs — one for heating and one for cooling. It is the right choice when your system needs to both warm and cool to maintain a precise temperature setpoint.

How It Works

The single PID output (a value from 0 to 1) is split at the midpoint:

  • Values above 0.5 drive the heat output (0% to 100%)
  • Values below 0.5 drive the cool output (0% to 100%)
  • At exactly 0.5 (on setpoint), both outputs are 0%

This means only one direction is ever active at a time. The controller never heats and cools simultaneously.

Signals

  • Input: temperature reading from any temperature sensor (number, in °C)
  • Output 1 (Heat): 0–100% output signal for a heating actuator (PWM fan, heating element)
  • Output 2 (Cool): 0–100% output signal for a cooling actuator (PWM fan, chiller pump)

Configuration Options

Temperature Setpoint — The target temperature. Default: 25°C. Valid range: 5°C to 40°C, in 0.5°C steps. On the dashboard this is shown and edited in your preferred unit.

Proportional Band (Pb) — The temperature range over which the output spans from 0% to 100%. A value of 2°C means the controller reaches full output when the reading is 2°C away from the setpoint. Default: 2°C. Valid range: 0.5°C to 20°C.

Integral Time (Ti) — Controls how quickly steady-state error is corrected. Default: 9999 (effectively disabled). Set lower (200–1000) only after proportional tuning is stable.

Sample Time — How often the PID recalculates, in milliseconds. Default: 30000 (every 30 seconds). Match this to your sensor's publish interval.

Compatible Hardware

Requires two proportional actuators — one for heating, one for cooling. Examples:

  • PWM fan controllers (such as a Raspberry Pi GPIO PWM output driving a fan)
  • 0–10V analog output modules (such as Sequent Microsystems 8-Layer HAT analog outputs)
  • Variable frequency drives

Do not wire these outputs to smart plugs or relays.


Humidity PID (pid-humidity)

The Humidity PID works identically to the Heat/Cool PID but controls humidity instead of temperature. It has two outputs — one for humidification and one for dehumidification.

Signals

  • Input: relative humidity reading from any humidity sensor (number, in %RH)
  • Output 1 (Humidify): 0–100% signal for a misting system, ultrasonic fogger, or humidifier
  • Output 2 (Dehumidify): 0–100% signal for an exhaust fan or dehumidifier

Configuration Options

Humidity Setpoint — Target relative humidity. Default: 85%RH. Valid range: 10%RH to 100%RH.

Proportional Band (Pb) — Humidity error range that spans full output. Default: 5%RH. Valid range: 1%RH to 50%RH. A value of 5 means the controller reaches full output when humidity is 5%RH away from target.

Integral Time (Ti) — Default: 9999 (disabled). Tune only after proportional control is stable.

Sample Time — Default: 30000ms (30 seconds).

Limitations

Humidity responds more slowly than temperature. Foggers and misters add humidity in bursts rather than continuously, which makes proportional PWM control difficult unless you have hardware that genuinely supports variable misting rates. For most relay-controlled foggers or smart plug–controlled humidifiers, the Hysteresis Controller is a better fit.


CO₂ Ventilation PID (pid-co2-ventilation)

The CO₂ Ventilation PID drives exhaust fans to bring CO₂ levels down toward a target ppm setpoint. When CO₂ rises above the setpoint, the output increases, spinning up exhaust fans to bring in fresh air. When CO₂ falls below the setpoint, the output decreases.

Signals

  • Input: CO₂ reading from a sensor such as the MH-Z19 (number, in ppm)
  • Output: 0–100% ventilation demand signal

Configuration Options

CO₂ Setpoint — Target CO₂ concentration. Default: 800 ppm. Valid range: 100 ppm to 5000 ppm, in 50 ppm steps. Outdoor ambient air is approximately 420 ppm. Mushroom fruiting rooms typically target 500–800 ppm. Grow tents for cannabis typically target 1000–1500 ppm during lights-on.

Proportional Band (Pb) — CO₂ error range (in ppm) that spans full output. Default: 200 ppm. Valid range: 50 ppm to 2000 ppm. A value of 200 means the exhaust fan reaches full speed when CO₂ is 200 ppm above the setpoint.

Integral Time (Ti) — Default: 9999 (disabled).

Sample Time — Default: 30000ms. For the MH-Z19 sensor, this should be at least 30000ms because the sensor needs time between readings to deliver accurate measurements. Do not set this below 5000ms.

MH-Z19 Warm-Up Note

The MH-Z19 CO₂ sensor requires approximately 3 minutes to warm up after power-on before its readings are reliable. During this period the sensor may report very high or very low values, which can cause the CO₂ PID to drive the exhaust fans to full speed briefly. This is expected behavior and settles once the sensor stabilizes.

Compatible Hardware

The single output works best with a proportional actuator such as a PWM-controlled AC fan speed controller or a variable blower with a 0–10V input. However, for basic CO₂ ventilation in grow tents and mushroom rooms, many users connect this output to a smart plug through a duty-cycle approach (on/off at a rate proportional to the output percentage), which is handled by a separate duty-cycle node in the flow.


3-Stage Cooling Controller (cooling-3stage)

The 3-Stage Cooling Controller uses a PID core to calculate a cooling demand percentage, then routes that demand through three discrete thresholds to activate stages of cooling equipment. Rather than variable-speed output, it produces boolean (on/off) signals for up to three cooling actuators.

This controller is useful when you have multiple cooling devices that should activate in sequence as heat load increases — for example, a circulation fan at low demand, then a chiller at medium demand, then an emergency backup at high demand.

Signals

  • Input: temperature reading (number, in °C)
  • Output 1 (Stage 1): boolean — on when cooling demand exceeds Stage 1 threshold
  • Output 2 (Stage 2): boolean — on when cooling demand exceeds Stage 2 threshold
  • Output 3 (Stage 3): boolean — on when cooling demand exceeds Stage 3 threshold
  • Output 4 (All Off): boolean — on when cooling demand is zero (all stages off)

Configuration Options

Temperature Setpoint — Default: 21°C. Valid range: 5°C to 40°C.

Proportional Band (Pb) — PID proportional band in °C. Default: 2°C. Valid range: 0.5°C to 20°C.

Stage 1 Threshold — PID output % at which Stage 1 activates. Default: 1%. Set this very low so Stage 1 (typically just a circulation fan) activates as soon as there is any cooling demand.

Stage 2 Threshold — PID output % at which Stage 2 activates. Default: 33%. Stage 2 typically represents a more significant cooling load like a refrigeration unit or chiller.

Stage 3 Threshold — PID output % at which Stage 3 activates. Default: 66%. Stage 3 is maximum cooling — a backup chiller, emergency fan, or alarm.

Sample Time — Default: 30000ms.

Note on Binary Actuators

The 3-Stage Cooling Controller is the one PID-based part that is specifically designed for binary (on/off) actuators. Each stage output is a boolean signal that turns a relay or smart plug on or off. This is the appropriate choice when you want staged escalation rather than continuous proportional control.


PID Tuning Guide

Tuning a PID controller means finding values for Proportional Band, Integral Time, and Derivative Time that make the controller stable and responsive for your specific system. Every system is different — a 10-litre grow tent heats and cools much faster than a 1000-litre fermentation chamber, so the same settings will not work for both.

Start With Proportional Only

Begin with integral and derivative disabled:

  • Set Integral Time to 9999
  • Leave Derivative Time at 0
  • Set Proportional Band to a value roughly equal to the maximum error you expect in normal operation

For a temperature controller targeting 25°C in a room that might reach 30°C on a hot day, start with a Proportional Band of 5°C.

Observe the dashboard after deploying. If the temperature oscillates (goes above then below the setpoint repeatedly), increase the Proportional Band. If the temperature approaches the setpoint very slowly and stops a few degrees short, decrease the Proportional Band.

Add Integral to Eliminate Droop

Once the system is stable with proportional control but sits a degree or two off setpoint, enable integral action:

  • Start with Integral Time around 500 (seconds)
  • If the system begins oscillating, increase Integral Time
  • If it takes too long to correct, decrease Integral Time

Derivative Is Usually Not Needed

For environmental control (grow rooms, fermentation chambers, HVAC zones), leave Derivative Time at 0. Derivative action amplifies sensor noise and can cause output chatter. It is mainly useful in systems that change very rapidly.

For a grow tent or small grow room targeting temperature:

  • Proportional Band: 2°C
  • Integral Time: 9999 (disabled)
  • Sample Time: 30000ms

For a fermentation chamber or glycol chiller system:

  • Proportional Band: 1°C to 3°C (thermal mass is high, system changes slowly)
  • Integral Time: 9999 (start disabled, add if needed)
  • Sample Time: 30000ms to 60000ms

For a mushroom fruiting room targeting humidity:

  • Proportional Band: 5%RH to 10%RH
  • Integral Time: 9999 (disabled)
  • Sample Time: 30000ms

For CO₂ ventilation in a grow tent:

  • Proportional Band: 200 ppm
  • Integral Time: 9999 (disabled)
  • Sample Time: 30000ms

When to Stop Tuning and Switch Controllers

If you have spent significant time tuning and the controller remains unstable, consider whether PID is the right tool. Binary actuators (smart plugs, relays) connected to PID outputs will always oscillate because the output signal cannot be meaningfully translated to partial power. Switch to a Hysteresis Controller in that case.

If the controlled variable (temperature, humidity) has very slow dynamics — taking hours to change — proportional-only control may be all you need. Do not add integral or derivative just because those settings exist.


Use Cases

Grow Tent with PWM Fan for Temperature

A small cannabis grow tent uses a Heat/Cool PID connected to a BME280 temperature/humidity sensor. The heat output drives a seedling mat through a PWM solid-state relay. The cool output drives a variable-speed inline fan through a PWM fan controller.

Settings: setpoint 24°C, proportional band 2°C, integral time 9999, sample time 30000ms.

The fan ramps up proportionally as temperature rises above 24°C, and the heating mat activates proportionally when it drops below. The dashboard shows both heat % and cool % in real time, making it easy to see which direction the controller is working.

Fermentation Chamber with Glycol Chiller

A 500-litre fermentation tank in a craft brewery needs to hold lager at 10°C during primary fermentation. A PT100 temperature probe reads the tank temperature. The cool output of a Heat/Cool PID drives the glycol pump through a 0–10V signal module (Sequent Microsystems 8-Layer HAT). The heat output is wired but unused (the cellar stays cold enough without supplemental heat).

Settings: setpoint 10°C, proportional band 1°C, integral time 9999, sample time 60000ms. A slow sample time matches the thermal mass of the tank — temperature changes over hours, not seconds.

The 3-Stage Cooling Controller is an alternative for systems where the glycol chiller has a fixed speed compressor and the only available actuators are on/off contactors for different compressor stages.


Troubleshooting

Dashboard shows "BAD PV" or the PID output is stuck at 0%

The PID controller is not receiving a valid sensor reading. In Node-RED, the PID node shows BAD PV (Bad Process Variable) when its input is missing or non-numeric. Common causes: the sensor has not published its first reading yet (wait 1–2 minutes after deploying), the sensor part is not wired to the PID input in the Configurator flow, or the sensor has an error (check the device health panel for offline indicators). Re-open the Configurator and verify that the sensor's output signal is connected to the PID input in the flow editor.

Temperature oscillates above and below the setpoint

The Proportional Band is too small. Increase it in the PID settings modal (under Tuning Parameters), then re-deploy flows. Start by doubling the current value. If oscillation continues, double it again. Once stable, you can reduce gradually to find the right level of responsiveness.

Temperature settles a few degrees off target (steady-state droop)

This is normal with proportional-only control. The controller reaches an equilibrium where the output is just enough to balance heat losses or gains, but that equilibrium point is not exactly on the setpoint. To eliminate this, enable integral action by setting Integral Time to a moderate value (300–1000), then re-deploy. Monitor for oscillation — if it occurs, increase Integral Time.

The actuator (smart plug / relay) is chattering — rapidly switching on and off

You have connected a binary (on/off) actuator to a PID output. The PID is continuously modulating its output, and the on/off actuator is trying to follow it by switching. This is the wrong controller for this actuator. Remove the PID part from your Configurator project and replace it with a Hysteresis Controller, which is designed for binary actuators.

Setting changes in the dashboard modal are not taking effect on the device

Setpoint changes take effect immediately. Tuning parameter changes (Proportional Band, Integral Time, Derivative Time, Sample Time) require re-deploying flows via the Deploy button. After saving tuning changes, open the Configurator and press Deploy.

The CO₂ PID is driving fans to full speed immediately after device boot

The MH-Z19 CO₂ sensor requires 3 minutes to warm up. During warm-up it may report very high CO₂ values, causing the PID to demand full ventilation. This is expected and resolves once the sensor stabilizes. Consider adding a startup delay in the flow if this is disruptive to your operation.


Known Issues

Tuning parameter changes (Proportional Band, Integral Time, Derivative Time, Sample Time) do not take effect until flows are re-deployed to the device. Setpoint changes are the exception — they write directly to the device via RTDB and are picked up by the running flow without a re-deploy.

The PID output display on the dashboard card shows the raw output from the controller node before the split function. For split-output controllers (Heat/Cool PID, Humidity PID), the card displays the split percentages separately. Opening the PID settings modal always shows the most up-to-date output value.

If you rename a room after deploying a flow that includes a PID controller, the PID's RTDB path changes and the dashboard card may show stale data until the new flow is deployed.


  • Hysteresis Controllers — for binary actuators (smart plugs, relays, contactors)
  • Actuators — compatible actuator parts for PID outputs
  • Wiring Flows — how to connect sensor and controller parts in the Configurator flow editor
  • Deploying to Pi — how to push a new flow to your device after changing tuning parameters
pidtemperaturehumidityco2controllerstuningconfigurator