A barcode reader on a Profibus link does not hand the PLC a string; it fills a block of input words, and the word monitor shows them in hex: 16#4C47 where the label prints LG. Nothing is broken. Each word already carries two ASCII character codes, and the only real work is splitting bytes and copying them. This guide walks through the split, the character mapping, the trim of terminators and padding, and the three test labels that prove the logic before the line runs.
The bytes are already ASCII: the hex display is only notation
Split the word and read it as two byte values. The high byte 16#4C is 4 × 16 + 12 = 76, and character code 76 is L. The low byte 16#47 is 4 × 16 + 7 = 71, the code for G. The buffer arrived as ASCII text; the monitor prints raw bytes in hex because a fieldbus I/O image moves bytes, not text. No base conversion runs anywhere, and no 256-entry lookup table is needed where the runtime can move a byte into a string position directly. If a table is unavoidable, 95 entries cover the printable range, bytes 32 to 126.
The bytes around the text explain why setup tools lean on the hex display: a configured prefix, a CR or LF suffix and, on some fieldbus profiles, status and counter bytes share the buffer with the code. Treat code bytes and framing bytes as one stream, trim at the end, and the text falls out clean.
What you need
Four facts remove every guess from the logic:
- Data area. The start address and word count of the reader's block in the I/O image, from the fieldbus or gateway configuration.
- Output format. The fixed data length and any prefix or suffix, such as CR (16#0D) or LF (16#0A). The setting lives in the reader's own configuration, next to its interface settings.
- A test label. Write LG4711 on paper. It mixes uppercase letters with digits, exactly what the byte order test needs.
- The symbology. Code 128 and QR codes arrive as plain character bytes. Code 39 with full ASCII conversion sends a two-byte pair for some characters, covered among the mistakes below.
If the trigger line or an I/O module for the reader is still on the bench, the code reader accessories category carries light boards, protective covers and I/O modules for that wiring stage.
Worked example: LG4711 in three words
Print LG4711 and trigger one read. Six characters at two bytes per word fill three words, and every byte lands in the printable range:
| Characters | Word | High byte | Character | Low byte | Character |
|---|---|---|---|---|---|
| L G | 16#4C47 | 16#4C | L (76) | 16#47 | G (71) |
| 4 7 | 16#3437 | 16#34 | 4 (52) | 16#37 | 7 (55) |
| 1 1 | 16#3131 | 16#31 | 1 (49) | 16#31 | 1 (49) |
The arithmetic, worked once per distinct byte: 16#34 = 3 × 16 + 4 = 52, and 52 is the character 4, because digits run from 16#30 = 48 for 0 up to 16#39 = 57 for 9. Rebuilt in stream order, the buffer reads LG4711, six characters long. A reader set to append CR LF adds a fourth word, 16#0D0A - decimal 13 then 10 - and the trim step drops it.
Five ranges cover nearly everything a barcode contains:
| Byte values | Decimal | Characters |
|---|---|---|
| 16#30 to 16#39 | 48 to 57 | digits 0 to 9 |
| 16#41 to 16#5A | 65 to 90 | uppercase A to Z |
| 16#61 to 16#7A | 97 to 122 | lowercase a to z |
| 16#20 | 32 | space |
| 16#0D, 16#0A | 13, 10 | CR, LF |
Convert the buffer in five steps
- Capture one known read. Trigger the reader on the LG4711 label and copy the data words from the input image into a work buffer, so the live link cannot overwrite them while you test.
- Settle the byte order once. If the first word shows 16#4C47, the first character of each pair sits in the high byte; if it shows 16#474C, the gateway streams low byte first. Pick the split that matches and apply it to the whole buffer, never per word.
- Split every word. The high byte is the word divided by 256 and truncated; the low byte is the remainder, or the word masked with 16#00FF. Three words become six bytes for this code.
- Copy each byte into its string position, in stream order. Byte i of the buffer goes to position i + 1, and the byte moves unchanged, because its value already is the character code.
- Trim the tail. Find the first byte below 32 - CR, LF or NUL - or, on space-padded fixed-length fields, count back over the trailing 16#20 bytes, then set the string length to the last printable character. The result compares and parses cleanly downstream.
Verify with three test labels
Run three reads before the logic goes live; each label targets one failure mode:
- All zeros, 0000. Every byte must read 16#30. If a four-digit code instead arrives as two small words such as 16#47 and 16#11, the reader is sending BCD, two decimal digits packed per byte; split each byte into two nibbles and add 16#30 to each nibble to build the characters.
- Mixed case. A code with a lowercase letter: lowercase runs 16#61 to 16#7A, so a byte of 16#68 (104) must print as h. An H in its place means something upstream shifts case, and string comparisons will drift later.
- Length. Count printable bytes against the symbology: characters equal two per word, minus terminator and padding bytes. A mismatch usually means a prefix byte such as STX (16#02) sits in front of the code.
Four mistakes that turn good reads into garbage
- Subtracting 16#30 from every byte. 76 - 48 = 28 puts a control code where L belongs. Reserve that subtraction for turning one digit character into its numeric value.
- Trusting the manual's byte order without the label test. One swapped pair turns LG4711 into GL4711 - right characters, wrong order, no match.
- Mixing conventions. Half the buffer split high byte first and half low byte first produces text that decodes but never compares. The convention from step 2 belongs to one device, so keep one conversion block per reader.
- Counting Code 39 full ASCII pairs as two characters. A symbol prefix plus a letter encodes one extended character, so two bytes can be one character of text, and the length check must count such pairs as one.
The same symptom on a serial link - words where text should be - has a documented field fix in a barcode reader hex-to-ASCII walkthrough for a legacy PLC platform, worth reading before the logic is rebuilt from zero.
Skip the conversion: read a string instead of words
A fieldbus word image is not the only route into the PLC. Set the reader's output format to send the decoded string with a terminator over serial or Ethernet, and the buffer arrives as characters - no split, no trim. The serial, USB and Ethernet input paths a scanner can take compare those routes, and wiring the reader as a TCP server with the PLC as the client shows the socket version. An implicit I/O assembly on EtherNet/IP moves the same byte stream as words, so the split from this guide applies there too.
If the station is still on the drawing board, choose a reader that talks Ethernet from the start: the decode result crosses as data you can read as text, and the conversion loop never gets written. Both readers below read 1D and 2D codes and connect over Fast Ethernet or GigE:
- Interface
- Fast Ethernet
- Resolution
- Up to 3 MP
- Interface
- GigE
- Resolution
- Up to 3 MP
MV-ID3013PM-12M-WBN is the compact Fast Ethernet model. MV-ID813M-05S-WBN-SR runs on GigE and carries its own white light. Deeper reading on the reader side sits on the code-reading topic page.
From raw words to a string the line can use
Once the conversion runs, the string is ready for real work. Store it the way storing ASCII barcode strings in PLC memory: bytes, words and clears lays out, split it into lot and part numbers as in parsing barcode string data into fields, or hold two readers against each other with string comparison logic in the PLC. Plan the whole path - trigger, data format, handshake, error handling - before writing logic; the reader-to-PLC communication planning checklist puts those decisions in order.
For hardware, the fixed code readers category lines up every interface and resolution filter side by side, and the code reader finder narrows the list by trigger and mounting needs:
1D/2D codes on the line
658 models · from $399.00When a conversion or a handshake still misbehaves after these checks, send the word list and a photo of the label through the contact page and the applications team will read the buffer with you.
Questions
Why does a barcode reader send hex instead of ASCII text?
The link moves bytes and the monitoring tool displays bytes, so the buffer shows up as hex words whether or not it holds text. Decode data itself is ASCII bytes; extra bytes around it - a configured prefix, a suffix such as CR or LF, and status or counter bytes the fieldbus profile adds - are why a setup tool may present everything in hex by default.
How do I recognize BCD data instead of ASCII in my words?
Read a code you know, such as 4711. ASCII digits arrive as 16#34, 16#37, 16#31, 16#31; BCD arrives packed, two decimal digits per byte: 16#47, 16#11. For BCD, split each byte into two nibbles and add 16#30 to each nibble before building the string - small values that never reach 16#30 are the tell.
Does byte order differ between readers on the same PLC?
It can, because word byte order comes from how each reader or gateway maps its serial buffer into the I/O image, not from the codes themselves. Two devices on one bus can legitimately disagree. Test every reader with its own known label and keep one split convention per device instead of copying the same conversion block everywhere.
Can the HMI do the conversion instead of the PLC?
Often yes: HMI and SCADA software can address the raw buffer and format each byte as a character, the same split this guide describes. The trade-off is that the PLC never sees a clean string, so comparisons, archiving and MES hand-off lack the text. Converting in the PLC once and passing the string on keeps one copy of the logic to maintain.
What if the code length changes from label to label?
Set the string length from the terminator or the first non-printable byte rather than from the fixed buffer size, and one loop then handles a three-character code and a twenty-character code alike. Size the buffer for the longest code the symbology allows - Code 128 can carry more than forty characters - and let the trim step do the rest.

