Older Hewlett-Packard pen plotters usually had an RS232 interface, but they were also available with GPIB (a.k.a. HP-IB, a.k.a. IEEE-488), a popular interface for laboratory equipment, also seen on HP's own 9800 series of computers.
While GPIB interfaces are still available, both as (expensive) commercial products and as open-source hardware, they are not well-suited to the task of controlling a plotter - most PC software expects to talk to a plotter over a serial port, not the VISA APIs typically used by GPIB adapters. Additonally, many of the serial-port-based GPIB adapters are more suited to instrument-control applications - sending and receiving short commands and responses - and as such lack the flow-control mechanisms needed for successful plotter operation.
Furthermore, HP's RS232 plotters supported a wide range of serial handshaking
options, and implemented an additional set of escape sequences to configure
this. Many applications send these escape sequences before and during plotting,
and expect the plotter to respond accordingly - for example, HPGL plots
generated by Autocad contain escape sequences to put the plotter into
XON
/XOFF
handshaking mode.
PlotAdapter aims to emulate this extended command set, allowing a GPIB plotter to be 'converted' to an RS232 interface and used by software that expects to communicate with an RS232-connected plotter.
You will need:
-
An HPGL plotter with a GPIB interface (e.g. a 7470A with Option 002)
-
An AVR-based Arduino with 5 volt IO and 14 available pins (I am using a Mega 2560)
-
A GPIB cable with some way of connecting it to the Arduino
-
(optional) a USB-serial interface with support for serial handshaking (see "Flow Control Limitations" section below for details)
It is crucial to use some form of flow control when sending data to the plotter.
Many plotter operations are time-consuming, and without flow control, it is very
likely that a buffer overrun will occur. This is complicated by the fact that
the driver for the Arduino's USB-serial interface does not handle XON
/XOFF
flow-control correctly.
The best way to send data to the plotter is to use a dedicated program that is aware of the plotter's escape sequences, and can set up a workable flow-control configuration itself. I wrote hpplot for this purpose.
-
Open
plotadapter.ino
in any recent version of the Arduino IDE -
Using the Library Manager (Tools ➡ Manage Libraries...), install the "FreeRTOS" library
-
Open
config.h
and edit the pin definitions, plotter address, and other parameters to suit your setup.
I wrote this project for my HP 7470A, but there is no reason this shouldn't work for other similar plotters in the series.
plotadapter
is implemented as a pair of tasks running on FreeRTOS -
serial_task
reads bytes from the serial port, handles escape sequences, and
inserts received data into a ring buffer. gpib_task
reads data from the ring
buffer, and transmits it via a very crude bit-banged GPIB implementation.
gpib_task
also monitors the data stream for HPGL commands that are known to
generate output (any command beginning with O
- OI
, OE
, OD
, etc.). When
an output command has been sent, it sends a GPIB TALK
command to the plotter
and waits for a response, which it sends to the serial port.
If a GPIB operation times out (the timeout is configurable as GPIB_TIMEOUT
in
config.h.
, default is 30 seconds), the bus is reset by asserting IFC
, the
command buffer is purged, and gpib_thread
is restarted. This also occurrs if
the "Abort Output" escape sequence ESC . K
is received.
In hindsight, FreeRTOS is probably overkill for a simple project such as this, and it could be rewritten using protothreads or even just as a plain event loop. However, implementing GPIB and serial IO as two independent tasks made it easier to reason about their interactions, and allowed the GPIB implementation to be a simple piece of procedural code, rather than a convoluted state machine. I regret nothing.
The following RS232 interface features are supported:
-
DTR flow control (when using an external serial adapter)
-
Echo mode setting with
ESC . @
(echo off, immediate echo, echo when character processed) -
Reporting available buffer space with
ESC . B
-
Reporting total buffer size with
ESC . L
-
Software low control (either
ENQ
/ACK
orXON
/XOFF
) using Handshake Modes 1 (ESC . H
) or 2 (ESC . I
) - see section below on limitations -
Output-initiator and output-terminator characters
The following features are NOT supported due to architectural limitations:
-
Reporting plotter status with
ESC . O
(querying plotter would interrupt HPGL command stream - returns status byte of0
instead) -
Plotter enable/disable with
ESC . (
andESC . )
The following features could be supported but I'm too lazy right now
-
Inter-character and turnaround delay
-
Echo-terminator and output-trigger characters
-
Reporting RS232 error status with
ESC . E
(currently always returns0
) -
Emulation of Circle and Arc HPGL commands that are present on RS232-equipped 7470As, but not on GPIB models.
The driver for the onboard USB-Serial converter appears to ignore XON
/XOFF
flow-control. Since we cannot use DTR flow control either, this needs to be
worked around by either:
-
Attaching an external USB-serial interface (with funcitoning flow control) to the Arduino's serial pins
-
Configuring/rewriting the application to use an alternate form of flow control (either
ENQ
/ACK
or by checking available buffer space withESC . B
before sending)
This is not a fully-compliant GPIB implementation by any means - it works OK if the plotter is the only device on the bus, but it will probably not be able to drive a longer bus, and may not coexist well with other devices anyway.