A scan button on an HMI works only while a client session is open and an operator is there to click it. A PLC tag event has neither: it fires in the controller, mid-cycle, whether or not a browser is logged in. The fix is not a script function on a roadmap — it is moving the trigger to the device that owns the lens. A fixed code reader or smart camera fires its decode from a discrete input, a serial command or a TCP command, runs with no session at all, and hands the string back to the PLC. Below you get the three trigger paths with their wiring, a field-of-view example with the arithmetic shown, a trigger-to-result latency budget, and the commissioning checks that prove the scan runs headless.
Why the button cannot carry a tag event
Browser-based HMI clients capture the image inside the session. Close the tab, log out or hit a session timeout, and the button has no camera to call and nothing that runs. A tag-driven event is the opposite case: the controller decides a scan is needed while nobody is watching. The two never meet, which is why the scan keeps failing exactly when production asks for it.
The principle is the same in HMI scripting everywhere: put the action where the event lives. A script action fired by a tag change instead of a button runs with no client open, and that is the move to make here. The reader becomes the scanner; it watches its own discrete input or socket instead of your operator.
If the current design scans through a phone camera or a web page, the decode lives in whoever happens to have the page open — the web-scanner versus vision-decoder path problem. A headless fixed code reader ends it: it decodes on its own clock and reports to whoever asks, client or no client.
Choose the trigger path
Three paths fire the scan, and the result usually returns over the same medium:
| Path | The PLC fires the scan by | Result returns by | Pick it when |
|---|---|---|---|
| Discrete input | A photoeye or spare output pulses the trigger input | Ethernet, serial, or the reader's outputs | The station has a stop position or photoeye; timing must be deterministic |
| Serial command | A short trigger string on a spare serial port | The same serial port | Legacy line with no spare switch port |
| TCP command | The PLC connects as a client and writes the software-trigger command | The same socket | The reader already sits on the plant network |
| EtherNet/IP assembly | A trigger bit in the output assembly | Result words in the input assembly every RPI | The PLC talks EtherNet/IP and you want tag-level access |
Discrete is the default for a stopped station. A photoeye or spare PLC output pulses the reader's trigger input, and timing stays deterministic because no socket stack sits in the path. Set the mode in the reader's trigger settings and leave free-run off; the trigger-mode trade-offs cover that choice. If a serial trigger goes silent, the cause is usually framing or command case, which the serial trigger diagnosis walks through.
TCP fits when the reader is already on the network. Wire the reader as TCP server with the PLC as its client and take the result back over raw sockets without EtherNet/IP; both patterns are step-by-step guides. For an EtherNet/IP PLC, put the trigger bit in the output assembly and read the result words every RPI, as the implicit I/O assembly mapping shows.
Smart cameras take the same idea one string further: an ASCII command over TCP starts the whole job, per the smart camera TCP trigger guide. When the station must also inspect — label present, cap colour, seal position — one smart camera does decode and inspection on one trigger. One device, one trigger, both answers:
- Interface
- GigE
- Resolution
- 6-10 MP
- Sensor format
- 1/2.4"
- Shutter
- Rolling
The MV-SC5060XM-08M-WBN pairs a 6 MP mono sensor with an 8 mm lens on an M12 mount and carries the job on a GigE link. Its rolling shutter suits a stopped-line trigger; parts moving under the lens want a global shutter instead.
Size the field of view before you mount it
The trigger makes the reader fire; the optics decide whether the decode succeeds. Two numbers set the mount height: working distance and field of view.
Worked example at a 100 mm working distance with an 8 mm lens on a sensor about 7.4 mm wide (the 1/1.7" type): FOV = 100 × 7.4 / 8 ≈ 93 mm. The pixel footprint on the part is 93 / 2560 ≈ 36 µm per pixel. A DataMatrix decodes reliably from three pixels per module, and four to five is comfortable, so this mount reads modules down to 3 × 36 ≈ 108 µm, call it 0.11 mm. Move the reader out to 150 mm and the same lens gives a 139 mm field, 54 µm per pixel and a 0.16 mm module floor. Check the smallest code you must read against that number before the bracket is machined.
Put those figures on a head you can buy. The LS-CRD-0028 pairs a 2560 × 2048 global-shutter sensor with an 8 mm lens, a 1/1.7" format and a 60 codes/s decode rate on Fast Ethernet:
- Interface
- Fast Ethernet
- Resolution
- 5 MP
- Sensor format
- 1/1.7"
- Shutter
- Global
Distance bands, close range to mid:
- Resolution
- Up to 3 MP
- Shutter
- Global
- Interface
- Fast Ethernet
- Resolution
- Up to 3 MP
- Interface
- Fast Ethernet
- Resolution
- Up to 3 MP
The LS-CRD-0047 reads at a 60-120 mm reading distance over USB 2.0, for a bracket-mounted head right at the part. The MV-IDB005EXI-05NRP focuses at 70 mm with a 4.63 mm lens and polarized light, made for shiny or film-wrapped codes. The MV-ID3013PM-12M-WBN carries a 12 mm lens at 1.3 MP, for a tighter field at a longer stand-off.
Wire and configure the tag-driven decode
- Mount at the computed working distance and confirm the field covers the code plus placement tolerance and skew.
- Run the trigger cable you chose: photoeye or spare output to the discrete trigger input, a spare serial port, or a reserved TCP port on the plant network.
- In the reader's trigger settings, select the matching trigger mode — external input, serial command or software command — and turn free-run off.
- Write the trigger as a one-shot in the PLC: fire on the rising edge of the part-present or inspect-now tag, never on the level.
- Configure the result path so every scan returns a verdict: the string on a read, a defined no-read marker or timeout on a miss.
- Add the PLC-side handshake: a 500 ms result timer, one retrigger on the first miss, an alarm on the second.
- Force the tag from the PLC with a known-good part under the lens and time the trigger-to-result interval.
- Close every HMI client and force the tag again. The string must still land in the PLC; if it does not, a trigger still lives on the client side.
The logic that runs in the PLC or gateway, in plain shape:
bool partPresent = false; // rising edge = part stopped under the reader
bool waiting = false; // TRUE between trigger and result
int noReadRun = 0; // consecutive no-reads on one part
on partPresent rising edge:
waiting = true
start result timer at 500 ms
fire the software trigger at the reader // discrete path: pulse the trigger input instead
on result received:
waiting = false
if string is empty or equals the no-read marker:
noReadRun = noReadRun + 1
retrigger once if noReadRun = 1, else raise the no-read alarm
else:
noReadRun = 0
write string to the recipe tag
The proof is step 8 with a stopwatch: forced tag, all clients closed, string in the PLC register inside the latency budget below.
The trigger-to-result latency budget
Budget the scan like any other I/O term in the cycle. At a stopped station on Fast Ethernet the pieces are:
- Exposure: 10 ms with strobed light on a stopped part. Dim light stretches this term directly.
- Decode: about 17 ms, which is 1000 ms / 60 at a reader sustaining its rated 60 codes/s. A pallet of codes multiplies this term.
- Network and stacks: about 3 ms for a short TCP result string on a 100 Mbit/s link. A discrete trigger trims most of this.
- One PLC scan: about 5 ms at a mid-range task class.
Thirty-five milliseconds is the expectation; 100 ms is the budget you sign up to. Measure the real interval instead of trusting either — the scan-to-flag timing method times exactly this chain end to end.
Handle no-reads so the line never waits on silence
A trigger without a result is the failure that stops lines. Give every miss a defined answer: configure the reader's no-read output or timeout string so the PLC always receives something inside the timer window. Retrigger once on the first miss, alarm on the second, and count no-reads per shift in a tag the supervisor already watches. Clusters on one batch point at print quality or a module size under the pixel floor from the field-of-view example — not at trigger wiring.
Most tag-driven decodes feed a lookup: recipe select, pallet ID, unit trace. The string lands in a tag, and the PLC recipe lookup pattern with UDT arrays turns it into the right job. Shiny or wrapped codes that no-read in clusters want the polarized head from the distance row above before any exposure tuning.
Checks before you order
- Field of view at the real mount height. Rerun the FOV arithmetic with your distance; the smallest module must hold three pixels or no trigger scheme saves the decode.
- Trigger medium with a spare in the panel. A dry contact, a serial port or a switch port; a tight takt wants the discrete path.
- A result path that speaks the PLC's language. Raw TCP, serial frame or implicit I/O assembly, decided before the panel build.
- A defined no-read marker and one retrigger. Silence reads like a broken cable at the worst hour of the shift.
- Polarized optics for shiny or filmed codes. Glare no-reads at any exposure; the optics cost less than the downtime.
- A session-free acceptance test. Close every client, force the tag, watch the string arrive — that test is the entire point of the design.
Next step
Pick the distance band from the heads above, check your smallest module against the three-pixel floor, and filter the camera finder by interface and resolution to shortlist readers. The trigger step of the system configurator collects the trigger, network and mounting choices in one pass, and the code-reading topic page gathers the handshake patterns that come after this one. If the code is unusual or the takt is tight, tell us the part and the cycle and we will spec the head with you.
Questions
Will the reader still decode with every HMI client closed?
Yes. The trigger lives on the reader, not in a client: a pulse on the discrete input, a serial command from a PLC port or a TCP command from a PLC socket starts the scan, and the decode string returns over the same link. The HMI only subscribes to the result tag afterwards, so operators see codes whether or not a session is open.
How fast is a tag-driven scan end to end?
Budget 100 ms and expect roughly 35 ms at a stopped station: 10 ms exposure with strobed light, about 17 ms decode at a reader sustaining 60 codes/s, about 3 ms of network and stack, about 5 ms of PLC scan. Discrete triggering removes most of the network term, so its worst case sits at the low end.
Which trigger path should I pick first?
Discrete input when a photoeye or spare PLC output is within cable reach: deterministic timing and no socket stack in the path. TCP command when the reader already sits on the plant network and you cannot pull cable. Serial when a legacy PLC has a spare port. All three run with no session open.
Is free-run mode faster than a triggered decode?
No. Free-run decodes every frame whether or not a part is present, spending the reader's rated decode rate on images nobody asked for. It can also hand the PLC a stale code from the previous part. A triggered decode yields exactly one result per tag event, which keeps the PLC handshake a simple one-shot.
What should the PLC do when the code will not decode?
Expect a defined answer, never silence: configure the reader's no-read marker or timeout string, run a 500 ms result timer, retrigger once on the first miss and alarm on the second. If no-reads cluster on one batch, suspect print quality or a module size under the three-pixel floor before touching exposure.




