Archive for October 16th, 2009

HP 54602B Oscilloscope: Capturing Screen Images Therefrom

Back in the early 90s I bought a Hewlett Packard 54602B digital oscilloscope: 150 MHz bandwidth, 4 channels. By and large, a fine piece of gear that’s been worth every penny.

Over the objections of the HP sales force, I got the HP 54651A RS-232 interface rather than the HP 54650A HPIB (aka GPIB, aka IEEE-488) interface. Reasoning: I’d need a matching interface on the PC side and PC architecture is anything but stable. Turns out that was a good decision, as you’ll realize if you count up the number of different buses since those days and factor in the cost of an IEEE-488 interface for each iteration. RS-232 is slow and not well-suited for complex arrays of test gear, but mostly I needed the scope for screen shots to go with my Circuit Cellar columns.

Here’s how that works…

Configure the scope by poking the RS-232 softkey in Print/Utility:

  • Connect to: HP Plot
  • Factors: On (this is absolutely vital)
  • Resolution: High
  • Baud Rate: 19200 (yes, “baud rate” is an oxymoron)
  • Handshake: DTR

Now the scope will dump HPGL to what it thinks is a plotter, so the trick is to make the PC look like a plotter. Turns out that’s not particularly difficult.

Despite the name, DTR handshaking does not use the scope’s DTR pin. The relevant manual section looks like this (click the thumbnail for full-size image):

HP54602B Oscilloscope Serial Port Pin Functions

HP54602B Oscilloscope Serial Port Pin Functions

So DTR remains high and the flow-control signaling actually uses the RTS/CTS pins. The cable I’ve been is basically a null modem connection with the appropriate gender on each end:

PC RS-232 HP 54602B Oscilloscope
9-pin F Signal 25-pin M Signal
1 DCD 20 DTR
2 RxD 2 TxD
3 TxD 3 RxD
also-> 8 DCD
5 Gnd 7 GND
6 DSR 20 DTR
9 RI n/c


  • PC 1 and 6 <- scope 20
  • PC 4 -> scope 6 and 8

I wired the cable like that mostly because I have a lifetime supply of nice 9-conductor shielded cable lying around. You could connect the scope’s DTR to its own DSR and DCD pins, apply similar trickery on the PC end, and everybody would be perfectly happy with 5-conductor cable, maybe even 4-conductor if you ran the ground through the shield.

Using XON/XOFF flow control seems to not work well, although I admit to not trying too hard to figure it out.

These days, I use a USB-to-RS-232 converter with the now-standard 9-pin connector. The port identifier may be nearly anything after udev/hotplug has its way with the hardware, but it usually works out to /dev/ttyUSB0.

The script requires C-Kermit (likely the ckermit package), ImageMagick, sed, and hp2xx (yes, spelled exactly like that), all of which should be packages in your favorite Linux distro. Haven’t a clue how this might work with Windows.

With all that in hand, copy-n-paste the following text into a file (I used gethp54602, for lack of anything more original), make it executable (chmod u+x gethp54602) and run it with a file name (./gethp54602 test). Poke the Print Screen softkey on the scope and settle back for a bit. The scope can’t keep up a steady flow of data at 19200 b/s, so the whole affair takes a minute or three for the 50-ish kB of text in a dual-trace image.

You’ll end up with three files:

  • test.hgl — raw HPGL text from the ‘scope
  • test.eps — raster conversion from HPGL
  • test.png — bitmapped screen-capture image

The magic script…

#!/usr/bin/kermit +
# Fetches screen shot from HP54602B oscilloscope
# Presumes it's set up for plotter output...
# Converts HPGL to PNG image

set modem none
set line /dev/ttyUSB0
set speed 19200
set flow rts/cts
set carrier-watch off

# Make sure we have a param
if not defined \%1 ask \%1 {File name? }

set input echo off
set input buffer-length 200000

# Wait for PRINT button to send the plot
echo Set HP54602B for HP Plotter, FACTORS OFF, 19200, DTR
echo Press PRINT SCREEN button on HP54602B...

log session "\%1.hgl"

# Wait for final character
input 480 \x03

close session

echo Converting HPGL in
echo --\%1.hgl
echo to PNG in
echo --\%1.png

# Without factors
#run hp2xx -m png -a 1.762 -h 91 -c 14 "\%1.hgl"
#run mogrify -density 300 -resize 200% "\%1.png"

# With factors
run sed '/lb/!d' "\%1.hgl" &gt; "\%1-1.hgl"
run hp2xx -q -m eps -r 270 -a 0.447 -d 300 -w 130 -c 14 -p 34 -f "\%1.eps" "\%1-1.hgl"
run rm "\%1-1.hgl"
run convert -density 300 -resize 675x452+2+2 "\%1.eps" "\%1.png"

echo Finished!
exit 0

Here’s a sample of what pops out; it’s the scope’s own calibrator waveform, nothing exciting, but you get the general idea.

Screen Capture of Calibrator Signal

Screen Capture of Calibrator Signal

The commented-out section labeled “Without Factors” converts the format you get with Factors Off. Turns out that there’s no unique ending string without factors, which puts a real crimp in getting the data. The advantage is that the HPGL converts directly to PNG and looks good. The only way I’ve found to capture the scope data is to just time out after a while.

With Factors On, however, the image data has a unique ending character (ASCII ETX, 0x03) after the label text, but the layout is rotated to plot in landscape mode. A direct conversion to PNG looks awful, perhaps because hp2xx must do software character generation, and I eventually figured out that making a bank shot off EPS vector format produced much better results.

However, hp2xx dutifully renders the text into the EPS image, but it doesn’t inject a carriage return after each linefeed: the text dribbles off to the far right of the actual screen image. To fix that, the sed editor hacks off the label text following the lb command. Mercifully, hp2xx doesn’t choke on the incomplete command.

And then convert does its usual magic. The image size is just right to drop into my Circuit Cellar columns; you may want something different for your purposes.

[Update: The PNG has an alpha channel that selects only the traces, so the background color depends on where you put it. A small tweak is there.]

For reasons that I absolutely do not understand, I cannot control the oscilloscope through the serial interface. The scope sends data to the PC just fine and I can get the scope to complain about the character format if I send truly bogus junk (like, mismatching the baud settings), but it simply will not respond to commands. Maybe the interface is broken or, more likely, I’m screwing something up. Hasn’t been a problem, though, for my simple needs.

Memo to Self: One of these days, eBay will have a 54652B serial/parallel interface that might work better.