Skip to content

Instantly share code, notes, and snippets.

Forked from shirriff/
Last active July 16, 2024 15:01
Show Gist options
  • Save pklaus/7e4cbac1009b668eafab to your computer and use it in GitHub Desktop.
Save pklaus/7e4cbac1009b668eafab to your computer and use it in GitHub Desktop.
Example of controlling a Rigol oscilloscope via Python. Fetch a 1 MB "Long Memory" trace from the oscilloscope and graph it using matplotlib.
#!/usr/bin/env python
Download data from a Rigol DS1052E oscilloscope and graph with matplotlib.
By Ken Shirriff,
Based on
by Cibo Mahto.
import numpy
import matplotlib.pyplot as plot
import sys
import visa
rm = visa.ResourceManager()
# Get the USB device, e.g. 'USB0::0x1AB1::0x0588::DS1ED141904883'
instruments = rm.list_resources()
usb = list(filter(lambda x: 'USB' in x, instruments))
if len(usb) != 1:
print('Bad instrument list', instruments)
scope = rm.open_resource(usb[0], timeout=20, chunk_size=1024000) # bigger timeout for long mem
# Grab the raw data from channel 1
# Get the timescale
timescale = float(scope.query(":TIM:SCAL?"))
# Get the timescale offset
timeoffset = float(scope.query(":TIM:OFFS?")[0])
voltscale = float(scope.query(':CHAN1:SCAL?')[0])
# And the voltage offset
voltoffset = float(scope.query(":CHAN1:OFFS?")[0])
scope.write(":WAV:POIN:MODE RAW")
rawdata = scope.query(":WAV:DATA? CHAN1").encode('ascii')[10:]
data_size = len(rawdata)
sample_rate = scope.query(':ACQ:SAMP?')[0]
print('Data size:', data_size, "Sample rate:", sample_rate)
data = numpy.frombuffer(rawdata, 'B')
# Walk through the data, and map it to actual voltages
# This mapping is from Cibo Mahto
# First invert the data
data = data * -1 + 255
# Now, we know from experimentation that the scope display range is actually
# 30-229. So shift by 130 - the voltage offset in counts, then scale to
# get the actual voltage.
data = (data - 130.0 - voltoffset/voltscale*25) / 25 * voltscale
# Now, generate a time axis.
time = numpy.linspace(timeoffset - 6 * timescale, timeoffset + 6 * timescale, num=len(data))
# See if we should use a different time axis
if (time[-1] < 1e-3):
time = time * 1e6
tUnit = "uS"
elif (time[-1] < 1):
time = time * 1e3
tUnit = "mS"
tUnit = "S"
# Plot the data
plot.plot(time, data)
plot.title("Oscilloscope Channel 1")
plot.ylabel("Voltage (V)")
plot.xlabel("Time (" + tUnit + ")")
plot.xlim(time[0], time[-1])
Copy link

The mapping from binary to real voltages provided by Cibo Mahto did not work on my setup. The mapping that did work was:

"data1 = np.frombuffer(rawdata, 'B')
data = (data1 - 128.0) * 10 * voltscale / 256 - voltoffset"

Copy link

The command "sample_rate = scope.query(':ACQ:SAMP?')[0]" returned a time-out error. As the sample_rate variable was not used elsewhere I simply removed it.

Copy link

Does anyone know how to actually get 1 million points? I am only getting 1200.

Copy link

zyb1003 commented Jul 6, 2022

@josiahsinclair I think 1200 is all you can get. BTW, your comments are useful!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment