Code readingHow-to

Store a scanned barcode value in VAL3 and trigger three applications

Store the scanned barcode value in a VAL3 string once its terminator arrives, match it against three codes, and fire the right application, with timing shown.

LumaSpec Vision11 min read Share on LinkedIn

On this page 9 sections
  1. 01Why does a scanned value never arrive complete?
  2. 02What do you need before writing the capture program?
  3. 03How do you capture a scan into a VAL3 string?
  4. 04How do you match three codes and trigger three applications?
  5. 05How long does one scan take to arrive?
  6. 06Should you keep the keyboard wedge or move to a fixed code reader?
  7. 07How do you prove the loop works before production?
  8. 08When is exact string matching the wrong answer?
  9. 09Questions

Three labels on the line, three applications on the controller, and the scans read fine — yet the value never arrives complete, or the wrong application starts. The fault is almost never the decode; it is the store. A scanner hands the controller a stream of characters, and code that samples that stream at the wrong moment commits a fragment of a code. This guide gives the capture pattern that fixes it in VAL3 terms: buffer the characters, commit on the terminator, match the committed string exactly against your three codes, and dispatch to three applications. You also get the arrival-time arithmetic, the decision between keyboard wedge, serial and a fixed code reader, and a 15-scan verification set to run before production. It is written for anyone wiring a scanner into a robot controller, with or without a PLC in the middle.

Why does a scanned value never arrive complete?

Because a scanner delivers characters over a link, not a variable assignment: a 12-character code arrives as 13 characters once you count its terminator, and code that samples the input mid-stream stores a fragment such as 4710987654 instead of the full 471098765412.

Three faults cover nearly every report of this problem. The partial string: the program reads the buffer before the last characters land. The doubled string: the second scan appends to the first because the buffer was never cleared between reads. The stale string: the done flag is never cleared, so the previous code re-fires its application on every part that follows. All three vanish under one commit rule — characters collect in a buffer, only the terminator commits the buffer into the value your motion code reads, and that value is consumed exactly once before the next scan is accepted.

What do you need before writing the capture program?

Three things: the three exact code strings copied character for character, one chosen terminator configured as the scanner's suffix, and two string variables plus a done flag sized to the longest code plus four characters — 16 characters covers a 12-digit code.

Before you write a line, collect the rest of the set:

  • The three strings exactly as your reader reports them, not as the label prints. Scan each label once and log the raw output before you hard-code anything; a check digit or a hidden suffix shows up immediately.
  • One terminator, chosen once. CR is the usual pick, because it ends every read identically whatever the code length.
  • Declarations with initials: a buffer string, a committed string, a done flag set to false, and two integer counters for missed and unknown scans.
  • A buffer sized to the longest code plus four characters: 12 + 1 terminator + 3 margin = 16 characters for a 12-digit code.
  • A read task that runs in the background, so motion never blocks waiting for characters.

How do you capture a scan into a VAL3 string?

Declare a buffer string, a committed string and a done flag once, append every incoming character to the buffer, and on the terminator copy the buffer into the committed string in one atomic assignment, then clear the buffer.

  1. Declare the variables once, with initials: string sScanBuf = "", string sCode = "", bool bScanDone = false, int nMissed = 0, int nUnknown = 0. The names are yours to choose; the commit order is not.
  2. Match the link settings at both ends — baud, parity and terminator — in the controller's serial-link configuration and the scanner's data-format menu.
  3. In the background read task, append every arriving character to sScanBuf.
  4. On the terminator, apply the commit rule: if bScanDone is still true, the previous scan is unread, so drop this scan and add 1 to nMissed; otherwise copy sScanBuf to sCode, set bScanDone to true, and clear sScanBuf in the same pass.
  5. In the motion task, read sCode only while bScanDone is true, dispatch, then clear bScanDone and sCode — that clear re-arms the read for the next scan.
// Capture pattern — illustrative names; keep your controller's own read call
string sScanBuf  = ""      // characters as they arrive
string sCode     = ""      // last committed scan, consumed once
bool   bScanDone = false   // true while sCode holds an unread scan
int    nMissed   = 0       // scans dropped while the last one was unread
int    nUnknown  = 0       // scans that matched no known code

loop:                       // background read task
  ch = readOneCharacter()
  sScanBuf = sScanBuf + ch
  if ch == CR:              // terminator arrived: the value is complete
    if not bScanDone:
      sCode     = sScanBuf  // the single commit point
      bScanDone = true
    else:
      nMissed = nMissed + 1 // previous scan still unread: drop this one
    sScanBuf = ""           // fresh buffer for the next scan

loop:                       // motion or main task
  if bScanDone:
    dispatch(sCode)         // match-and-fire block in the next section
    bScanDone = false       // consume, then re-arm
    sCode     = ""

One related trap: a read instruction that arms itself once and never re-arms produces one good scan and then silence. ARL and AWA ASCII instructions execute once: retrigger each scan walks that exact fault on a serial ASCII link, and the cure is the same re-arm.

How do you match three codes and trigger three applications?

Compare the committed string for exact equality against the three literals — never a prefix — and branch to the matching application program; any other value increments a reject counter and starts nothing.

The compare runs on sCode, never on the live buffer, so the string cannot change under the test. Prefix matching looks convenient and fails quietly: a longer code that begins with a shorter pattern's digits — 471098765412 against a 47109 pattern — selects the wrong application. Whole-string equality against exactly three literals leaves no such overlap; everything else lands in the reject bucket.

For the dispatch itself, three forms work: call the three application programs directly from the branch; set an integer program selector that the motion code switches on; or pulse one of three digital outputs to hand the start to the cell. If the start signal belongs inside a running motion program — a clamp pulse, a start bit to the cell PLC — triggering a digital output mid-motion in VAL3 shows where the output call sits relative to the motion instructions.

If your reader appends a line ID or a timestamp to each read, strip everything outside the payload before the compare; the capture side of that problem is the subject of variable-length barcode scanner input: fix it with a suffix.

How long does one scan take to arrive?

About 30 ms on a 9,600-baud serial link: roughly 17 ms to decode plus 13.5 ms to transmit 13 characters, and most of that shrinks away if the reader pushes the string over Ethernet instead.

t_decode = 1 / read rate = 1 / (60 codes/s) = 16.7 ms t_serial = 13 characters × 10 bits per character / 9600 bit/s = 13.5 ms t_total = 16.7 ms + 13.5 ms ≈ 30 ms

The inputs: a 12-character payload plus its CR (13 characters), 8N1 framing at 10 bits per character, 9,600 baud, and a decode rate of 60 codes/s — the rate the 5 MP reader in the parts list below prints. Move the port to 115,200 baud and the serial term falls to 130 / 115200 = 1.1 ms, so the arrival is about 18 ms and decode-bound. Over Ethernet the reader pushes the decoded string the moment it exists, and the decode term dominates.

Against a 2-second robot cycle, 30 ms is invisible. The value of the number is knowing the window in which the buffer is half full — and that window is exactly what the terminator commit makes harmless, so the timing never has to be sampled around.

Should you keep the keyboard wedge or move to a fixed code reader?

Keep the wedge only where the scan feeds a screen you control end to end; for a robot cell, wire the scanner or a fixed code reader to a serial or network port so the string arrives on a link your program owns.

A wedge types into whatever field has focus, so a focus change or a remote-desktop session drops or splits scans — the failure keyboard wedge scans dropping over RDP documents for HMI panels. A serial link delivers each scan as one delimited string, and serial, USB and Ethernet input methods to a PLC compares the same three paths on the PLC side.

Input path How the string arrives Best fit Watch out
Keyboard wedge into a screen field Keystrokes into the focused field Operator desks with one fixed screen Focus changes and remote-desktop sessions drop or split scans
Serial link to the controller One terminator-delimited string per scan Fixed cells where the controller owns a port Baud, parity and terminator must match at both ends
Fixed code reader on Ethernet Decoded string pushed per read Robot cells, high rates, no screen involved Trigger set-up and reading distance must suit the fixture

Whichever reader you pick, set its trigger to match the part-present signal; fixed barcode reader trigger modes: sensor, serial or free-run compares the three trigger paths. For the fixed cell, the fixed code readers category is the shortlist, and every reader there hands your program a finished, delimited string.

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
$1,979.00View part
Fixed code readersCompact fixed industrial barcode reader, 1.2 MP, USB 2.0, 60-120 mm reading distance (LS-CRD-0047)LS-CRD-0047
Resolution
Up to 3 MP
Shutter
Global
$559.00View part
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
$920.00View part

The MV-ID3013PM-12M-WBN pairs a 1.3 MP sensor with a 12 mm focal length on a Fast Ethernet interface, the shape for a mount where the label sits away from the optics and the string should travel the network. The LS-CRD-0047 reads over USB 2.0 from 60 to 120 mm with its 1.2 MP sensor, which suits a label presented at a fixture. For frames that carry several labels at once, the LS-CRD-0028 decodes up to 60 codes/s from 2560 x 2048 images at 30 fps through an 8 mm lens.

A manual load station keeps the same loop: the operator presents the label, the reader supplies the finished string, and the capture task cannot tell the difference. Wired handheld code readers suit a fixed cell, and the LS-HCR-0001 is the USB starting point.

Handheld code readersHandheld industrial barcode reader, 1.0 MP, USB 2.0 (LS-HCR-0001)LS-HCR-0001
Resolution
Up to 3 MP
Shutter
Global
Interface
USB
Connection
Wired
$539.00View part

How do you prove the loop works before production?

Run 15 scans before you trust it: each of the three codes five times, plus the unknown-code and mid-application cases, and require zero wrong dispatches across the set.

  1. Scan the three codes in rotation, five rounds each: the matching application must fire on all 15 reads. Log sCode beside the label value on every read; a single mismatch is a capture fault, not a decode fault.
  2. Scan a fourth, unknown code three times: nothing starts, and nUnknown reads 3 at the end.
  3. Force a scan while an application is mid-cycle: the scan must be dropped, nMissed must rise by 1, and the running motion must not change.
  4. Unplug the scanner mid-string: with no terminator there is no commit, sCode stays empty, and nothing fires. Reconnect and rescan; the next complete string must commit normally.
  5. Scan two codes back to back, faster than the cycle consumes the first: the second must be either queued cleanly by your logic or counted in nMissed — never merged into one string.

Zero wrong dispatches across those cases is the bar. A program that passes the set has no silent path left in the capture, match or dispatch logic.

When is exact string matching the wrong answer?

When the label carries a variable suffix, when decode quality matters as much as the value, or when the dispatch belongs to the PLC rather than the robot — each case needs one more input than the bare string.

Variable payloads: keep exact equality, but apply it to the payload alone. Strip a fixed-position suffix or split on a fixed separator before the compare, so a timestamp can never break a match.

Graded or verified labels: a read can decode and still be too poor to act on. Gate the dispatch on the reader's confidence signal as well as the string; how to judge whether a decode is trustworthy sets out that judgement.

PLC-owned dispatch: when the value must gate the cell rather than the robot, move the compare into ladder — PLC ladder logic to compare barcode strings and count three reads builds the three-way match, and storing ASCII barcode strings in PLC memory covers the storage bytes underneath it.

The decisions in one place: commit on the terminator, never sample a stream; match whole strings against your literals; reject unknowns and count them; re-arm after every dispatch. Keep the wedge only for a screen you own, take serial where the controller owns a port, and take a fixed reader on Ethernet when the cell must run without a screen at all. Shortlist optics in the fixed code reader finder, or send your three codes and reading distance through the contact page and we will match the reader to the fixture. The code-reading topic page collects the rest of the capture-and-decode guides.

Questions

What terminator should the scanner send at the end of each code?

Pick one and match it on both sides: CR, or CR plus LF, is typical. It is set as the scanner's suffix in its data-format or terminator menu, and the same character must end the capture in your program. Never rely on a pause in the stream; the terminator is what tells the capture task the value is complete, whatever the code's length.

How large should the string buffer be?

Size it to the longest code plus four characters: a 12-digit code gets a 16-character buffer, which covers the terminator plus margin. If a scan arrives longer than the buffer allows, discard it and add it to the reject counter. An over-length string is either a misread or the wrong label, and neither should start an application.

Does the read have to be re-armed after each application starts?

Yes. A read instruction that arms once leaves the input dead after the first code, so the second scan produces nothing at all. Clear the done flag and the committed string as the final step of every dispatch, and treat a first-scan-works-second-scan-silent symptom as a missed re-arm before you change anything else.

Can a handheld scanner drive the same three-application program?

Yes, at manual load stations. A wired handheld that ends each read with the same terminator behaves exactly like a fixed reader to the capture task, so the store, match and dispatch logic does not change. Only the mount and the trigger move, from the fixture to the operator's hand; a wireless model adds a base-station link worth testing before production.