Printing Barcodes with MAI OpenBasic
Barcode Basics >
Application Notes >
MAI OpenBasic systems often used a line printer equipped with a special internal module to
print barcodes. These printers are no longer available, and as they succumb to old age
they must be replaced with currently-available printers which do not support the same
barcode command syntax. Barcodes can be printed on laser printers with a little
modification of the OpenBasic application software.
The first solution involves adding a BarDIMM module to a Hewlett-Packard LaserJet printer.
Product and programming details can be found at
This solution is effective and relatively easy to implement; all of the complicated
calculations and formatting are done in the BarDIMM, so the OpenBasic code changes are
relatively simple. The downsides are that the BarDIMM works only with Hewlett-Packard
printers and that one module must be purchased for each printer; this is not too bad for
one printer, but can get expensive if several printers are involved.
The second solution involves downloading a PCL barcode font to a laser printer; the
particular brand of printer does not matter, as long as it is compatible with the PCL-5
printer command language (most laser printers are). Here is a link to information
(including downloadable manual and demonstration versions) for several PCL font kits and,
for heavy-duty users, a font generator program:
The downloadable manuals go into a fair amount of detail on using the PCL fonts. The
remainder of this article will deal with using Code 39 and Code 128 with OpenBasic.
Code 39 (info at
is an excellent general-purpose barcode that can contain letters and numbers and is very
easy to use. To download a font, simply copy it to the printer's port; it is best to do
this just before running a print job that will require barcodes. To modify the OpenBasic
code which generates the report, first remove the barcode instructions for the old
printer; there will typically be a command to start the barcode followed by the data, then
finished with a command to stop the barcode. Add new code to select the correct PCL
barcode font, print the data, and then switch back to a regular text font.
The following example assumes that the printer is attached to Port 6 and that the data we
wish to print is in OUTS$. The string BARON$ is set to an escape sequence that selects
font number 25501 (each font in a PCL font kit has a different ID number, so any font can
be downloaded and selected by number; use the ID number which is embedded in the
particular font you wish to use). The string BAROFF$ is loaded with an escape sequence
that switches back to the printer's default font (typically Courier). Asterisks are added
before and after the data to represent the start/stop characters required by the barcode
Note: It is important to send the final string to the printer in a single instruction to
prevent the system from inserting any extra characters while the barcode font is still
active. With some types of barcodes a control code (carriage return, for example) can be
printed as a barcode character.
10000 LET BARON$=CHR(27)+"(25501X"
10002 LET BAROFF$=CHR(27)+"(3@"
10004 LET OUTS$=BARON$+"*"+OUTS$+"*"+BAROFF$
10006 PRINT (6)OUTS$
Code 128 (info at
includes upper and lower case alpha characters, numbers, all the standard ASCII symbols,
and all of the standard ASCII control code. Formatting a Code 128 barcode is more complex
because, unlike Code 39, it requires calculation of a checksum. In the example below the
barcode will be printed using Code 128 "Subset B'; this is the most commonly-used
subset which includes all of the standard printable ASCII characters. Subset A includes
the control codes, and Subset C provides a means for compressing all-numeric data into a
more compact barcode. Details on the different subsets can be found in the manuals for the
PCL Barcode Font Kits and Font Generator referenced above. We will stay with Subset B in
this example for simplicity.
The lowest ASCII value for a printable character is 32 (space); in the Code 128 character
set, this is character 0. When calculating the checksum, the Code 128 values are used; to
convert to a printable ASCII character we have to add 32. The Code 128 value of the Start
Subset B character is 104 (printed as ASCII 136), and the value of the Stop character is
106 (printed as ASCII 138). More excruciating detail is available in the PCL Font manuals,
At line 10026 in the example we are formatting a Transparent Print command. This
instruction tells the printer that the next X number of characters are to be printed, and
not interpreted as command characters. This is very important with Code 128 since it is
perfectly possible for a checksum to work out to the same value as the Escape code. The
Transparent Print command prevents the printer from accidentally interpreting a checksum
as a command character.
00100 REM PRINT "HELLO" AS A BARCODE
00102 LET OUTS$="HELLO"
00104 GOSUB 10000
00106 REM CONTINUE WITH REST OF APPLICATION
10000 REM *** SET UP ESCAPE SEQUENCES TO TURN BARCODE ON AND OFF
10002 LET BARON$=CHR(27)+"(25501X"
10004 LET BAROFF$=CHR(27)+"(3@"
10006 REM *** CALCULATE CHECKSUM BEGINNING WITH START CHAR
10008 LET CHECK=104
10010 LET MULTI=1
10012 FOR XYZ = 1 TO LEN(OUTS$)
10014 LET CHECK=CHECK+((ASC(OUTS$(XYZ,1))-32)*MULTI)
10016 LET MULTI=MULTI+1
10018 NEXT XYZ
10020 REM *** DO MODULO 103 DIVISION TO GET FINAL CHECKSUM
10022 LET CHECK=MOD(CHECK,103)
10024 REM *** FORMAT TRANSPARENT PRINT ESCAPE SEQUENCE
10028 REM *** BUILD THE FINAL STRING
10032 REM *** SEND IT TO THE PRINTER
10034 PRINT (6)OUTS$
The result should be a perfect Code 128 barcode. Other AppNotes on Code 128 checksum
calculations can be found at http://www.makebarcode.com/info/appnote/app_001.html