An engineer knew a 24 V output told an upstream conveyor it was safe to feed. They did not know the tag, the routine, or the conditions, and the answer crossed a controller boundary. They had been searching for eight minutes when they asked, which gave the session a measured baseline.
How does this belt tell the upstream flex conveyor it is OK to feed? It is a 24 V output we send to a flex on a different controller. I know the signal exists. I do not know the tag name, the routine, or what makes it true.
The engineer had been hunting for eight or nine minutes when they asked, and had not found it. That is what makes this session worth writing up: the comparison has a measured human baseline on one side, and both sides were working the same question against the same file.
This is also the shape of most break-fix questions. Not "explain this rung" but "somewhere in here is the thing I am describing, find it." The published answer had to survive the engineer opening their own editor and checking it, so every claim below carries a program, routine, and rung number.
What the engineer had to go on
One belt number and one sentence of plant context: this belt is fed by a flex conveyor on another controller, and we send that flex a 24 V signal telling it we can accept.
Nothing was pasted in. No tag name, no routine name, no program scope, no rung. The tag the engineer was looking for could not be searched for directly, because not knowing its name was the entire problem.
The material was a 112 MB full-controller export taken offline. No live connection to the controller was involved at any point in this session, which matters for reproducibility: the same export produces the same trace, and the trace can be rerun by anyone holding the file.
Finding the output: one search on the belt number
The only searchable handle in the question was the belt number, so that is what got searched. It surfaced the rung that writes the output on the first pass:
AREA_12 / MC02_Inbound, rung 6
XIC(BELT_4100.CHG_EN) OTE(FLEX_FEED_EN_5)The output is FLEX_FEED_EN_5, and it is gated by exactly one thing: the belt's own charge-enable bit. One condition, one output. The rung is almost trivially simple, which is precisely why it is hard to find by guessing at names. There is nothing distinctive in it except the belt number.
Searching the thing you know rather than the thing you want is the move here. The belt number appears in tag names across the project, and one of those appearances is an input to the rung that writes the signal the engineer was describing.
Proving the signal leaves the controller
Finding a plausible output is not the same as proving it is the one going out on a wire. A project-wide cross-reference on FLEX_FEED_EN_5 returned exactly one reference in the entire export: the output instruction above.
Written once. Read nowhere.
That is what a hardwired discrete output to another controller looks like from inside the logic. If the signal were consumed anywhere in this controller, the cross-reference would show it. If it were passed to the other controller over the network, there would be a produced or consumed tag or a message instruction carrying it. Neither exists. The only remaining path for that bit to affect anything is a physical terminal, which is exactly what the engineer said they had.
The negative result is the load-bearing one here. A single-hit cross-reference proves the absence of software consumers, and absence is what turns "here is a candidate output" into "here is the output."
What makes the permit true
Following the charge-enable bit into the stock OEM conveyor drive instruction returned the rung that writes it, inside the instruction body:
Conveyor drive instruction body, rung 8
XIC(MTR) XIC(AUX) [AUTO_MODE | MNT_MODE] [charge-enable timer] OTE(CHG_EN)Four conditions, all of which must hold:
| Condition | In the rung | What it means on the floor |
|---|---|---|
| Motor commanded | XIC(MTR) | The drive has been told to run |
| Running feedback present | XIC(AUX) | The drive is actually running, not just commanded |
| Zone in automatic or maintenance mode | AUTO_MODE or MNT_MODE | Not stopped, not in a mode where the zone is off |
| Charge-enable timer satisfied | The timer bit | A short up-to-speed dwell before the permit is granted |
In plain terms, the flex conveyor is told to feed only while this belt is genuinely running in auto, and only after it has been running long enough to accept product. The timer is the difference between "the motor has been commanded" and "the belt is moving at speed," and it is the condition an engineer reading only the call site would never see.
Crossing into the instruction body is the step that takes the longest by hand. The call site and the body are separate parts of the export, and the parameter names inside the body are not the tag names outside it. Every argument has to be mapped back manually.
The handshake the whole line runs on
The same instruction call on rung 6 passes the downstream belt's charge-enable bit in as this belt's discharge permit. The downstream belt's charge enable is this belt's permission to discharge, and the chain continues down the line, belt to belt.
Every belt tells its upstream neighbor it can accept, in software, through that argument. This one belt is the exception, because its upstream neighbor is not another belt on this controller. It is a flex conveyor on a different one. So its charge enable leaves software and becomes a physical 24 V output.
That is the mental model the engineer was missing, and it is one paragraph long. Once you have it, the single odd output stops being odd. It is the same handshake as every other belt on the line, expressed in copper because the neighbor is out of reach.
The evidence, item by item
| Claim | How it was verified | Citation |
|---|---|---|
The feed permit output is FLEX_FEED_EN_5 | Search on the belt number surfaced the writing rung | The inbound routine, rung 6 |
| The permit is gated by the belt's charge enable | The single input condition on that rung | The inbound routine, rung 6 |
| The signal is a hardwired output, not a software one | Project-wide cross-reference returned 1 reference, the write | Whole-export cross-reference |
| Charge enable requires four conditions | Traced the bit into the drive instruction body | Drive instruction body, rung 8 |
| The discharge permit comes from the downstream belt | Argument mapping at the instruction call | The inbound routine, rung 6 |
| No controller was touched | Offline export only | 112 MB controller export |
Every row came back with the verbatim rung text attached, so the engineer confirmed the whole chain in their own editor in seconds rather than taking it on trust. That property matters more than the speed. A fast answer you have to believe is worth less than a slower one you can check, and this one is both.
What the manual version costs
The manual version of this question is not hard. It is slow, and it is slow in a way that does not reward experience much.
Start with the file. A full-controller export at 112 MB is one XML document. Text search across it will find the belt number, and it will also find it in tag declarations, in comments, in descriptions, and in every other routine that references the same belt. The hits come back unranked and undifferentiated, and the rung that writes the output looks no different from the fifty that mention the belt in passing.
Then guess at a naming pattern. The engineer does not have the tag name, so the alternative to reading every hit is guessing what a feed permit to a flex conveyor might be called at this site and searching for that instead. Guesses that miss are indistinguishable from the tag not existing.
Then cross-reference the candidates. For each plausible output, confirm what writes it and what reads it. The editor's own cross-reference is good at this, once you have a tag name to give it, which is the thing you are trying to find.
Then cross the instruction boundary. The permissives are not in the routine, they are in the instruction body, in a different part of the file, under parameter names rather than tag names. Mapping the arguments at the call site back to the parameters inside the body is manual and it is where attention goes.
Then prove the negative. To say "this is the hardwired output" rather than "this might be," you have to enumerate every reference to the tag and find nothing reading it. That is a confirmatory step with no shortcut and no partial credit.
The engineer had eight or nine minutes into that sequence, on their own count, and had not finished. The traced version returned the output, the permissives, and the handshake topology in about twenty seconds with rung citations on every claim.
Roughly 25x, on a question that lives entirely inside the export. The multiple is calculated against a baseline that had not yet produced an answer, so it understates the real gap rather than flattering it. It is also the only honest way to state it: the manual side was stopped, not completed.
The part that generalizes
This question crossed a controller boundary, and the answer depended on recognizing that it did. A tool that reads one export in isolation has to reason explicitly about what leaves the file, otherwise a write-once tag looks like dead logic instead of a wire. The same boundary reasoning is what makes cross-controller work hard for people, and it is discussed further in what an AI can and cannot read out of PLC code.
The handshake pattern here, what feeds me and what I feed and the permits between them, is one of the most common questions on a conveyor line, and the argument mapping at the instruction call site already contains the whole answer. Most of the eight minutes went into recovering work that the call site had already done and the export had never lost. That is the general case for deterministic retrieval in Nexus: the facts are in the file, and the cost is entirely in getting them out.