Commissioning has a smell. Hot electrical cabinets, cardboard dust, coffee gone cold at 2 a.m. And it has a sound I have learned to dread: silence on a conveyor line that should be moving.
Last week I was on a go-live in the Inland Empire — an 80,000-square-foot 3PL handling apparel returns, new WCS going in against an existing conveyor controls setup. A pallet sat dead at a divert. The WCS monitor said, in bright green letters, "RELEASED." The controls engineer at the PLC cabinet stared at his I/O lights and said, "We never got the release."
We lost two days to that pallet. The root cause was almost embarrassing: the WCS programmer was working from revision 7 of the signal table. The PLC in the field was running revision 9. Somewhere between the two, the site crew had re-pulled wire twice and added two photoeyes, and nobody updated the table. The release request landed on a spare address that meant nothing to the PLC program. Nobody was listening on that channel.
In twenty years I have watched this movie a dozen times. The hardware is fine. Both software packages are fine. What kills the integration is the document in between — the I/O signal table. Here is how I build one that doesn't come back to haunt me.
Sort Every Signal Into Three Buckets Before You Open Excel
The rookie mistake is opening a spreadsheet and typing row after row until you have a hundred signals and no idea what half of them do. I sort first, then list.
Bucket one: commands, WCS to PLC. Start, stop, release, reset, mode change. A command that needs no reply is a command I delete — if the PLC doesn't have to answer, you have nothing to troubleshoot when it goes wrong at midnight.
Bucket two: states, PLC to WCS. In position, running, faulted, e-stop, manual/auto mode. States are read-only. The WCS looks; it never writes. Plenty of projects die right here, when a WCS programmer takes a shortcut and writes directly to a status bit the PLC owns. Two writers, one bit, signals flickering at commissioning, and the bug turns out to be friendly fire.
Bucket three: heartbeat. The WCS toggles a bit every second or two; the PLC toggles one back. Each side watches the other's pulse and alarms when it flatlines. This is the cheapest insurance on the whole table, and the one most often value-engineered out. The argument is always the same: "the network switch will alarm if the link drops." A switch alarm tells you the cable is down. A heartbeat tells you whether the machine on the other end is alive, dead, or brain-dead with its program hung. Those are different facts, and at 2 a.m. the difference matters.
Take "release one pallet" as an example. You need exactly four signals: release request (WCS to PLC), request received (PLC to WCS), release complete (PLC to WCS), plus the heartbeat. Four signals, one job, ownership crystal clear. Any row on the table that can't answer "what is this for, who writes it, who reads it" gets deleted. A signal table is not better when it's longer. Every unmaintained signal is one more suspect when commissioning goes sideways.

The Three-Step Handshake, and Why Two Steps Will Burn You
My timing diagram has three steps and I don't negotiate on this. The WCS sets "release request." The PLC sees it and sets "request received." The PLC executes the release, the pallet arrives, and the PLC sets "release complete." The WCS sees "complete" and resets "request." The PLC sees "request" go away and resets "complete." Full circle, back to a clean idle state.
Why three steps? Because I have personally paid for both shortcuts. Shortcut one: the WCS fires and forgets. The request goes out, the PLC misses it on a signal bounce, the pallet never releases — but the WCS thinks it did and dispatches the next task. The whole line jams. Shortcut two: the PLC acts but never reports back. The release happened, the WCS doesn't know, it times out and re-sends the request, and the same pallet gets released twice. The divert downstream becomes a demolition derby.
The point of the three-step handshake is a closed loop: nothing advances until the previous step is confirmed, and nothing resets until the reset is seen. There is a bonus nobody talks about. If either side loses the network or hangs, the handshake freezes mid-step — visibly, loudly, with an alarm. Frozen is fine. What kills you is the silent failure, the one you discover three pallets later when the damage is already done.
The Pre-Commissioning Checklist I Run on Every Site
Table done, code written — don't go to full-line integration yet. Run these single-item tests first. They save roughly half the tears on commissioning night.
Debounce first. Photoeyes and proximity switches bounce on the mechanical edge. A few dozen milliseconds of input debounce in the PLC program is table stakes. And the WCS side shouldn't trust a single scan either — require two consecutive scans before accepting a state change. Bounce is invisible in testing and shows up exactly when volume peaks.
Audit the addresses. Take the table and walk every signal against the actual address in the PLC program, one by one. Field re-wiring and last-minute additions happen on every project; the table revision and the program revision must match. My rule now: the table carries a revision number, and that number appears in both the PLC program comments and the WCS configuration. The revision-7-versus-9 disaster from my opening story is exactly what this prevents.
Pull the cable. Unplug a network cable and time how long the WCS takes to notice the PLC is gone — that's your heartbeat test. Hit the e-stop and verify the "e-stop" state the WCS sees matches what the machine actually did. One principle here: the e-stop circuit itself runs on hardwired safety relays. The "e-stop status" sent to the WCS is only a mirror. Never hang a safety function on a software signal.
Test the mode signal. When the PLC goes to manual, the WCS must know — and must stop dispatching tasks. I once watched a WCS keep sending releases while a technician was jogging the conveyor by hand. A pallet got shoved out by a release command nobody expected. Nobody was hurt, but it was luck, not design. Mode is a safety item, not an option.
Then soak it. Two hours of continuous running, with a random e-stop, a random network drop, and a random manual intervention thrown in. Commissioning time is the most expensive time on the project. Rehearsing the failures beats performing them in front of the customer.
If you're walking onto a commissioning site tomorrow, bring one thing: a printed signal table, signed by both sides, revision number matching the code. That alone blocks half the failure modes. The checklist above handles the rest, one item at a time.





