Code readingHow-to

Compare a partial barcode string in a PLC at any start position

Copy each barcode string into scratch bytes at a start offset, then compare only the copied length: ladder steps, offset math and an odd-position example.

LumaSpec Vision10 min read Share on LinkedIn

On this page 9 sections
  1. 01Why the register-pair compare fails on an odd position
  2. 02What you need before the first rung
  3. 03The three numbers that define the slice
  4. 04Copy, then compare: the ladder steps
  5. 05Worked example: seven characters from position 9 of two 24-character reads
  6. 06When the match should leave the ladder
  7. 07Mistakes that turn a pass into a false read
  8. 08Where to start on your line
  9. 09Questions

Two readers put variable-length barcode strings into your PLC, and the check you actually need is narrow: the lot field in the middle must match while the serials around it differ. A whole-string compare fails every good part. A register-pair compare starts mid-word the moment the field begins on an odd character. The reliable fix is to stop comparing registers and start copying bytes: read each string's actual-length byte, block-move the exact slice into scratch bytes, and compare that slice alone. This guide gives the byte layout, the offset arithmetic, the ladder steps, a worked example at an odd start position, and the point at which the match belongs in a reader or a vision controller instead.

Why the register-pair compare fails on an odd position

Card-level and module hand-offs commonly write barcode ASCII two characters per 16-bit register, and compare instructions act on all 16 bits at once. A field that starts on character 9 shares its first register with a character you do not care about, and a variable code length moves the half-used register at the tail. Every combination of odd or even start and odd or even length then needs its own mask-and-shift rungs. That is how a short check grows into a page of logic.

String types addressed in bytes end that. IEC 61131-3 STRING data keeps two length bytes ahead of the characters: the maximum length first, then the actual length. Platform manuals print slightly different totals for the same idea. One PLC family's engineering manual describes string data as a 2-byte header followed by up to 254 character bytes, and another IEC runtime sizes an 80-character string at 81 bytes. Your platform's programming manual is the place to confirm the header your compiler emits; check the string data overview in its instruction documentation.

The common core is what the routine needs: fixed header bytes, then one byte per character. Every character in the field owns one address, so position 9 is as easy to reach as position 10. The byte-versus-register trade is worked through further in storing ASCII barcode strings in PLC memory: bytes, words and clears.

What you need before the first rung

  • both reads visible as bytes: a STRING tag, or registers with a byte view of the same memory;
  • the header size in bytes, read once from a watch table (2 on the IEC layout, 0 for headerless ASCII blocks);
  • scratch space of at least the slice length for each read, plus two integer tags for the actual lengths;
  • a block-move that works on bytes and a block-compare that runs over the scratch area;
  • one new-read flag per reader and one match bit out, with a no-match bit if the line acts on rejects.

The strings arrive from the fixed code readers on the line; Ethernet, serial and USB readers all deliver the decoded ASCII on each trigger. A compact reader that pushes each decode over Fast Ethernet as the part passes fits this hand-off:

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

The three numbers that define the slice

None of them is the code length:

  • start position — the first character of the field, counted from 1;
  • character count — how many characters must be equal;
  • header bytes — 2 on the IEC layout, 0 for a headerless ASCII block.
first byte to copy = start position + header bytes - 1 bytes to copy = character count length guard = start position + character count - 1

Positions count from 1 and byte addresses from 0, which is where the - 1 comes from, twice. On the IEC layout the first byte simplifies to start position + 1, so characters 9 to 15 live in bytes 10 to 16. Run the guard before anything is copied: read byte 1 of each string into an integer tag and reject the read when either tag sits below start position + count - 1. That one compare is what makes variable code lengths safe. The routine never walks off the end of a short read into the next register map.

When the variable part is trailing serial data rather than a mid-string field, levelling the lengths with a suffix at the reader can settle the strings before the PLC sees them.

Copy, then compare: the ladder steps

  1. Gate on both reads. Run the routine only when both new-read flags are set. Lift each string out of the receive area on that handshake, not on a free-running scan — the flag discipline in copying barcode data to a string only on a new read handshake applies here.
  2. Read the lengths. Move byte 1 of each string into two integer tags; these are the actual character counts.
  3. Apply the guard. If either length is below start position + count - 1, switch the no-match bit on and jump to step 7.
  4. Copy slice A. Block-move count bytes of string A from byte (start position + 1) into scratch area A.
  5. Copy slice B. Repeat from string B into scratch area B.
  6. Compare. Block-compare the two scratch areas over count bytes; equality switches the match bit on.
  7. Latch the verdict. Hold match and no-match until the consuming logic acknowledges them, so the bits survive past the scan that set them — the same idea as latching a barcode string that lives for one scan.
  8. Reset. Clear both scratch areas and both new-read flags in the rung that re-arms the hand-off for the next part.

Worked example: seven characters from position 9 of two 24-character reads

Inputs. Read A is the 24-character label 4711-A07LOT2416X09182461; read B is the 24-character label 4711-A03LOT2416X09182477 (example labels in a part-number, lot and serial format). The field to verify is characters 9 to 15, the lot code LOT2416: start position 9, character count 7. The start is taken odd because that is the case register compares mishandle. Header: 2 bytes, from the IEC string layout. Guard threshold: 9 + 7 - 1 = 15 characters.

Rule in words. Character n sits at byte n + 1, so the slice starts one byte after its position number and runs for the count. Both strings must reach position start + count - 1 before anything is compared.

Arithmetic.

  • First byte to copy: 9 + 2 - 1 = 10.
  • Last byte copied: 10 + 7 - 1 = 16, covering characters 9 to 15.
  • Guard: 9 + 7 - 1 = 15, and both actual lengths read 24, so 24 ≥ 15 and the compare is allowed.

Result. Bytes 10 to 16 of read A spell LOT2416, and bytes 10 to 16 of read B spell LOT2416: all 7 copied bytes are equal, so the match bit latches on. A whole-string compare would have failed. Characters 1 to 8 (4711-A07 against 4711-A03) and characters 16 to 24 (the serials) differ.

Decision. Below 15 characters on either read, set no-match and skip the compare; at 15 or more on both, compare the 7 bytes and act on the bit. The register version of the same check needs three full register-pair rungs plus a masked rung for the half-used tail, redrawn for every parity of start and length. The byte version is one move pair and one compare, unchanged at any offset.

When the match should leave the ladder

Two situations move the work out of ladder. If the field moves with the product — a different start position or count per recipe — the copy routine needs indirect addressing on top of a recipe table. That is the shape barcode recipe lookup in a PLC with UDT arrays and search logic grows into. If the real question is whether a scanned lot exists in your list at all, that is a lookup rather than a substring compare, and verifying scanned barcodes against a PLC lookup table covers it.

When a pass or fail is all the PLC needs, let the vision side decide. A vision controller runs string compares in software, drives cameras and lights from the same box, and hands the PLC one bit over Ethernet, serial or an output. An entry controller in that role carries four built-in light channels, an N97 processor and 8 GB of memory plus a 128 GB SSD with a 1 TB HDD:

Vision controllersHikrobot MV-VC2140-128G40-1T VC2100 Vision Controller, N97, 8GB+128G SSD+ 1THDDMV-VC2140-128G40-1T
LAN ports
3-4 LAN ports
USB 3 ports
2 USB 3 ports
Light outputs
4 built-in channels
Memory
8 GB
$1,679.00View partBuild a system with it

Where the pass or fail stays at the reader, these three cover Fast Ethernet, GigE and USB hand-offs across short and mid-range working distances:

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
Fixed code readersHikrobot MV-ID813M-05S-WBN-SR 1.3 MP resolution, 4.9 mm focal length, White light, SR, GigE, Static cableMV-ID813M-05S-WBN-SR
Interface
GigE
Resolution
Up to 3 MP
$719.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

Mistakes that turn a pass into a false read

  • Case drift. L and l sit 32 apart in ASCII, so decide the case policy before the compare and apply the same fold to both slices.
  • Even offsets only on the test bench. Run the same two labels with the field at start positions 8, 9 and 10; a byte-copy routine must return the same verdict at all three.
  • Late clearing. Scratch areas and flags that survive into the next part can re-present the previous verdict; clear them where you re-arm the hand-off.
  • Length passing for content. Equal lengths do not mean equal fields; the block-compare decides the match, the length tags only permit it.

Where to start on your line

Settle the hand-off before the logic: pick the reader interface that matches the PLC platform in the code reader finder, prove the new-read handshake, then add the guard and the slice copy. When the field sits at a fixed position on every label, splitting barcode string data into fields: lot and part numbers is the simpler cousin of this routine. More string-handling patterns sit on the code-reading topic page. If you send us your two label formats and the PLC platform through the contact page, we will map the compare with you.

Questions

How do I find the header size my PLC string type uses?

Watch bytes 0 and 1 of a string you know in a watch table. On the IEC layout byte 0 holds the maximum length and byte 1 the current length, so a 24-character read in an 80-character field shows 80 then 24. If your reader card writes plain ASCII with no header, byte 0 is already the first character and every offset shifts by two: character 9 starts at byte 8, not 10.

Why does an odd start position break a register-pair compare?

A 16-bit register holds two ASCII characters, and compare instructions test the whole register at once. A field starting on character 9 shares its first register with an unwanted character at one end and leaves a partial register at the other, so each start and length combination needs its own mask-and-shift rungs. Copying bytes first removes the masking entirely: every character gets its own address, odd or even.

How do I make the substring match case-insensitive?

Fold case during the copy: OR each copied character byte with 32 on both slices before the compare. Upper and lower case ASCII letters differ by exactly 32, so the operation turns both into capitals; digits and punctuation are unchanged, so a lot code such as 2416 compares exactly as before. Keep the original bytes in the string registers untouched for the archive or the operator display.

Is there a limit on how many characters the slice can cover?

One IEC string holds up to 254 characters after its header, so a slice of that size is still two block-moves and one block-compare. In practice compare the shortest field that separates your parts, often 6 to 12 characters: the guard stays simple, the scratch area stays small, and the whole routine remains well inside one PLC scan.

When is it better to do the match in the reader or controller?

Move it upstream when the check is constant: set the field once in a fixed code reader or vision controller and send the PLC a single match bit over Ethernet, serial or an output. Keep it in ladder when the compared field moves with the product recipe, when two readers must feed one check, or when the PLC must log which characters disagreed for quality records.