- 01What the GridConnect library actually is
- 02The four function blocks
- 03Six control modes and what they do
- 04The assignment-operator trap (must read)
- 05The Simple vs Advanced power limit math
- 06Capacitor coordination — the 75% / 60s rule
- 07Tuning defaults that need to change
- 08Library vs custom ST — when to choose which
- 09Hybrid approach — use the library as a reference
- 10What one scan cycle actually does
- 11When it goes wrong — troubleshooting
01 — What the GridConnect library actually is
The GridConnect library is a free IEC 61131-3 library that ships with AcSELerator RTAC (SEL-5033). It is not a separately licensed product. You add it to a new RTAC project from the library manager, instantiate the function blocks, wire the inputs and outputs, and you have a working power plant controller. The current version at the time of writing is 3.5.1.0 and it requires RTAC firmware R143 or later.
The library is meant for utility-scale solar with PV inverters, optional battery storage inverters, and optional shunt capacitors. The whole thing is designed around regulating the point of interconnection (POI) between the plant and the utility. Every control loop runs on an internal evaluation interval that defaults to 5 seconds.
- Closed-loop control of power factor, reactive power (VAR), and voltage at the POI
- Power factor and voltage compensation modes (different from control modes — see Section 03)
- Active power limit with two algorithms: Simple and Advanced
- Frequency regulation using plant output or storage
- Capacitor switching coordinated with inverter VAR output
- Battery storage inverter integration with downramp support for cloud cover
The library does not handle the utility communications layer. You still configure the DNP3 outstation, the Modbus master to the inverters, and the POI measurement inputs separately in the AcSELerator project. The GridConnect blocks expect you to feed them clean tag values and wire their outputs back to your DNP3 / Modbus tags.
02 — The four function blocks
The whole library is four function blocks. Everything else is enumerations, helper types, and the connection logic that wires them together.
| Function Block | What it does | How many in a project |
|---|---|---|
fb_MasterPlantController |
The brain. Reads POI measurements, runs the PI loops, decides what setpoint goes to each inverter and capacitor. Holds all the tuning parameters, limits, and mode selection logic. | Exactly one per RTAC project. |
fb_PvInverter |
Interface to one PV inverter. Reads the live P, Q, PF, mode status and writes back setpoints. Knows when the inverter is offline, faulted, or in the wrong control mode. | One instance per inverter (or per logical inverter group on string-counted plants). |
fb_StorageInverter |
Same idea as fb_PvInverter but for a battery storage inverter. Supports charge and discharge directions, ties into frequency regulation and downramp control on the master controller. |
One instance per storage inverter. Optional if no BESS on site. |
fb_Capacitor |
Interface to one shunt capacitor bank. Handles on/off command pulses, fault status, and sequencing (which cap closes first when more VAR is needed). | One per capacitor bank, up to g_c_CAP_MAX. Optional. |
The way they connect is through pointers, not data copies. The master controller has an output called ConnectToPlantDevices that is a pointer. Every inverter and capacitor function block has a ConnectToMasterController input that you wire to that output. After that, the master controller reaches into each device block on its own internal cycle to read measurements and write setpoints. You do not have to manually shuffle data between them.
The master controller runs first, the device blocks run after with the pointer wired in. Order matters — if you call Inverter1() before MasterController(), the inverter is running on stale data for one full cycle.
03 — Six control modes and what they do
The master controller has six reactive-side control modes selected through the ControlMode input. Four of them are control modes (PI loop tries to drive the POI to a setpoint) and two are compensation modes (output follows a curve based on plant conditions).
| Enum value | Mode | What the PI loop regulates | Inverter must be in |
|---|---|---|---|
0 | Power Factor Control | POI power factor → PFControlSetpoint | PF mode |
1 | VAR Control | POI reactive power → QSetpoint | VAR mode |
2 | PF Compensation | POI power factor follows a slope vs plant kW | PF mode |
3 | Voltage Compensation | POI VAR follows a 4-point curve vs POI voltage | VAR mode |
4 | Voltage Control | POI voltage → VSetpoint (drives VAR ref to inverters) | VAR mode |
5 | Open-Loop PF Control | Pass-through — PF setpoint goes directly to inverters, no POI feedback | PF mode |
The thing that catches people the first time is that PF Control mode and Voltage Control mode talk to the inverters differently. PF Control writes to the inverter's power factor reference. Voltage Control writes to the inverter's VAR reference and ignores the inverter's PF mode entirely. If the inverter is in the wrong mode, the master controller tries to flip it through a periodic mode change control. If the inverter cannot be flipped, that inverter is marked unavailable and the others have to make up the difference.
This is in the manual but it's easy to miss. The compensation modes (PF Compensation and Voltage Compensation) do not observe the PFLagLimit, PFLeadLimit, VLimitHigh, VLimitLow, QLimitHigh, or QLimitLow settings. They are bounded by their own curve setpoints instead. If you forget this and rely on the lag/lead limits for protection, compensation mode can drive past those limits and you will not get an alarm.
Open-Loop PF Control (mode 5) is the fallback. When POI measurements go bad or your power meter drops out, the controller cannot run any of the closed-loop modes safely, so you fall back to passing the PF setpoint straight through to the inverters. The plant will not regulate at the POI but it will still respect the dispatched PF target. Wire your PlantMeasurementsGood input to a quality-check rollup and trigger mode 5 when it goes false.
04 — The assignment-operator trap (must read)
This is the single biggest thing that will burn you if nobody warns you in advance. The function blocks in this library are classes with internal memory allocated inside them, and copying them with the := operator either produces a compile error or, worse, silently breaks the data exchange between blocks.
The same rule applies in a more subtle way to function block inputs and outputs. You can not have a GridConnect class as a VAR_INPUT or VAR_OUTPUT in your own custom function blocks. If you wrap GridConnect blocks inside your own wrapper functions, you have to declare them in VAR_IN_OUT or pass pointers. The compiler will catch most of these with the same C0328: Assignment not allowed error, but some of them slip through and cause memory corruption at runtime.
There is also a scope rule. The classes have to be declared in permanent scope — Programs, Global Variable Lists, or VAR_STAT sections. You can not declare them inside a method or as locals that get destroyed between cycles. The internal memory allocation only works if the object lives for the whole life of the RTAC project.
05 — The Simple vs Advanced power limit math
The active power limit has three modes set through PLimitMode: NoLimit (output 100%), Simple, and Advanced. The Simple and Advanced modes both try to limit total plant output to PSetpoint but they handle the math differently.
Simple mode
Simple mode adds up the rated kW of every available inverter, calculates what percentage of the total is needed to hit the setpoint, and writes that same percentage to every inverter. If some inverters are online but flagged as uncontrollable (in local mode, faulted, or comms failed), the controller subtracts their actual current output from the setpoint and divides the remainder across the rest.
Example from the manual: 40 inverters at 500 kW each = 20 MW total rated. Setpoint is 15 MW. If 2 inverters are running but uncontrollable at 250 kW each, the math is:
Every controllable inverter then gets a power limit of 76.3% of its own rated kW. Simple mode does not handle cloud cover well — if half the plant is in a cloud shadow, the limited inverters can not actually produce 76.3% and you are leaving real power on the table.
Advanced mode
Advanced mode runs a PI loop on the POI power measurement. The setpoint is still PSetpoint but instead of doing the static percentage math, it watches the actual POI feedback and adjusts each inverter's limit to drive total output toward the target. If one inverter has unused capacity because its neighbor is in a cloud shadow, Advanced mode shifts the limit toward the available inverter.
Advanced mode has an anti-windup protection: if an inverter is not responding to setpoints, after InverterPLimitDelay (default 120 seconds, manual recommends at least 2x your inverter data update period) the controller clamps that inverter's limit to 115% of its present output. This prevents the loop from winding up the setpoint to absurd values while the inverter sits there ignoring it.
The manual is explicit: Advanced mode needs inverter data updates at least every 5 seconds, ideally faster. If your Modbus poll cycle is 10 or 15 seconds, the PI loop is running on stale data and you will see oscillation. On those slow plants, stick with Simple.
06 — Capacitor coordination — the 75% / 60s rule
If you have shunt capacitors at the substation, the master controller can switch them as part of the reactive control strategy. The logic is: inverters do the fine control, capacitors do the coarse control.
Specifically: when the controller calculates that more VAR is needed and the inverters are collectively at more than 75% of the rating of the next capacitor in the sequence for 60 seconds continuous, that capacitor closes. Once closed, the inverter VAR demand drops back down because the capacitor is now supplying coarse VAR.
Two settings constrain this:
CapacitorOperationPeriod(default 5 minutes) — the minimum time between any capacitor switching events. Prevents hunting.SequenceNumberon each capacitor block — determines what order the caps engage.0means "not dependent on others."1means "first to turn on, last to turn off."2means "only turn on if cap #1 is on." And so on up tog_c_CAP_MAX.
Sequencing matters when caps are different sizes or located at different points in the collector system. You want the largest fixed cap closing first to provide the bulk reactive support, then smaller caps trim from there. The library handles this correctly if you set the sequence numbers right.
07 — Tuning defaults that need to change
The library ships with PI tuning defaults that are intentionally conservative. They will not unwind your plant but they will not regulate tightly either. Here are the defaults and what I usually change them to on a typical 5–20 MW plant. Your mileage will vary — tune on the actual plant, do not trust generic numbers.
| Parameter | Library default | Typical starting point | Note |
|---|---|---|---|
QKp (VAR control) | 1 | 0.3 – 0.5 | Default is too aggressive on small plants. Causes overshoot. |
QKi | 0 | 0.03 – 0.05 | Default of 0 means proportional-only — you will get steady-state offset. |
PFKp | 1 | 0.2 – 0.4 | Same issue as Q — reduce gain on smaller plants. |
PFKi | 0 | 0 – 0.02 | Some plants tolerate a small integral. Many run fine with 0. |
VKp (voltage) | 1 | 0.2 – 0.4 | Voltage loop is the slowest. Be gentle. |
VKi | 0 | 0.02 – 0.04 | Default is too slow to recover from a voltage step. |
QDeadband | 250 kVAR | Plant-specific | 250 kVAR is way too wide on a 1 MW plant. Set to ~2–5% of plant Q rating. |
EvaluationPeriod | 5 s | 1 s | If your Modbus poll is fast enough, run the loop at 1 second. Better regulation. |
InverterPLimitDelay | 120 s | 2x your Modbus poll | Manual is explicit on this one. Set to at least twice the inverter data update period. |
The compensation modes use the same PI tuning parameters as their corresponding control modes. PF Compensation uses PFKp / PFKi, Voltage Compensation uses VKp / VKi. There is no separate tuning for compensation, which is unfortunate — compensation usually wants a slower response than control mode.
08 — Library vs custom ST — when to choose which
The library is a starting point. It is not the only way to build a PPC on the RTAC, and on a few project types I have written custom ST from scratch instead. Here is the honest trade-off.
Use the library when
- The plant is a standard solar PV + optional BESS layout with PV inverters that already expose PF / VAR / power limit mode controls over Modbus or DNP3.
- You need a working PPC fast and the utility has not asked for anything unusual.
- The integrator team is more comfortable with function-block wiring than with writing ST from scratch.
- The plant uses one of the IEEE 1547 / UL 1741 SA / SB control profiles that map cleanly to the six built-in modes.
- You want SEL TAC engineering support to be useful when something goes wrong. Library code is well-supported. Custom ST is on you.
Write custom ST when
- The plant has non-standard topology — multiple POIs, hybrid PV+wind, synchronous condensers, STATCOMs alongside inverters.
- The utility interconnect requires a control mode that doesn't fit one of the six library modes — e.g., a custom droop curve, a non-IEEE Volt-Var shape, or a market-specific frequency response curve.
- You need sub-second control on something the library evaluates on its 1–5 second cycle — e.g., fast frequency response on a battery, ride-through coordination with protective relays.
- You are tying the PPC into another control system (a microgrid controller, a hybrid plant controller, a utility-side device) and need to expose internal state that the library does not surface.
- You need to log or trend internal PI state for tuning or audit. The library's internal variables are not all exposed as outputs.
The middle ground — and what I do most often — is to use the library for the main reactive and active power loops, and write custom ST around it for the parts that do not fit. The library's fb_MasterPlantController exposes enough outputs (Enabled, PFOutOfBand, QOutOfBand, conditioned setpoints, ramp limits) that you can layer extra logic on top without modifying the library itself.
09 — Hybrid approach — use the library as a reference
Even on plants where I write custom ST from scratch, the library is useful as a reference for what the canonical PPC structure looks like. The control mode enumeration, the input list on fb_MasterPlantController, the way it handles inverter mode mismatches and unavailability, the capacitor sequencing rules — these are well-thought-out patterns that you can borrow without copying the code.
The Voltage Compensation curve is a good example. The library uses four (V, Q) points to define the curve, with linear interpolation between them and clamping outside the endpoints. That is also what IEEE 1547-2018 specifies for Volt-Var. If you write custom ST you should follow that same four-point structure even if your reasons for writing custom are about something else entirely.
The release notes at the end of the library manual are also worth reading. They tell you which control modes were added in which version, which bugs got fixed, and which behaviors changed. If you are inheriting a project from another integrator, check what library version they used before you change anything — the library has had behavior changes between versions, particularly around how mode 4 (Voltage Control) routes commands through the inverter VAR reference instead of the PF reference. Older projects that predate version 3.5 may be relying on the old behavior.
The library is a real tool, not a toy. It will run a production PPC on a utility-scale plant for years without intervention. The trap to avoid is treating it as a black box — you still need to understand what is happening inside, especially around the assignment-operator rule, the compensation-mode limit behavior, the Simple vs Advanced power limit math, and the capacitor 75% / 60s rule. Once you understand those, you can use the library where it fits and write custom ST where it does not, and the two coexist fine on the same RTAC.
← Back to the full SEL RTAC PPC design article
10 — What one scan cycle actually does
Everything in the GridConnect library runs inside one scan of the RTAC. The default evaluation interval is 5 seconds, meaning the function blocks skip their heavy logic on the intermediate scans, but every scan still reads inputs and writes outputs. Once the project is downloaded and the controller is in RUN, this sequence repeats forever:
- Input phase. AcSELerator runtime reads the tags mapped to the master controller's
PlantMeasurementsinput — POI P, Q, V, I, frequency, plus the per-inverter feedback values brought in by the Modbus master. These land as fresh values in the FB inputs before any user code runs on this scan. MasterController()executes. The first thing it does is checkPlantMeasurementsGood. If false, the mode auto-flips to Open-Loop PF Control (mode 5) — the PI loop is bypassed and the dispatched PF setpoint passes straight through to the inverters. If true, the selectedControlModeruns its PI loop against the live POI value and computes the next demand. The result is staged inside theConnectToPlantDevicespointer.- Device FBs execute, in declaration order.
Inverter1()runs, thenInverter2(), then storage FBs, then capacitor FBs. Each one reads its share of the staged demand through the pointer, applies device-local checks (offline, faulted, wrong control mode), and writes its setpoint to its own output tag. An inverter in the wrong mode triggers a periodic mode-change command rather than getting skipped entirely. - Output phase. The Modbus master pushes the new setpoints downstream on the next IO update; capacitor close/open commands fire to their relay outputs.
- Wait for next scan, then repeat.
If you call Inverter1() before MasterController() on any given scan, the inverter is operating on the previous scan's staged demand — one full cycle stale. At the 5-second default evaluation interval, that is a 5-second lag in the control loop, which shows up as visible voltage or VAR overshoot at the POI on a step setpoint change. On a plant that is already marginal on Modbus poll time, you can stack two staleness sources and the loop oscillates.
Three rules that fall out of this:
- Declare the master FB first in your main program, devices after. Always.
- Keep the master FB and all device FBs in the same program, same task. Splitting them across tasks breaks the pointer semantics.
- If you wrap the GridConnect FBs inside your own wrappers, the cycle order inside your wrapper has to preserve master-before-devices. Do not let a wrapper hide the ordering rule from the next person who opens the project.
11 — When it goes wrong — troubleshooting
Three failure patterns I have seen on plants running the GridConnect library. Each one is silent in the sense that nothing actually alarms — the symptom is wrong behavior, not an error message.
Symptom: VAR setpoint changes at the POI take 10+ seconds to act
What it looks like. You issue a Q setpoint step change from the utility-side SCADA. The inverter VAR command updates immediately on the RTAC tag display, but the POI VAR reading drifts for 10 to 15 seconds before settling. The plant looks slow to dispatch.
How to find it. Open the main program in AcSELerator RTAC and check the function-block call order. Confirm fb_MasterPlantController is the first instance called and every fb_Inverter is below it. Then check the evaluation interval — the default 5 seconds is the most likely culprit. Two adjacent scans plus a Modbus poll cycle stacks into the 10–15 second window you are seeing.
How to fix it. Drop EvaluationInterval on fb_MasterPlantController from 5 seconds to 1 second. Watch CPU load on the RTAC after the change — on a 3530 this is usually fine; on a 3505 it can push utilization above 70% if you have many inverters. If you cannot drop the interval, tighten the Modbus poll cycle on the inverter master to match.
Symptom: One inverter's VAR contribution stays at zero while the others ramp up
What it looks like. POI is short of its Q setpoint. The master controller is asking for more VAR. Inverters 1 through N all ramp up except one, which stays flat. No alarm. The diagnostic tag on the stuck inverter says it is online.
How to find it. The library will not dispatch to an inverter that is in the wrong control mode. Read the actual ControlMode register on the stuck inverter from the Modbus side (not from the RTAC FB output). Most likely the inverter is in local PF mode instead of the remote Q mode the library expects. This happens when a site tech changes the inverter to local mode to do something else and forgets to put it back, or when the inverter loses power and comes back up in its default local mode.
How to fix it. The library issues a mode-change command on every evaluation interval when it sees an inverter in the wrong mode. If that is not taking, check that EnableModeChange on fb_Inverter is true. Some sites disable that flag during commissioning and never re-enable it. The other place this hides: the inverter Modbus register map. Newer inverter firmware sometimes changes the mode register address, and the library's default register map can be one revision behind. Verify the register address against the current inverter manual.
Symptom: Capacitor banks switch on and off rapidly during cloudy weather
What it looks like. A cap bank closes, opens 90 seconds later, closes again, opens again. Switching count on the breaker climbs fast. Cap fuses start blowing within weeks.
How to find it. The 75% / 60-second threshold described in section 06 is a continuous-time check. If the plant Q demand briefly drops below 75% during a cloud passage and then comes back up, the library will not start the switching timer. But if your Q demand sits right at the threshold, you get cap-on-cap-off behavior driven entirely by cloud-induced Q oscillation. Look at the historian: plot Q demand for a cloudy afternoon and see whether it crosses the 75% threshold in both directions multiple times per hour.
How to fix it. Add hysteresis. The library does not expose a built-in hysteresis parameter, so the practical fix is to raise the close threshold (e.g. to 80%) and lower the open threshold (e.g. to 65%) so that the gap between them absorbs the oscillation. You can do this without leaving the library by adjusting the threshold inputs on fb_Capacitor. The other option is to gate the cap switching with a 5-minute moving average of Q demand, which means writing a small custom ST block that wraps the cap FB — the kind of hybrid approach section 09 describes.
When something on the GridConnect library does not behave the way you expect, do not start with the library code. Start by confirming the inputs the library is actually seeing — pull the POI measurement values out of PlantMeasurements, pull the inverter feedback registers, pull the ControlMode off each device. Three quarters of "library bug" reports turn out to be a measurement that is stale, a feedback register that is reading the wrong address, or an inverter in the wrong mode. The library does what it is told. The work is making sure what it is being told is real.