The discussion below relates specifically to the Keysight MSO-X 3034A oscilloscope, but I suspect it will apply just as well to other Keysight scopes and perhaps more generally. I’d be interested to hear about other instruments.

On the computer end, although I’ve written this with MacOS in mind, I expect it would work on Linux without modification.


Lots of modern test instruments have an Ethernet jack on the back, which means we can connect them to the LAN and control them remotely. Obvious tasks include:

For the MacOS user though, much of the online information seems to be Windows specific, which is a nuisance. Further, although software libraries exist to communicate with these devices they seem a bit unwieldy.

For someone using lots of different devices, or who needs a solution which is robust in the face of errors and bizarre happenings, these formal, well-tested systems make sense.

However, more casual approaches seem to work well on MacOS.

The programming guide

Commendably, Keysight publish a programming guide to the 3000 X-Series scopes.1 At over 1200 pages, it is undeniably a thick document, but it seems clear and well-written. I’m working from version 02.38.000 of the document, and all the page numbers below refer to that.

The key insight is that you can control the scope using a command line interface on socket 5024, which is referred to as the ‛Telnet Sockets’ approach. Thus without installing any software at all, you can control the scope from the terminal. Here’s a short example to query the scope’s identification number:

$ telnet <hostname> 5024

*IDN? is a SCPI2 command which returns the instrument’s identification number. See page 170 of the progammer’s guide for more details.

Given that most of this is text based, Perl seems a convenient choice if we want to automate things. Rather than using port 5024 though, it’s better to use port 5025 which offers an interface without human-helpful prompts.

Grabbing a screen dump

As an example task, let’s dump an image of the oscilloscope’s screen. If you just want the code, grab it from GitHub.3

The key, and most difficult, task is to find a suitable command. After some searching, I found :DISP:DATA? which is described on page 306.

To get an image of the screen in PNG format, all we have to send is:


The data returned are in IEEE-488.2 binary block data format, which is helpfully described on page 70.

It seems convenient to derive a new class from IO::Socket::INET to handle this:

package MSO;

use base qw(IO::Socket::INET);

sub get_ieee_binary_block						
    my $io = shift;							
    my $header;								
    read($io, $header, 2);						
    # length of length							
    my ($m) = ($header =~ /^#(\d)$/)					
	or die "Unable to parse header A: $header, ";			
    # length of data							
    read($io, $header, $m);						
    my ($n) = ($header =~ /^(\d+)$/)					
	or die "Unable to parse header B: $header, ";			
    # data								
    my $data;								
    read($io, $data, $n);						
    # end-of-line							
    return $data;							

Which we can call thus:

my $addr = 'mso.local';

my $mso = MSO->new(PeerAddr => $addr, PeerPort => 5025)			
  or die "Unable to open MSO connection, ";				
my $data = $mso->get_ieee_binary_block;					
open(my $fh, '>', 'foo.png');						
print {$fh} $data;							

Here’s the result:

As you see, the code is pretty simple. There might be some sense in abstracting the binary block handling into a library, and perhaps wrapping print and getline to facilitate tracing, but I’ve not yet done that.

Movie making

One particular use for this is to take a series of screen dumps, then combine them into an animated GIF—indeed that’s what led me to explore this.

Graphics Magick4 and Image Magick5 can assemble the frames processing them as it does.

For example, I grabbed a series of frames calling them y001.png, y002.png, &c. I wanted to crop out a section of the display, then glue them into a movie. This command did the trick:

convert y*png -crop 301x301+187+92 -repage 301x301+0+0 aa.gif


More imagemagick

To extract the main part of the display:

convert mso.png -crop 601x400+37+43 cropped.png

To convert the image into a traditional green on black:

convert mso.png -negate green-on-black.png

You can combine the flags.

Bonjour oscilloscope!

I was delighted to see that the scope supports zero configuration networking6 (Bonjour in Apple parlance), so if you change the scope’s name to something sane e.g. mso you can say e.g.:

$ telnet mso.local 5025

Web interface

I was also delighted to see that the scope’s web interface works tolerably well in some places without installing Java.

$ open http://mso.local