SKW EnergyOS
EC fans7 min read

Reading and controlling an EC fan over Modbus: the registers, the loop and the mistakes

What a typical EC fan exposes on Modbus — rpm, setpoint, bus volts, current, temperature, fault — how a static-pressure loop should drive it, and the three errors we see most often in the field.

Everything in this series came from six Modbus registers. This post is about those registers: what they are, how a controller should use them, and what goes wrong.

A control loop: sensor to controller to actuator to process, with feedback from the process back to the sensor
Every HVAC loop. For the supply fan: the sensor is duct static pressure, the actuator is fan rpm.

The registers that matter

  • actual_rpm (read) — what the rotor is doing. The feedback for any speed loop and the sanity check on every command.
  • setpoint_rpm (read/write) — the command. On some fans it is a percentage or a 0–10 V equivalent instead of rpm; check the manual for the scale.
  • bus_v_raw (read) — DC-bus voltage, 1 V per count on this fan. Power-quality and health signal.
  • current_raw (read) — DC-bus current, 0.01 A per count. Multiply by bus volts for power.
  • ipm_temp_c (read) — inverter heat-sink temperature. Thermal health.
  • faulted (read) — the drive's fault flag; usually paired with a fault-code register that says why.

Register addresses and scales differ by manufacturer — ebm-papst, Ziehl-Abegg, Rosenberg and others each publish their own map. The quantities are the same. The first job on any new fan is to confirm the scales from physics, the way the DC-bus post did, before trusting a single number.

The loop

A supply fan on an AHU is usually controlled to hold a duct static-pressure setpoint: a sensor in the main duct, a controller comparing it to the setpoint, and the fan rpm as the actuator. The static setpoint is itself a number worth optimising — too high and every VAV box throttles against it and the fan wastes power; too low and the farthest zone starves. That is why our system writes the static setpoint and lets the AHU's own loop drive the fan: the fan loop stays local and fast, and the optimisation stays one level up.

Three field mistakes

  1. Writing too often. The step test showed this fan takes 18–45 seconds to land on a new speed. A loop that writes every 5 seconds is always chasing a moving target. Match the write interval to the actuator — tens of seconds for a fan — and validate against actual_rpm before the next move.
  2. Ignoring the fault flag's context. A fault with a bus sag is a mains event. Logging bus voltage alongside the flag turns 'fan keeps faulting' into 'the feeder dips at 20:25 every night'.
  3. No bounds on the write. An EC fan will happily accept 299 rpm or 100% from any controller on the bus. Every setpoint write should pass a hard minimum and maximum before it leaves the controller — and on a BACnet system, sit below the operator's priority so a human can always override it.

Where this goes

Six registers from one fan produced power without a meter, a fault diagnosis without a site visit, a measured fan-law exponent and a ramp-rate for the control loop. Multiply by every fan in the building and you have the telemetry layer an autonomous controller runs on. The integration reference describes how that layer connects to the BMS; the product tour shows what it looks like once it is running.