Interfacing to the DSO3000
The DSO3000 series oscilloscopes from Agilent are low-cost (as digital scopes go) digital storage oscilloscopes. They are actually rebadged Rigol DS5000 series scopes. There are four scopes in the series with different bandwidths:
- DSO3062A
- DSO3102A
- DSO3152A
- DSO3202A
I have the DSO3102A, so all this information is based on that model. I expect the others to be identical except for slight differences in firmware and the front-end electronics.
These scopes have a USB interface built in and Agilent sells optional RS-232 and GPIB interfaces. The USB protocol is undocumented, however, and the only software that supports it is Agilent's (Rigol's) Scope Connect software. This has a few disadvantages:
- It is a Windows program
- It is not (easily) controllable by other programs
- It is closed-source
It used to be a separate option you had to buy and was tied to a particular scope, but now it is free.
Since I primarily use Linux, I need different software. I would also like to control the scope from other programs.
Warning
Use this information and code at your own risk. Most of this is not documented by Agilent or Rigol. Since the scope can have its firmware upgraded over USB, it is almost certainly possible to "brick" it if you get into firmware upgrade mode and send the wrong data. There may be commands which can damage the scope in some way, and there are definitely commands that will crash the scope and erase the calibration data. I am not responsible for what you do to your hardware.
Protocol
The scope accepts GPIB commands over USB with a simple protocol which involves only control packets:
Request | Vendor 0 (c0 00) |
---|---|
Direction | Device -> Host |
Value | 0 |
Index | 0 |
Length | 1 |
Data | One byte indicating the length of data to read with Read Data below. |
Request | Vendor 0 (c0 00) |
---|---|
Direction | Device -> Host |
Value | 1 |
Index | 0 |
Length | Length of data to read |
Data | length bytes of response text |
Request | Vendor 1 (c0 01) |
---|---|
Direction | Device -> Host |
Value | Byte to send (\r terminates a command) |
Index | 0 |
Length | 0 |
No data |
Commands are sent to the scope ony byte at a time with Send byte
packets. After the command is sent, the length of the response is obtained with the Get Response Length
command, and then response data is read with Read Data
.
If there are more than 255 bytes of response data waiting to be read, Get Response Length
will return 255. In this case the host must read the data and get the length again to find out how much, if any, data remains to be read.
The host must read the amount of data indicated by the Get Response Length
packet in a single read. If you read less than this, data may be lost or future transfers may be corrupted. The scope will always return the amount of data requested, even if this causes data from old transfers to be returned.
A response is always one line of text. The host should consider the data to be terminated with a \n
, even if extra data is received. For example, the :WAV:DATA?
command sends extra bytes after the \n
which look like a buffer is not terminated correctly. I'm pretty sure this is the result of a bug in the scope and not in my code or libusb.
Confusingly, commands must be terminated by \r
while responses are terminted by \n
.
Interesting behavior: If you always read 255 bytes when reading the response to :WAV:DATA?
, the next to last packet (length 255) will contain garbage after the \n
and the last packet (length 1) will contain a single \n
followed by the contents of the previous response. This indicates that the scope uses one buffer for small responses and a different buffer for the large waveform response.
Official Documentation
Agilent has a Programmer's Reference which is inteded for users of the RS-232 and GPIB add-ons (there is no official support for using the USB port outside of Scope Connect). This document has been recently updated and contains lots of detail on the command set.
Extra Endpoints
The scope has one endpoint of each type in each direction. I suspect that this is just a generic configuration and several of the endpoints aren't used (except one bulk endpoint for firmware upgrades).
Scope Connect can show screen captures, so one of these endpoints is probably used for that.
Software
I have written a simple console program for talking to the scope directly. Each line of text you enter is sent to the scope and the response is printed. If you enter &mem
or &scr
then the waveform data from the source specified by :WAV:SOURCE
is dumped to a file named mem.txt
(all data) or scr.txt
(only data shown on screen) which can be read as an array by Octave.
Source code is available on github: https://github.com/cktben/dso3000. This requires libusb but does not require any special drivers. I have only tested this on Linux but it should work on any platform supported by libusb.
NOTE - You must upgrade to the newest firmware version before this software will work properly. The firmware that shipped with my scope (03.01.18) had bugs in the command handling code. You can get the newest firmware from Agilent's web site.
Secrets Features
- 50-ohm termination of inputs
- Read calibration data (is there any use for this?)
Future Work
I want to get a better front-end for talking to the scope. Maybe something like a Linux equivalent of Scope Connect.