Code readingHow-to

Read a code once: stop after the first good read

Stop a code reader once: end after the first good read by stopping the stream, gating the callback, switching to trigger mode or a PLC handshake.

LumaSpec Vision10 min read Share on LinkedIn

On this page 11 sections
  1. 01Why the reader fires again on every frame
  2. 02Pick the method that fits the station
  3. 03Method 1: stop acquisition in the success branch
  4. 04Method 2: gate the callback with a done flag
  5. 05Method 3: run on hardware trigger, one read per part
  6. 06Method 4: let the PLC own the read cycle
  7. 07Worked example: duplicate window for a 30 fps reader on a 2 s dwell
  8. 08Verify the count: one part, one read
  9. 09Common mistakes
  10. 10Which method for your case
  11. 11Questions

A code reader in continuous mode does what it is built to do: it decodes every frame that arrives. While the code sits in the field of view, every frame is another result, and your PLC, database or stack light sees dozens of reads for one part. This guide is for anyone wiring fixed code readers, vision sensors or smart cameras to a line who needs one accepted read per part. You will choose among four ways to stop the repeats, set up the one that fits your station, and verify that the count lands on exactly one.

Why the reader fires again on every frame

The decoder is stateless. It holds no memory of the last result, so a code that stays in view is simply a code in every new frame. At 30 fps that is a fresh image every 33.3 ms, and datasheets quote decode throughput in codes per second precisely because free-run reading is the default. The repeats are not a fault you can tune out of the decoder; they are what continuous acquisition means. The fix lives one level up: define an acceptance policy of one validated result per part, and suppress everything after it. Which frame counts as the read is a validation question — symbology, string format, grade — the same one behind judging whether a decode is trustworthy.

Pick the method that fits the station

Method What it stops Effective within Fits
Stop acquisition in the success branch the frame stream about one frame interval (33 ms at 30 fps) PC and UI applications where the part stays in view
Done flag checked first in the callback your processing only the next callback streams that must keep running for logs or a second tool
Hardware trigger, one shot per part the reads themselves the trigger edge discrete parts with a sensor; lowest light and CPU load
PLC handshake, command and done bits who accepts the result one PLC scan PLC-owned cycles with no-read handling

Rules of thumb. If nothing else needs the frames, stop the stream. If the stream must run, gate your callback. If parts arrive one by one past a sensor, trigger. If the PLC owns the cycle, handshake. On a production line the last two combine: the trigger delivers the frames, the handshake decides acceptance.

Method 1: stop acquisition in the success branch

  1. Validate the decode first: correct symbology, expected string format, passing grade. Only a result that survives this counts as the read.
  2. In that same success branch, call the SDK's acquisition stop — the call that halts the stream — before any UI, database or PLC action.
  3. Copy the decoded string, grade and timestamp into your own variables, then hand them to the rest of the application.
  4. Restart acquisition only on the next cycle: a new-part signal, an operator reset or the next trigger.

Frames already exposed when you call the stop can still land in the queue. At 30 fps that is at most one more callback, and it finds the gate closed. If your processing lags acquisition, the backlog runs longer than one frame; fix that gap first, as in fixing the frame-rate gap between acquisition and processing.

Method 2: gate the callback with a done flag

When the stream must keep running — the same frames feed an image archive or a second tool — leave acquisition alone and gate your own logic.

  1. Declare done as a boolean initialized to false, next to the reader handle.
  2. First line of the callback: if done is true, return or re-queue the buffer, and touch nothing else.
  3. On a validated result, set done to true, then run your actions.
  4. Reset done to false only on the next cycle edge, never on a timer alone.
done: bool = false

on_frame(frame):
    if done: return            # suppress every callback after the first
    result: string = decode(frame)
    if is_valid(result):
        done = true            # first good read wins
        handle(result)

The test that proves it: hold one code in view for ten seconds. handle executes once, the callback counter keeps climbing, and done blocks the rest.

On a smart camera the gate lives on the device, so suppression survives a network hiccup. The MV-SC5060XM-08M-WBN, for instance, runs its inspection on a 6 MP mono sensor with an 8 mm lens over GigE — the whole loop stays at the camera.

Smart cameras & vision sensorsHikrobot MV-SC5060XM-08M-WBN SC5000X series Smart Camera, 6 MP, Mono, 8 mm focal length, M12-mountMV-SC5060XM-08M-WBN
Interface
GigE
Resolution
6-10 MP
Sensor format
1/2.4"
Shutter
Rolling
$1,629.00View part

The cost is that illumination and decoder stay loaded between reads. Strobe the light through a controller so the LEDs fire only while the gate is open; the light controllers category lists strobe-capable units.

A 4-channel, 200 W digital controller with strobe over RS-232, such as the LS-CTL-0070, keeps the light dark until the gate opens.

Light controllersDigital control box, 4 ch, 200 W, RS232 (LS-CTL-0070)LS-CTL-0070
Output
Constant voltage 24 V
Channels
4 channels
Control
Digital
Feature
Strobe
$549.00View partBuild a system with it

Method 3: run on hardware trigger, one read per part

Wire a photoelectric sensor or a PLC output to the reader's trigger input. One edge then yields one frame: no trigger, no frame, no decode, no light. This removes duplicates at the source instead of filtering them afterwards.

  1. Set the acquisition mode to match. The classic trap is a pulsing trigger line ignored because the device still free-runs, as in a GigE camera that ignores its external trigger.
  2. Re-arm after each accepted read. Single-shot acquisition delivers exactly one frame per arm — read-once behavior from the hardware itself, as covered in a hardware trigger that stops after one frame.
  3. If the station also archives an image per part, take the whole set from the same trigger rather than free-running, per multiple captures per trigger.
  4. Strobe the light on the trigger edge so illumination duty follows the read rate.

Compact Fast Ethernet readers such as the MV-ID3013PM-12M-WBN — 1.3 MP, 12 mm lens, M12 mount — suit tight stations in this arrangement.

Fixed code readersHikrobot MV-ID3013PM-12M-WBN 12mm focal length 1.3 MP Compact Industrial Code ReaderMV-ID3013PM-12M-WBN
Interface
Fast Ethernet
Resolution
Up to 3 MP
Shutter
Global
Lens mount
M12
$1,979.00View part

Method 4: let the PLC own the read cycle

On a PLC-owned line, the reader should no more decide when to read than a proximity switch decides when to count. Handshake it:

  • The PLC sets a command bit on part-present.
  • The reader reads once — gated or triggered as above — writes the string to the result register and sets a done bit.
  • The PLC takes the result and clears the command in the same scan; the reader clears done and re-arms.
  • Edge-trigger the command: a read on the rising edge, never on the level.

Clear the handshake bits once at power-up — a first-scan-bit reset at startup does exactly this — so a command latched from the previous shift cannot fire a phantom read. If the camera also waits on a ready gate, a stale gate swallows the first images after load; check the ready-gate fix. Plan the link itself — protocol, timeouts, retries — with the barcode reader to PLC communication plan.

Worked example: duplicate window for a 30 fps reader on a 2 s dwell

Inputs. The reader is the LS-CRD-0028, whose data prints a 30 fps frame rate, a 60 codes/s decode rate and a 2560 x 2048 sensor with an 8 mm lens. The dwell is 2 s in the field of view — an illustrative value for a part held under a static station.

The rule: free-run attempts one decode per frame, so attempts equal frame rate times dwell. A gated or stopped reader accepts exactly one result, and the stop lands within one frame interval.

frame interval = 1000 ms / frame rate ungated attempts = frame rate × dwell wasted decodes = ungated attempts − 1

The arithmetic. Frame interval = 1000 ms ÷ 30 = 33.3 ms. Ungated attempts = 30 frames/s × 2 s = 60 decodes of one and the same code, and the 60 codes/s rating shows the reader can spend its full throughput on repeats. Gated, you get 1 accepted read, at most 1 frame in flight, and every latecomer suppressed by the flag.

The result: 60 results become 1, and decoder and light duty drop by the same factor.

The decision: the moment dwell exceeds one frame interval — 33 ms here — a free-run reader returns more than one result per code. Past 0.5 s of dwell, 0.5 × 30 = 15 decodes are already wasted per part. Gate or trigger every static station; leave free-run only where the code crosses the view within a frame or two.

Fixed code readers2560 x 2048 fixed code reader, 30 fps, 60 codes/s, 8 mm lens (LS-CRD-0028)LS-CRD-0028
Interface
Fast Ethernet
Resolution
5 MP
Sensor format
1/1.7"
Shutter
Global
$920.00View part

Verify the count: one part, one read

  • Hold one code in view for 10 s: the accepted-result counter shows exactly 1. The raw callback counter keeps climbing on a gated stream, or freezes on a stopped one.
  • Timestamp the log. A duplicate that slips through lands within one frame interval of the accepted read — the in-flight frame your gate must catch.
  • Cover or remove the code and confirm the no-read path: the timeout fires, the station re-arms, nothing hangs.
  • Watch the PLC side: the result register changes exactly once per cycle, and the done bit pulses once.
  • Run a fixed batch or a full shift and compare read count with part count; fold the test into a written acceptance run like barcode reader verification for label inspection.

Common mistakes

  • Stopping after the UI action. Navigating to a result view takes hundreds of milliseconds; frames keep decoding meanwhile. Stop first, then navigate.
  • Resetting done on a timer instead of a cycle edge. Open too early and you accept a second read on the same part; open too late and the next part's first frames are swallowed.
  • Restarting acquisition while the previous one still runs. The SDK reports the resource busy; stop before you start, per why a single-frame acquisition stays busy.
  • Level-held PLC commands, as in the warning above.
  • Identical codes on rework parts. A re-armed trigger will read the same string twice; if the second must not count, compare against the last accepted string and timestamp, or require a part-left signal between reads.
  • Debugging the in-flight duplicate. One callback after the stop is normal pipeline behaviour; suppress it.

Which method for your case

  • Stationary part, PC or HMI application: stop acquisition inside the success branch.
  • Stream needed for an archive or a second tool: done flag, with a strobed light.
  • Discrete parts passing a sensor: hardware trigger, one shot per part.
  • PLC-owned line: trigger for the frames plus handshake for acceptance.
Build the whole station

The configurator matches a camera, lens, light, light controller and cables to each other, step by step, and lists only parts that fit what you already picked.

Start with the trigger sensor

If you are still choosing hardware, the code reader finder filters fixed readers by interface, resolution and shutter. More decode-side fixes sit on the code-reading topic page. If a handshake will not close on your platform, contact us with the reader model and the PLC you are wiring to.

Questions

Will stopping acquisition right after the read make me miss a second code?

No, provided one code per view is your case. The accepted result came from a frame you already hold, and you copy the string out before the stop. Any frame still in flight can only add a duplicate of the same code. If two codes can legitimately enter the field within one frame interval — about 33 ms at 30 fps — keep the gate logic active during the wind-down and accept the second code explicitly.

Why does exactly one more result arrive after I set the done flag?

That frame was already exposed and dispatched before your flag took effect; the callback pipeline drains one frame deep at typical frame rates. Treat the flag as effective from the next frame boundary and let it suppress that latecomer. If more than one duplicate lands, your processing is lagging acquisition and the queue is holding frames — drain or flush it when the gate closes.

Should I use hardware trigger or a software flag to read once?

Trigger stops the repeats at the source: no edge, no frame, no decode, and illumination runs only per shot. The flag costs no wiring and works on any reader whose SDK exposes a callback, but the stream and light stay loaded. On a PLC-owned line use both — trigger for the frames, handshake for the acceptance — because they solve different halves of the problem.

How do I re-arm the reader for the next part?

Tie re-arming to the cycle, not the clock: the PLC clears the command, the part-left sensor fires, or the next trigger edge arrives. Add a no-read timeout set above your measured worst-case good-read time — exposure, decode, transfer and one PLC scan — so a missing or unreadable code cannot stall the station. Log every timeout; a rising no-read rate usually means lighting or label wear, not logic.

Can I just filter duplicate reads in the PLC instead?

You can: compare each incoming string and timestamp against the last accepted pair and pass only changes. It works, but the reader, decoder and light keep running at full duty for every frame, and identical consecutive codes — common on rework — need a time window, not just a string compare. Filtering is the right fix only when the extra decodes serve a purpose, such as grade verification.