Link to home
Start Free TrialLog in
Avatar of johnsit
johnsitFlag for United Kingdom of Great Britain and Northern Ireland

asked on

New to printer control codes on HP-UX

Hi,

Please forgive my ignorance, Im new to the world of HP-UX and unix.

Im trying to work out exactly how printer control codes work.

I have setup a test printer with our default interface file which works (using lp command).

I have then found a control code that is use elsewhere in our org (its actually in some progress DB code) which is working and outputs the job to A5 and to tray 4, (the code is \033&l25a5H\033(s12.5H which works fine).

I have then placed the code in a test file, containing nothing but,

\033&l25a5H\033(s12.5H   This is a test

However when testing the file with the lp command, the control code is simply printed instead of obeying the codes. Can anyone think why this could be the case?

Thanks much in advance for any feedback.
Avatar of Steven Carnahan
Steven Carnahan
Flag of United States of America image

Try this:

echo "\033&l25a5H\033(s12.5H"  
This is a test
Several points:

\033 is a graphic representation of the non-graphic Escape control-code character (the character with decimal code 27, or hexadecimal 1B, or octal 033)

... testing the file with the lp command ... might indicate that the file has been processed in some way by the (fairly primitive) *n*x spooler/model script mechanism, which may have removed control-code characters.

What you want to do instead is send the contents of the file directly to the printer port; I'm very rusty with *n*x, so can't really advise, but perhaps cat or even lpr (provided that you can specify the destination printer without the request being processed by lpsched or similar).
... and an interpretation of your PCL snippet:


<Esc>&l25a        Page Size: A5
       5H         Paper Source: id 5 is Printer Dependent
<Esc>(s12.5H      Primary Font: Pitch (12.5 characters per inch)

Open in new window


Note:

The value in the Paper Source sequence is printer -dependent (i.e., it will work on one model of printer, but it is possible that you will require a different value on a different device).
The Pitch sequence will only work if the current selected primary font is a fixed-pitch font (Courier and Letter Gothic are the only standard fixed-pitch printer-resident fonts on most LaserJet printers).
... to select fonts successfully, you ideally need to specify all of the required font characteristics; for example, to select the Courier Regular (Upright, Medium) font with a pitch of 12.5 characters-per-inch, using the ISO-8859-1 Latin-1 symbol set, use:
 
<Esc>(0N<Esc>(s0p12.5h0s0b4099T

where <Esc> represents the escape control-code character.

This is interpreted as follows:

<Esc>(0N          Primary Font: Symbol Set (0N = ISO 8859-1 Latin 1)
<Esc>(s0p         Primary Font: Spacing: Fixed
       12.5h      Primary Font: Pitch (12.5 characters per inch)
       0s         Primary Font: Style (Upright, solid)
       0b         Primary Font: Stroke Weight: Medium
       4099T      Primary Font: Typeface (4099 = Courier)

Open in new window

SOLUTION
Avatar of Michael Dyer
Michael Dyer
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
... and the following link provides a brief history of the PCL language, and links to the PCL5 Technical Reference manual (as per above), and also to other PCL5 & PJL manuals:

http://h20000.www2.hp.com/bizsupport/TechSupport/Document.jsp?objectID=bpl04568 

Be aware that some of the manuals (in PDF format) are multi-megabyte downloads.
Avatar of johnsit

ASKER

Thanks for all the great info,

Firstly, the,
echo "\033&l25a5H\033(s12.5H"   
This is a test 

Open in new window

Unfortunately didnt work, again the text was simply printed, I have noticed however that there is a preceding page printed with "option summary" but that may be beside the point as the control code is still printed.

I think one of the major points mentioned,

... testing the file with the lp command ... might indicate that the file has been processed in some way by the (fairly primitive) *n*x spooler/model script mechanism, which may have removed control-code characters.
could be the reason as the file is passing through (what we call) an interface file (again, sorry, Im new to Unix) which contains the following,

#!/usr/bin/sh

# (c) Copyright 1992, 1993, 1994 Hewlett-Packard Company.  All Rights Reserved.

# $Header: /users/hpnp/odyssey/repository/sh/hpnp.model.psh,v 1.1.1.1 2001/10/15 19:15:34 hpnp Exp $
#
# HP HPNPL Utility for Unix, HP-UX Network Printer Control Script
# This script invokes the original model script from the 
# subdirectory model.orig and pipes its output to hpnpf.

if echo $PATH | grep "/usr/bin" > /dev/null 2>&1
then
  :
else
  PATH=$PATH:/usr/bin
  export PATH
fi

# Add bin to the path for systems with /bin
if [ -d /bin ]
then
  PATH=$PATH:/bin
fi

HPNP=/opt/hpnp

# [Modified by Kumaresan for JPIU on 26th Sept '99.
HPNP=/opt/hpnpl
# ]

# [ Modified by Amit R. Raval to handle the remote printing capability on June
# 24th 1998.

    BIN=/usr/bin

# ]

MODEL=`basename $0`
REALMODEL=`echo $0 | sed -e "s%$MODEL%model.orig/$MODEL%"`

HPNPBIN=$HPNP/bin

TMP=/var/tmp

# [ Modify by the Amit R. to solve the problem of security on 20th Feb. 1998

ID=/usr/bin/id
CUT=/usr/bin/cut
AWK=/usr/bin/awk

         MKDIR=/usr/bin/mkdir

USERNAME=`$ID | $CUT -f1 -d" " | $CUT -f2 -d"(" | $CUT -f1 -d")"` # get user name

if [ $USERNAME = "root" -o $USERNAME = "lp" ]
then
   TMP=$HPNP/tmp
else

   /usr/bin/sun > /dev/null 2>&1
   if [ $? -eq 0 ]
   then
# [ Modified by Amit Raval to fix the defect#57434 on 20th Apr. 1999
#   HOME=`$AWK  'BEGIN   { FS=":" }
#         {if ( $1 == UNAME) print $6 ; }' UNAME=$USERNAME /etc/passwd`   # get home dir. from /etc/passwd 

   JAHOME=`$AWK  'BEGIN   { FS=":" }
         {if ( $1 == UNAME) { print $6 ; exit } }' UNAME=$USERNAME /etc/passwd`   # get home dir. from /etc/passwd 
# ]
   else
# [ Modified by Amit Raval to fix the defect#57434 on 20th Apr. 1999
#   HOME=`$AWK -v UNAME=$USERNAME 'BEGIN   { FS=":" }
#         {if ( $1 == UNAME) print $6 ; }' /etc/passwd`   # get home dir. from /etc/passwd 

   JAHOME=`$AWK -v UNAME=$USERNAME 'BEGIN   { FS=":" }
         {if ( $1 == UNAME) { print $6 ; exit } }' /etc/passwd`   # get home dir. from /etc/passwd 
# ]
   fi

   if [ -z "$JAHOME" ]  # Handle the NIS issue
   then
      JAHOME=$HOME      # Assign the env veriable HOME if JAHOME is null.
   fi


# [Modified by Kumaresan for JPIU on 26th Sept '99.
   if [ ! -d $JAHOME/.jpiu ]
   then
      $MKDIR $JAHOME/.jpiu > /dev/null 2>&1
      if [ $? -eq 0 ]
      then
        TMP=$JAHOME/.jpiu
      fi
   else
        TMP=$JAHOME/.jpiu
   fi
fi

# ]

rm -f $TMP/hpnp.$$

LOG=$TMP/hpnp.$$
HPNPF=$HPNPBIN/hpnpf
LPLOG=/var/adm/lp/log
HPNPFLOG=""
debugf=""

PRINTERCFG=/opt/hpnpl/admin/printers/267.cfg
JRECOV="yes"
SLEEPSEC=20

LOGTRIES=1
ERRORLOGS=0

# [Modified by Kumaresan for JPIU on 26th Sept '99.
MANPATH=$MANPATH:/usr/lib/hpnp/man:/opt/hpnpl/man
# ]
export MANPATH

# xPORT, PERIPH, TEOJ are all configurable
xPORT=
PERIPH=test
# [ Follwing variable is added by suresha to fix the correct display of
# model script name in modifing queue on 10th March 2000
MODELSCRIPTNAME=net_ljx000
# End of change by suresha ]
DEVTYPE="PJL"
TEOJ="-w"
STATUSLOG=""
HPNPFOPT=
TOJMON=""
ONUSTATUS=""

# job monitor related
# [ ifndef and endif added by suresha(not supported jobm in NPIU)
# End of change by suresha ]
userjobm="yes"
jstay=""
defdsplay="`uname -n`:0"
dsplay=""
dsplayfile="$HPNP/etc/hpnpdisplay"
XJETMON=$HPNPBIN/xjjm
topazopt=""

if test ! -w $LPLOG
then
  LPLOG=/dev/null
fi
if [ -z "$PERIPH" ]  
then
  PERIPH=$MODEL
fi

  # [ Following line is added by suresha to fix print jobs last problem
  # on 10th March 2000
qname=`echo $1 | cut -d- -f1`
# End of change by suresha ]
job=$1
user=$2
title=$3
copy=$4
options=$5
shift; shift; shift; shift; shift
files="$*"

# changed the parsing of the x hostname from filename to fix defect #43080
# the value of dsplhost is set to be the end of 
# the filename.  the file name is of the form (dir)/dA1208(job#)(hostname)
# so the name of the host sending the job is whatever follows the job id 
# in the file name
#
file1="$1"
jobnum=`echo $job |  sed "s/.*-//`
dsplhost=`basename $file1  | sed "s/.*$jobnum//"`

PAGEF=$TMP/pg.${job}
rm -f $TMP/pg.${job}
#
# Remove the log file if job is cancelled
# or the scheduler is shutdown.
#
trap "rm -f $LOG $PAGEF;trap 15;kill -15 0;exit 0" 15

# [ Modified by Amit R. Raval to handle the remote printing capability on June
# 24th 1998.

# Handle the options of lpr 
remote_lpr() 
{

      if [ -n "$options" ]
      then
         for i in $options
         do
             case "$i" in
                   -oBSDJ*) # Handle the "-J" option.
		        title="`echo "$i" | $BIN/sed 's/-oBSDJ//'`";;

                   -oBSDC*)  # Handle the "-C" option.
		        tmpopts="`echo "$i" | $BIN/sed 's/-oBSDC//'`" # strip off -oBSDC
			if [ "$tmpopts" != "$syst" ]
			then
			    opts=$tmpopts
			fi ;;

                   -oBSD*) # Handle other options.
		        ;;

                        *)  
                        if [ "$opts" != "" ] # Avoid space in options variable.
                        then
                            opts="$opts $i" # get rest of options
                        else
                            opts="$i"
                        fi;;
              esac
         done

      fi

      options="$opts"

}

# ]

# [ Modified by Amit R. Raval to handle the remote printing capability on June
# 24th 1998.

echo "$options" | $BIN/grep  "\-oBSD" > /dev/null 2>&1

if [ $? -eq 0 ]
then
  remote_lpr
fi

# ]

# search for options
for i in $options
do
  case "$i" in
  # job, jobnp, jobp for bring job up if default is no
    job+[a-zA-Z0-9_:.]*)  
      dsplay="`echo "$i" | sed 's/job+//'`" 
      jobm="yes";;
    job)  
      jobm="yes";;
    jobnp)  
      jobm="yes"
      jstay="-nopersist";;
    jobnp+[a-zA-Z0-9_:.]*)  
      jobm="yes"
      jstay="-nopersist"
      dsplay="`echo "$i" | sed 's/jobnp+//'`";;
  # following two keep job monitor permanently
    jobp+[a-zA-Z0-9_:.]*)  
      dsplay="`echo "$i" | sed 's/jobp+//'`" 
      jobm="yes"
      jstay="-persist";;
    jobp)  
      jstay="-persist"
      jobm="yes";;
    # nojob prevent job comes up if default is up
    nojob*)  
      userjobm="no";;
    debugm[/.a-zA-Z0-9_]*)
      debugf="`echo "$i" | sed 's/^debugm//'`";;
    debugm)
      debugf=$TMP/$MODEL;;
    hpnpflog)
      HPNPFLOG="-l $TMP/hpnpflog"
      rm -f $TMP/hpnpflog
      touch $TMP/hpnpflog
      chmod 666 $TMP/hpnpflog;;
    relay)
      lang="RELAY";;
    topaz)
      if [ $copy -gt 1 ]
      then
        topazopt="-m"
      fi;;
  esac
done

if [ "$debugf" != "" ]
then
  rm -f "$debugf"
  touch $debugf
  chmod 666 $debugf

  if [ ! -w "$debugf" ]
  then
    echo "$debugf is not writable. write to $TMP/$MODEL."  >> $LPLOG
    debugf=$TMP/$MODEL
  fi
  $REALMODEL $job $user "$title" $copy "$options" $files > $debugf
  exit 0
fi

# if PJL device, turn on PJL ;
case "$DEVTYPE" in
  PJL) 
    ONUSTATUS="-a1";;
  PJLEX)
    ONUSTATUS="-a3";;
  *)
    if [ "$TEOJ" = "-w" ]  # it should not happen, but double check anyway
    then
      TEOJ=""
      echo "   Non PJL printer, turn off TEOJ" >> $LOG
    fi;;
esac

#Turn off USTATUS and TEOJ if relay mode
if [ "$lang" = "RELAY" ]
then
  ONUSTATUS=""
  TEOJ=""
fi

# bring Job Monitor up 
# env. variable DISPLAY does not apply
if $HPNPBIN/psbr
then                 
  if [ "$jobm" = "yes" -a -x "$XJETMON" ]
  then
    # settle where to display 
    if [ "$dsplay" = "" ]
    then
      # get from a file (not tested yet)
      if [ -s "$dsplayfile" ]
      then
        dsplay=`grep "^$user " $dsplayfile | cut -f2 -d" "`
      fi
      if [ "$dsplay" = "" ]
      then      # get display name from job's name

# changed parsing of hostname from filename to fix defect #43080
# the value of dsplhost is set earlier in the script to be the end of 
# the filename.  the file name is of the form (dir)/dA1208(job#)(hostname)
# so the name of the host sending the job is whatever follows the job id 
# in the file name
#
#        dfname=`basename $opt6`
#        cfname=`dirname $opt6`/c`expr match $dfname '\d\(.*\)'`
#        dsplay="`sed -n "/^H/s/H//p" $cfname`:0"

	    if [ -n "$dsplhost" ]
	    then
		dsplay="$dsplhost:0"
	    fi
        if [ "$dsplay" = "" ]
        then
          dsplay=$defdsplay
        fi
      fi
    fi

    FSIZ=`$HPNPBIN/fsize $files` 
    FSIZ=`expr $FSIZ \* $copy`
    if [ -n "$FSIZ" ]
    then
      TOJMON="-b $FSIZ"  
    fi
    if [ "$userjobm" = "yes" ]
    then
      echo "\t$XJETMON $dsplay $job &" >> $LOG
      $XJETMON -display "${dsplay}" $jstay $job 2>>$LOG &
    fi
  fi
else
  if [ "$jobm" = "yes" ]
  then
    echo "   hpnpd is not running, no job monitor" >> $LOG
  fi
fi

# pack all options for hpnpf,
HPNPFOPT="-j $job+$user $TEOJ $TOJMON $ONUSTATUS $xPORT -x $PERIPH $HPNPFLOG $topazopt"
if [ -n "$STATUSLOG" ]
then
# [ Modified by Amit Raval to fix the defect#57484 on Apr 21th 1999
#  rm -f "$STATUSLOG"
 if test ! -f $STATUSLOG
 then
# ]
  touch "$STATUSLOG"
  chmod 666 "$STATUSLOG"
# [ Modified by Amit Raval to fix the defect#57484  on Apr. 21th 1999
 fi
# ]
  HPNPFOPT="$HPNPFOPT -s $STATUSLOG"
fi

echo "\t$REALMODEL $options " >> $LOG
echo "\t$HPNPF $HPNPFOPT" >> $LOG

rm -f $PAGEF

while :
do
  #
  # Save the stderr messages in a temporary log file
  # and discard stdout which is the peripheral output.
  $REALMODEL $job $user "$title" $copy "$options" $files | $HPNPF $HPNPFOPT 2>>$LOG > /dev/null

  retcode=$?
 
  if [ "$retcode" -eq 0 ]
  then
  #
  # If the transfer is successful (0), remove
  # the log file and exit.
  #
    grep -v Warning $LOG | cat >> $LPLOG
    rm -f $LOG $PAGEF
    exit 0
  else
  # [ Following lines are added by suresha to fix print jobs last problem
  # on 10th March 2000
     if [ $retcode -eq 5 ]
     then
      grep -v Warning $LOG | cat >> $LPLOG
	  echo "disabling $qname" >> $LPLOG
	  disable $qname
      rm -f $LOG $PAGEF
      exit 3
	 fi
  # End of change by suresha ]
  #
  # Only record the first $LOGTRIES errors to avoid 
  # fill up spooler log 
  #

    if [ $retcode -eq 2 -o "$JRECOV" != "yes" ]
    then
      grep -v Warning $LOG | cat >> $LPLOG
      rm -f $LOG $PAGEF
      exit 2
    fi

  # 
  #    it is important to check if zero length string, i.e. no options
  #    append to the end of option, so that it won't be overridden
  #    page file exist only for pjl device, as a result, don't do this
  #    if device is not PJL (such as LJ3Si, LJ3,...)

    case "$DEVTYPE" in
      PJL | PJLEX )
        if [ -s $PAGEF ]
        then
          STARTPG=`grep "printed page" $PAGEF | cut -f2 -d: `  
# [Modified by Kumaresan on 9th Jan98 to fix the problem of setting
#  srbb option without page number in specific case.
	  if [ -z "$STARTPG" ]
	  then
# if only one page is printed, "printed page" will not be there in $PAGEF file.
# So, set STARTPG as 1. Otherwise nothing will be set with STARTPG and the srbb
# option will be sent without start page number.
		STARTPG="1"
	  fi
# ]

          if [ -z "$options" ]
          then
            options="srbb$STARTPG"
          else
            if [ "$ERRORLOGS" -eq 0 ]
            then     # first recovery
              options=`echo $options | sed -e "s/$options/$options srbb$STARTPG/"` 
            else 
              options=`echo $options | sed "/srbb/s/srbb[0-9]*/srbb$STARTPG/g"`
            fi
          fi
        fi;;
    esac
        # log it LOGTRIES times
    if test -s $LOG -a $ERRORLOGS -lt $LOGTRIES
    then
      echo "   Unable to finish the job, try to recover job $STARTPG" >> $LOG
    fi
    ERRORLOGS=`expr $ERRORLOGS + 1`
    sleep $SLEEPSEC
  fi
done

Open in new window


Which as far as I can tell is not stripping out the codes however Im not good enough at scripting to be 100% sure.

I will continue testing and report any findings here.

The eventual aim for this is to place the code in a bespoke program to print an interleaved 2 of 5 barcode in the middle of some text.

The details of the codes can be found here.

http://welcome.solutions.brother.com/bsc/public_s/id/htmldoc/printer/cv_hl4040cn/eng/html/ug/appendix11_3.html


Thanks again for the help so far
Avatar of johnsit

ASKER

OK, progress, I have managed to get the control codes working from inside the progress application, now if I could only find the correct control coder from the brother website.... the documentation is hard to follow for a simpleton newbie like me :)
 (http://welcome.solutions.brother.com/bsc/public_s/id/htmldoc/printer/cv_hl4040cn/eng/html/ug/appendix11_3.html)
The page you refer to includes some examples (using Basic, or something like that?).

For Interleaved 2 of 5, the example is shown as:

LPRINT CHR$(27);"it1r1s0o0x00y20b123456?\";

which appears to be constructing a string consisting of:

escape character (decimal 27)
i - this is some sort of sequence identifying character (although it does not follow the PCL syntax rules, and is proprietary to Brother)
t1 - bar code mode = "interleaved 2 of 5"
r1 - bar code includes human readable line
s0 - bar code style 3:1 (I think this might be the height/width ratio)
o0 - quiet zone = 0
x00 - horizontal offset = 0
y20 - vertical offset = 20
b123456? - bar code data (6 characters - filled to 10 numeric digits?) - ? represents a check-digit character
\ - (proprietary) sequence terminating character
Any feedback?
Avatar of johnsit

ASKER

Sorry for the delayed response.

I did see the examples but am unsure how to piece it all together.

In our example the escape char is \033 so would I try "\033\it1r1s0o0x00y20b123456?\" in the code?

Sorry to ask stupid questions but this is all very foreign to me.

I may call brother later for some feedback and will post here if I recieve any.

Thanks again.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of johnsit

ASKER

I think Im about there on this one.

FYI, the eventual used code was,

it1r1s0x00y00b67890123\ for without a check digit and,

it1r1s0x00y00b67890123?\ with a check digit, hence with the control code \033 they become,

\033\it1r1s0x00y00b67890123\ for without a check digit and,

\033\it1r1s0x00y00b67890123?\ with a check digit.

Dansdad, thanks, as ever your'e a gold mine when it comes to control codes. I feel 400 to you and 50 each to the other contributors is fair (shout if not :))

Big thanks to all!