You can use many different methods to print barcodes from your AS/400. In this article, I will discuss the three most popular methods: IBM’s Intelligent Printer Data Stream using an IPDS-capable printer, workstation customization objects, and ASCII transparency. This article will help you determine which method or methods will be right for you.
Before you can print barcodes, you must decide which symbologies are required. Some of the more common are 3 of 9, UPC-A, and interleaved 2 of 5. The 3 of 9 symbology can represent digits 0 through 9 and uppercase A to Z, along with some special characters (*, $, /, +, %). The term 3 of 9 is derived from the manner in which the barcode is printed. Each character is represented by nine elements: five bars, four spaces, and an intercharacter gap. Three of the elements are wide bars or spaces. If you need lowercase character representation, you could use the 128 symbology.
The UPC-A symbology is widely used in the retail environment. UPC-A is a numeric-only barcode that uses a Modulus 10 check digit for increased accuracy.
Interleaved 2 of 5 is a high-density, self-checking numeric symbology used mainly in warehousing and industrial applications. Each character is composed of five bars or five spaces, two of which are wide. The first character of an interleaved 2 of 5 barcode is represented by the first five bars. The second character is represented by the first five spaces, and so on.
Printing barcodes using IBM’s Intelligent Printer Data Stream (IPDS) interface can be relatively painless with externally defined printer files and the BARCODE DDS keyword. The printer file must be created with the Device type (DEVTYPE) parameter set to *IPDS, and, of course, the printer itself must be configured as an IPDS printer. The AS/400 does not require the AFP or Print Services Facilities products to be installed in order to print barcodes using IPDS-capable printers.
Sixteen common barcode symbologies are supported using the BARCODE keyword. The format of the BARCODE keyword is shown in Figure 1. The default values
for the extra parameters are *HRZ, *HRI, *NOAST, and no check digit. Unit Width is
.015, and the Wide/Narrow Ratio is 2.5. These default values are set inside the keyword and cannot be changed.
Barcodes can be generated by simply specifying the BARCODE keyword, the barcode type (3 of 9, UPC-A, etc.), and the barcode height. The valid data types for printing barcodes are alphanumeric and signed decimal, although on symbologies that are alpha, you can get by without specifying a data type. Consult the OS/400 DDS Reference for the correct data types for the symbology you wish to use.
The valid values for the height parameter are from 1 to 9. The height is determined by the lines per inch specified in the printer file. A height of 3 would generate a barcode 1/2” tall at six lines per inch and 3/8” tall at eight lines per inch. In order to generate a horizontal 3 of 9 barcode 1/2” high, you could use the example in Figure 2.
Using the Barcode Keyword Parameters
Let’s take a closer look at the parameters that we did not specify. The Horizontal/Vertical parameter is used to specify the orientation of the barcode, either horizontal (which looks like a picket fence) or vertical (which looks like a ladder).
The Human readable parameter determines whether the data contained inside the barcode is printed in addition to the barcode in human readable form either above or below the barcode. The default is *HRI, with the data printing below the barcode. The *HRITOP can be used to print the human readable data above the barcode, if desired. An OCR font is used to print the data, so if your users do not like the appearance, you can choose *NOHRI and add another line in the printer file to print the human readable characters.
The *AST parameter is a little confusing. The 3 of 9 symbology uses an asterisk as a start/stop character. It appears that the *AST parameter affects only the human readable data. If you specify *NOAST, the barcode itself will contain the asterisks at the beginning and end, but the human readable characters will not. If you specify *AST, the barcode remains the same, but asterisks are placed at the beginning and end of the human readable data.
The Check digit parameter is used to indicate if a check digit or multiple check digits should be generated. The OS/400 DDS Reference specifies if check digits are generated by default and for which symbologies they are generated. By default, a Modulus 10 check digit is generated for the interleaved 2 of 5 symbology. If you decide to let the system generate a check digit for you, you should be sure that the check digit generated is correct. If you do not want a check digit generated automatically, use X’01’ for the check digit parameter. If you want to generate a check digit for a barcode that does not automatically generate a check digit, enter X’02’. Care should be taken when using this parameter. User-defined check digits are not checked for validity and could cause barcode errors if they are not valid. The Intelligent Printer Data Stream Reference manual contains more information on barcodes and valid check digits.
Unit Width and Wide/Narrow Ratio can be used in conjunction to scale the barcode to a desired size or to conform to a customer’s specification. Unit Width is specified in inches and determines the width of the narrow bar. This is sometimes referred to as the X dimension. The OS/400 DDS Reference states that the valid values are from .007 to .208. On my printer, though, I receive a barcode specification check exception error if I specify a value higher than .039. This shouldn’t pose a problem because a seven-digit barcode, using 3 of 9 with a width of .025 and a ratio of 2.5 will generate a barcode a little over 3” long. These dimensions should allow you to create a barcode that will fit most, if not all, of your needs.
The value .007 will generate a barcode that is quite small. While you may be able to scan this size of barcode with a good quality laser scanner, you may not be able to scan the barcode with a wand. If the barcode is for internal use only, it shouldn’t pose a problem. If you are generating barcodes to be used by your customers, care should be taken to ensure the barcode conforms to their specifications.
The Wide/Narrow Ratio is pretty straightforward. The valid values are from 2.00 to
3.00. The narrow bar size is simply multiplied by the ratio to determine the width of the wide bars and spaces.
Figure 3 shows an example of an interleaved 2 of 5 barcode printed vertically, 1/2” high, with the human readable data on top of the barcode. The width of the narrow bar is
.010”, with a ratio of 3 to 1. By default, the check digit will automatically be generated. For the most part, using *IPDS to print barcodes from your AS/400 is fast and easy. The ability to specify the narrow bar width and the ratio makes the barcode scalable, giving you the ability to print the barcode in a wide variety of sizes. This makes it easier to print the barcode on the page in the allotted space. Some positioning is required, because the barcode will not necessarily start in the desired position. The spacing is based upon the current font being used.
IPDS cards are available for a wide variety of laser printers as well as certain dot matrix printers, such as the IBM 6400 series. IPDS interfaces can be purchased from third- party vendors or directly from IBM. They can be a little cost-prohibitive, though, with prices ranging anywhere from $900 to $1,300 per printer. While IPDS is proprietary, it has been around for quite a few years and, as of yet, shows no signs of disappearing.
Make the Most of Your Current Printers
What if you already have laser printers installed and would like to use them without the expense of purchasing IPDS cards? How do you handle remote printing using TCP/IP? One option would be to purchase a font cartridge or a SIMM that would install directly onto the printer. You can also purchase controllers that attach through the parallel cable. Prices range from $200 to around $700. You’ll want to ask a lot of questions before buying these products to make sure they are compatible with your brand of printer.
Some of the lower-priced SIMM modules contain bitmapped fonts that are not scalable and provide only a few different narrow bar sizes and a couple of ratios. If you have a limited amount of space in which to print your barcode and your SIMM does not allow scaling of the barcode, you may be disappointed when you are unable to fit the barcode on the page in the allotted space. Some more expensive SIMMs function similarly to the BARCODE keyword. You specify the symbology and the width and ratio. Some of these SIMMs have built-in intelligence for creating check digits.
One advantage of bitmapped SIMMs is that they will not allow you to print a barcode that is out of spec. One company I worked with, Intercon Associates, states it would be able to burn a different size barcode onto its SIMM if you supplied the specifications. Some of the more expensive modules may be easier to use because they allow you to use the carrot (^) symbol to select the barcode to print. Lower-priced SIMMs and those designed specifically for PC applications will require you to send an escape sequence to the printer to change fonts.
SIMMs or font cartridges also allow you to print barcodes from non-AS/400 devices. If you need to print barcodes from your PC, this would be something to consider. There are disadvantages to using this method. It does require extra coding and setup in your application programs. And of course you cannot receive support from IBM if you encounter problems during setup. IBM does provide some support for Workstation Customization Objects (WSCST) and ASCII transparencies, but if the project starts to
become involved, IBM may ask you to sign a support contract and assign a consultant to your project.
Let’s say you decide to purchase and install a SIMM in your printer. Your next task is getting it to work correctly. If the particular SIMM you purchase requires you to send an escape sequence to change fonts, you will be required to send an ASCII hex 1B to the printer through the print stream.
I will explain in detail a couple of methods for doing this. Either you can create a WSCST for the printer and include an ASCII translation table, or you can send transparent ASCII data through the print stream.
(For more information on printing, see the November 1997 issue of Midrange Computing, which offers five articles about printing in its Focus section.)
Customize Your Output
First, I’ll explain what a WSCST is and the steps involved in creating and using it. A WSCST allows you to alter the way the AS/400 supports local or remote displays and printers. Some of the printing functions you can change are special character support, bold and underlining, font and pitch support, and paper size and orientation. Once the WSCST is created and modified to meet your specific needs, it can be attached to a printer, or several printers may use the same customization object. I will explain the basic steps, but you should also read the chapters pertaining to ASCII printing in OS/400 Workstation Customization Programming.
To create the WSCST, use the Retrieve WSCST Source (RTVWSCST) command, as shown in Figure 4. RTVWSCST will create a source member that you can edit and compile.
Enter *TRANSFORM for the DEVTYPE prompt. This will allow you to select the manufacturer type and model of printer you have. If you prompt on the manufacturer type and model field, you will be able to select your printer from the supplied list. If your printer is not listed, you may be able to use a generic HP. (Consult your printer manual to determine if your printer emulates an HP.) Enter the name of the source member, file, and library. By default, IBM will store the source member in QTXTSRC in library QGPL, but you may save it anywhere you like.
After you have retrieved the WSCST, you need to edit the source member. This part is a little tedious, but you will have to do it only once. Enter the code and translation table in Figure 5 after the line containing :EASCCPINFO.
You will want to double-check the translation table after you key it in. Any mistakes here will cause unpredictable results in your printer output. Also pay particular attention to the syntax. A misplaced colon or period will result in errors when you attempt to compile the WSCST.
The body of the table contains the ASCII translation of EBCDIC data. The first EBCDIC character is represented by the first character (4) in the right-hand column. The second character is read from the top row, -0-1-2, etc. The first EBCDIC character is X’40’, which is translated into ASCII X’20’. Change the EBCDIC X’5F’, which is the
logical not (¬), from x’AA’ to x’1B’. The EBCDIC ‘5F’ is located on the second line down from the top in the last column on the right in the translation table. Hex 1B is the signal to the printer that the string of data following it is a printer control command.
After you have made these changes, you need to create the WSCST using the Create WSCST customization (CRTWSCST) command (see Figure 6).
End the print writer and assign the WSCST to the printer with the following command:
CHGOUTQ OUTQ(name) MFRTYPMDL(*WSCST) WSCST(library/name)
When you restart the writer, output generated from your AS/400 will be using the WSCST you just created. Send a few reports to the printer to test the output.
The next step would be to modify your RPG program to send an escape sequence to the printer to generate the desired barcode font. After you install the chip into the printer, you are able to generate a font listing from the control panel of the printer. The escape sequences should be listed next to the barcodes they produce. In this case, the font ID for an AIAG 3 of 9 barcode is F10. The escape sequence is listed as
After you have printed the barcode, you will need to issue an escape sequence to set the font back. If you are not sure which font the printer is using, you could either experiment to find the correct font or change the font before you generate any output. Most of the time, the printer will be using a courier font, as this is a fixed pitch font available on most HP and HP-compatible printers. You will need to experiment with the pitch to get the correct character size, but 13.3 would be a good place to start.
Transparent but Not Invisible
An alternative to creating the WSCST is to send ASCII-transparent data through the print stream. The advantage to this method is the reduced setup, but one disadvantage is that the escape sequence must be converted to ASCII hex by the programmer. The printer file must be created with the Unprintable character action as RPLUNPRT(*NO). This parameter specifies what action should be taken when encountering an unprintable character. By setting the parameter to *NO, the AS/400 will not try to replace the ASCII data with blanks. (The default for the replacement character is ‘ ‘. A character could be substituted.)
If at all possible, you should use RPG IV. With ILE, you can define a constant to contain the ASCII hex data. Without ILE, you would have to use the BITON and BITOFF operation codes to create the ASCII data. Figure 7 contains the ILE code to create a constant to generate the same barcode as used in Figure 2.
What this code does is create a field named Font1 that contains the necessary ASCII hex data to change to a barcode font. Because the AS/400 is an EBCDIC system, you must precede the ASCII stream with two characters that instruct the system to send the string to the printer unconverted. X’03’ is the first character that tells the AS/400 that an ASCII stream is to follow. X’17’ is the length of the string in binary (the length of the string is 23 bytes, which, converted to binary, is X’17’).
The next character is X’1B’, or the printer escape character. Because we are changing the symbol set and the font, we actually have two escape sequences strung together. Using ASCII transparency, we simply write the field Font1 as an output field to our printer file. Any data sent to the printer after field one would be converted into a barcode. To change the font back to a Courier font using the IBM PC-8 symbol set and a pitch of 13.3, we could use the code example in Figure 8.
Any necessary instruction can be sent to the printer using ASCII transparency. Care must be taken to avoid overlapping the fields used to send escape sequences with fields that contain data. An easy way to accomplish this is to place the constants on a line by themselves without spacing before or after. The AS/400 will send the data to the print queue followed by a carriage return and line feed instruction. This will keep your data from
being overlayed. The example in Figure 9 changes the font to the barcode font, sends the data to be barcoded, and changes the font back to a Courier font at 13.3 pitch.
As with anything new, it will take some experimenting to get the desired output. After you get the hang of it, though, the task will not seem that difficult. If you get stumped, you can always place the printer in hex dump mode to view the exact output the printer is receiving. The printer can always be reset to the default menu settings by powering it off and on.
One way to approach this would be to start small. Start by creating a program that prints just a barcode. From there, you can add different functions until you achieve the desired results. When you’re finished, you can add the code to an existing application that may require a barcode.
I prefer the transparency method over the WSCST. The WSCST will affect all output sent to the OUTQ, whereas the ASCII transparency will affect only the job that is running. The WSCST could introduce other problems with text size and spacing. Instead of hard coding the ASCII transparency date in the ILE program, a file could be created to store the transparency data so that it may be used easily by several programs. A program could be created that will allow you to enter the escape sequence and convert it to ASCII hex.
Which Method Is the Best?
So what is the best way to print barcodes from your AS/400? It really depends on the amount of time or money you want to spend. Using IPDS-capable printing is about as easy as it gets. The barcodes are completely scalable, allowing a wide variety of sizes to be printed. Because not all printers are IPDS-capable, you may have to either add a SIMM module to an existing printer or replace the printer entirely. Because the AS/400 is so flexible, you may find that there isn’t one right answer. Perhaps a combination of several different methods is the best solution for your organization.
References Intelligent Printer Data Stream Reference (S246-0148-00) OS/400 DDS Reference V3R2 (SC41-3712-01, QBKAUI02) OS/400 Workstation Customization Programming V3R2 (SC41-3605-1, QBKAQ602)
Figure 1: The barcode keyword parameters
A R HDG
A ORDER# 7A 39
A BARCODE(CODE3OF9 3)
Figure 2: Printing a 3 of 9 barcode using the defaults
A R HDG
A @ORD 13S 0 39
A BARCODE(INTERL2OF5 3 *VRT +
A *HRITOP (*WIDTH .010)
A (*RATIO 3.00))
Figure 3: Example of an interleaved 2 of 5 barcode
Retrieve WSCST source (RTVWSCST)
Type choices, press Enter.
Device type . . . . . . . . . . > *TRANSFORM *TRANSFORM, 3101, 3151...
Manufacturer type and model . . > *HP4
Source member . . . . . . . . . ITHP4 Name
Source file . . . . . . . . . . QTXTSRC Name
Library . . . . . . . . . . . QGPL Name, *CURLIB, *LIBL
Text ‘description’ . . . . . . . ‘HP Printer in Info Tech Department’
F3=Exit F4=Prompt F5=Refresh F12=Cancel F13=How to use this display
Figure 4: The Retrieve Work Station Customization Object (RTVWSCST) command
EBCDICCP = 37
ASCIICP = 437
/* -0-1-2-3-4-5-6-7-8-9-A-B-C-D-E-F */
‘2020838485A0A68687A49B2E3C282B7C’X /* 4- */
‘268288898AA18C8B8DE121242A293BAA’X /* 5- */
‘2D2F833E85A0A68F80A57C2C255F3E3F’X /* 6- */
‘6F9088898AA18C8B8D603A2340273D22’X /* 7- */
‘ED616263646566676869AEAF647900F1’X /* 8- */
‘F86A6B6C6D6E6F707172A6A791009200’X /* 9- */
‘E67E737475767778797AADA844590000’X /* A- */
‘5E9C9DFA001514ACAB005B5D00DB27DD’X /* B- */
‘7B41424344454647484900939495A2A7’X /* C- */
‘7D4A4B4C4D4E4F50515200968197A398’X /* D- */
‘5CF6535455565758595AFD939995A2DC’X /* E- */
‘3031323334353637383900969A97A300’X. /* F- */
Figure 5: ASCII to EBCDIC translation table
Create WSCST (CRTWSCST)
Type choices, press Enter.
WSCST name . . . . . . . . . . . > ITHP4 Name
Library . . . . . . . . . . . > QGPL Name, *CURLIB
Source member . . . . . . . . . *WSCST Name, *WSCST
Text ‘description’ . . . . . . . *SRCMBRTXT
Source file . . . . . . . . . . QTXTSRC Name
Library . . . . . . . . . . . QGPL Name, *CURLIB
Authority . . . . . . . . . . . *LIBCRTAUT Name, *LIBCRTAUT, *CHANGE...
Replace object . . . . . . . . . *YES *YES, *NO
F3= Exit F4=Prompt F5=Refresh F12=Cancel F13=How to use this display
Figure 6: The Create Work Station Customization (CRTWSCST) command
D Font1 C CONST(X’03171B2830591B28733070342ED 363968323476307330623054’)
Figure 7: ILE constant to create a 3 of 9 barcode using ASCII Transparency
D Font2 C CONST(X’03161B283130551B2873307031-
Figure 8: Using ASCII Transparency to change the font to Courier
O E DPRNT1 0
O Font1 25
O E DPRNT1 0
O E DPRNT1 1
O Font2 25
Figure 9: Printing the barcode and resetting the font