blogng/blog/2019-02-23-resurracting-an-hp-7440a-plotter.markdown

178 lines
6.7 KiB
Markdown
Raw Normal View History

2019-03-09 19:40:18 +00:00
---
layout: post
2019-03-09 19:43:32 +00:00
title: "Resurrecting an old plotter"
2019-03-09 19:40:18 +00:00
date: 2019-02-23
comments: true
tags: plotter, art, python, hardware, recurse
---
2019-03-11 02:19:27 +00:00
I finally decided to give in to FOMO on
2019-03-09 19:40:18 +00:00
[#plottertwitter](https://twitter.com/hashtag/plottertwitter?lang=en) and bought
an old plotter off *ebay*. Being in batch at the [Recurse
Center](https://recurse.com) helped a lot: the old hardware laying around inspired the purchase, and a successful
[nerdsnipe](https://xkcd.com/356/) of [Alex](https://github.com/wildconceits) gave me a willing
collaborator. All of the work below was done with him.
2019-03-09 19:40:18 +00:00
## What is a plotter anyway?
2019-03-13 00:40:36 +00:00
Plotters are graphics devices that can transfer vector images onto a physical
medium. The core mechanism of a plotter is an arm that can move a pen in 2
axes (w.r.t the medium) and the ability to pick up or place down the pen to draw.
2019-03-11 02:19:27 +00:00
Versions of plotters exist where paper is replaced with other flat materials
like vinyl or pen with a knife to make it a cutting plotter.
2019-03-09 19:40:18 +00:00
I like to think of plotters as the naive solution to the problem that computers
2019-03-09 19:40:18 +00:00
should be able to draw. Smaller, expensive memory chips (or [magnetic
cores](https://en.wikipedia.org/wiki/Magnetic-core_memory)) in earlier computers
2019-03-11 02:19:27 +00:00
made working with raster images hard, and plotters didn't need much operating
memory.
2019-03-09 19:40:18 +00:00
2019-03-13 19:28:02 +00:00
## HP7440A
2019-03-11 02:19:27 +00:00
HP7440A _"ColorPro"_ was an affordable plotter manufactured by HP, it can hold
and switch between 8 pens simultaneously, and draw on surfaces as large as A4.
2019-03-11 02:19:27 +00:00
[HP Museum has a longer post about this
2019-03-09 19:40:18 +00:00
plotter](http://hpmuseum.net/display_item.php?hw=80)
2019-03-11 02:19:27 +00:00
Ours came pretty unscathed, with original manuals!
2019-03-09 19:40:18 +00:00
2019-03-11 02:19:27 +00:00
First thing we did was to open and clean it. I was quite surprised by how
2019-03-09 19:40:18 +00:00
easy it is to open, take that 2018 tech!
2019-03-11 02:19:27 +00:00
![7440A Top cover open](/images/7440a_open.jpg){ width=600px }
2019-03-09 19:40:18 +00:00
The internal mechanism is pretty simple. There are two servos. One for moving
2019-03-13 19:28:02 +00:00
the paper back and forward, and the other for moving the pen left and right.
There is also a solenoid-based lever to move pens to and from the paper.
2019-03-09 19:40:18 +00:00
## Talk To Me
2019-03-11 02:19:27 +00:00
![7440A Interfaces](/images/7440a_interface.jpg){ width=600px }
2019-03-09 19:40:18 +00:00
Our plotter didn't come with any cables to either power it or to send it
2019-03-13 19:28:02 +00:00
commands.
2019-03-09 19:40:18 +00:00
Puzzling out the power supply was the biggest mystery. After digging through the manuals and
[hand drawn schematics from the HP
Museum](http://hpmuseum.net/exhibit.php?hwdoc=80), we managed to identify it as
a `10-0-10` AC to AC. Luckily someone was selling one on *ebay*.
2019-03-09 19:40:18 +00:00
Communication turned out to be done using standard serial over a
`DB-22` adapter. We solved this by chaining a `DB-22` to `DB-9` adapter to a `DB-9` to
`usb` adapter.
2019-03-09 19:40:18 +00:00
2019-03-13 19:28:02 +00:00
The final step was writing in the only language the plotter can understand,
[`HP-GL`](https://en.wikipedia.org/wiki/HP-GL) or `HP Graphics Language`. Lucky
2019-03-13 19:28:02 +00:00
for us, HP was on top of the plotter game when plotters were popular, so `HP-GL`
has become a de facto standard for talking to plotters.
2019-03-13 00:40:36 +00:00
...and finally our plotter moves!
2019-03-09 19:40:18 +00:00
<video width="600" height="450" controls>
<source src="/images/7440a_printing.mp4" type="video/mp4">
2019-03-13 19:28:02 +00:00
</video>
2019-03-09 19:40:18 +00:00
2019-03-13 00:40:36 +00:00
## Goooooooo faster.
2019-03-09 19:40:18 +00:00
2019-03-11 02:19:27 +00:00
HP7440A has a limited amount of buffer space (about `60 bytes`), so if we send a
longer command list to the interface, it will drop all bits after 60 and crash.
2019-03-09 19:40:18 +00:00
Our first solution was to add `1s` sleep between sending subsequent
commands, however this made drawings really slow, and led to artifacts from
2019-03-13 00:40:36 +00:00
ink bleeding while the plotter is waiting for the next command.
Another Recurser, Francis, pointed us to a clever hack in the [wait function]
from [hpgl.js]. This function uses the HPGL command `OA;` to block execution
2019-03-13 19:28:02 +00:00
until the plotter is finished with the current instruction. When the plotter
executes `OA;` it sends the current pen position, but it first needs to
wait until the pen has stopped moving. Thus we can batch a bunch of commands
and append `OA;`; once we read the position from the serial,
we know that the previous batch is consumed and we can send the next batch.
2019-03-09 19:40:18 +00:00
2019-03-13 00:40:36 +00:00
[wait function]: https://djipco.github.io/hpgl/hpgl.js.html#line1535
[hpgl.js]: https://github.com/djipco/hpgl
2019-03-09 19:40:18 +00:00
The code for this trick looks like:
2019-03-09 19:40:18 +00:00
```python
import serial
# combine command together with maxlen buflen and expose as an iterator
def stitch(body, buflen=40):
start = ["IN;PU;", "SP1;"]
end = ["SP0;"]
final = start + body + end
## read in 20 bytes at a time or boundary
count = 0
buf = []
for ins in final:
if count + len(ins) >= buflen:
yield "".join(buf)
buf = []
count = len(ins)
else:
count += len(ins)
buf.append(ins)
# send rest of the code
yield "".join(buf)
# cmds is a list with semicolon attached to the command
def exec_hpgl(cmds):
port = "/dev/cuaU0"
speed = 9600
body = stitch(cmds)
with serial.Serial(port, speed, timeout=None) as plt:
for ins in body:
# size (Esc-B) returns bufferlen
plt.write(ins)
# For block sent, end with OA, which reports back current
# position on the pen
plt.write("OA;")
c = ""
data = ""
while c != '\r':
c = plt.read()
data += c
print("read: {}".format(map(ord, c)))
print("OA return: {}".format(data))
# We got data, mean OA got executed, so the instruction buffer
# is all consumed, ready to sent more.
```
This made the plotter super fast!!!
## Everything's a line anyway!
After initial success we quickly realized our plotter does not respond to any
commands that involved HP-GL instructions to draw basic geometry, like `CI` for
circle.
A re-reading of the manual made us realize that HP sold this functionality as a
[hardware adapter board that plugs into the
bottom](https://support.hp.com/us-en/document/bpp01354). Our plotter did not arrive with this board.
2019-03-09 19:40:18 +00:00
But everything in computer graphics is a line anyway, right? Using some [root of
2019-03-09 19:43:32 +00:00
unity](http://mathworld.wolfram.com/RootofUnity.html) math, we came up with a circle
2019-03-09 19:40:18 +00:00
drawing routine.
<video width="600" height="450" controls>
<source src="/images/7440a_circle.mp4" type="video/mp4">
2019-03-13 19:28:02 +00:00
</video>
2019-03-09 19:40:18 +00:00
## This is only the beginning
Hardware wise, the only thing left to fix is our pens, which expired in
2019-03-09 19:40:18 +00:00
1996! We are yet to come up with a strategy to refill/replace them.
![Plotter Pen](/images/7440a_pens.jpg){ width=600px }
I am also going to leave this plotter at RC (so that other Recursers can
continue hacking on it), and buy another one for me to actually do some
2019-03-11 02:19:27 +00:00
generative art. :-)
2019-03-09 19:40:18 +00:00
## Notes
2019-03-11 02:19:27 +00:00
1. Big thanks to Amy and Francis and Alex S for their help at various points.
2019-03-09 19:40:18 +00:00
2. All of our python code is here: [https://github.com/dbalan/plotter-scripts](https://github.com/dbalan/plotter-scripts)
3. Thanks to all who proof read this post.