Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/rhalkyard/plotadapter

Serial-GPIB converter for HP plotters
https://github.com/rhalkyard/plotadapter

Last synced: about 1 month ago
JSON representation

Serial-GPIB converter for HP plotters

Awesome Lists containing this project

README

        

# PlotAdapter: Serial-GPIB converter for HP Plotters

## Introduction

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.

## Getting Started

### Hardware

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)

### Software

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](https://github.com/rhalkyard/hpplot) for
this purpose.

### Building `plotadapter`

1. Open `plotadapter.ino` in any recent version of the Arduino IDE

2. Using the Library Manager (Tools ➡ Manage Libraries...), install the
"FreeRTOS" library

3. Open `config.h` and edit the pin definitions, plotter address, and other
parameters to suit your setup.

## Notes

### Plotter Models

I wrote this project for my HP 7470A, but there is no reason this shouldn't work
for other similar plotters in the series.

### Software Architecture

`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](http://dunkels.com/adam/pt/) 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.

### Features

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` or `XON`/`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 of `0` instead)

* Plotter enable/disable with `ESC . (` and `ESC . )`

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 returns `0`)

* Emulation of Circle and Arc HPGL commands that are present on RS232-equipped
7470As, but not on GPIB models.

### Flow-Control Limitations

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 with `ESC . B`
before sending)

### GPIB Bus limitations

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.