Skip to content

Instantly share code, notes, and snippets.

@dannas
Last active January 4, 2022 18:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dannas/5cb06b883b306704e8319261c61878cb to your computer and use it in GitHub Desktop.
Save dannas/5cb06b883b306704e8319261c61878cb to your computer and use it in GitHub Desktop.
WIP Siglent SCPI experiments
# Very much WIP for experimenting with SDS1104X-E/SDS2104X-E scopes SCPI
# interface
import pyvisa as visa
from pyvisa.resources.resource import Resource
import matplotlib.pyplot as plt
import time
import numpy as np
def test(scope : Resource):
#Identify the model, firmware version
scope.query("*IDN?")
# Set format of responses. LONG, SHORT, OFF
# We need OFF to be able to parse output
scope.write("CHDR off")
scope.query("CHDR?")
# Reset the device
scope.write("*RST")
# Returns 8193.
# 8192 means Trigger ready
# 1 means New Signal Acquired
# TODO(dannas): Read up on how this works again
scope.query("INR?")
scope.write("ARM")
scope.query("INR?")
scope.query("INR?")
scope.write("STOP")
scope.query("TRIG_MODE?")
scope.write("TRIG_MODE SINGLE")
# Arm the scope
scope.write("ARM")
# Press stop button
scope.write("STOP")
# Read acquisition mode
scope.query("ACQUIRE_WAY?")
# Read number of data points that the hw will acquire from the input signal
# Here for channel 1
# TODO(dannas): C2, C3 and C4 times out. Why?
scope.query("SANU? C1")
# Return the acquisition data of the scope Stop, Auto, Ready (normal, single)
scope.query("SAST?")
# Get current time base
scope.query("TDIV?")
scope.write("CHANNEL1:TRACE ON")
scope.write("C2:TRACE ON")
scope.write("C3:TRACE ON")
scope.write("C4:TRACE ON")
# Trigger delay.
scope.query("TRIG_DELAY?")
scope.write("TRIG_DELAY 1E-5")
scope.query("C1:VOLT_DIV?")
scope.query("C2:VOLT_DIV?")
scope.query("C3:VOLT_DIV?")
scope.query("C4:VOLT_DIV?")
scope.write("C1:VOLT_DIV 2.5")
# Sample rate of the oscilloscope
scope.query("SARA?")
# D1M = DC 1Mohm
# A1M = AC 1Mohm
# D50 = DC 50ohm
# A50 = AC 50ohm
# GND = GND
scope.query("C1:COUPLING?")
# Numerical value in E-notation with SI unit.
# e.g. 2.50E-10S
scope.query("C1:SKEW?")
# The probe attenuation 1x, 10x, ...
scope.query("C1:ATTENUATION?")
# Return the memory size
scope.query("MEMORY_SIZE?")
scope.write("MEMORY_SIZE 1.4M")
# Returns ON or OFF
scope.query("C2:BANDWIDTH_LIMIT?")
# Returns ON or OFF
scope.query("C1:INVERTSET?")
# Set skew
scope.write("C1:SKEW 9.99E-08S")
scope.write("C1:SKEW 0E-09S")
# Values less than 1 should have 1 decimal
scope.write("C1:ATTENUATION 0.1")
scope.write("C1:ATTENUATION 50")
scope.write("C1:ATTENUATION 10")
scope.write("C1:INVERTSET ON")
scope.write("C1:INVERTSET OFF")
# OFF means full bandwidth
# ON means 20MHz bandwidth limit
scope.write("BANDWIDTH_LIMIT C1,ON")
scope.write("BANDWIDTH_LIMIT C1,OFF")
# Voltage offset
scope.query("C1:OFST?")
scope.query("C2:OFST?")
scope.query("C3:OFST?")
scope.query("C4:OFST?")
# Edge: EDGE
# Slope: SLEW
# Pulse: GLIT
# Video: TV
# Window: WIN
# Interval: INTV
# Dropout: DROP
# Runt: RUNT
# Pattern: PA
# Serial: SERIAL
#
# Parameter names
# IL: Interval Larger
# IS: Interval Smaller
# I2: Interval in range
# I1: Interval out of range
# PL: Pulse Larger
# PS: Pulse Smaller
# P2: Pulse in range
# P1: Pulse out of range
scope.query("TRIG_SELECT?")
scope.query("WAVEFORM_SETUP?")
scope.write("C1:WF? DAT2")
data = scope.read_raw()
header = data[0:15]
# Strip header and line endings \r\n
data = data[15:-2]
for i in range(5):
t0 = time.time()
scope.write("C1:WF? DAT2")
data = scope.read_raw()
n = len(data)
dt = time.time() - t0
print(f'{int(dt * 1000)}ms, n={n}')
print('all tests passed!')
def plot_waveform(scope: Resource):
vdiv = float(scope.query("C1:VDIV?"))
offset = float(scope.query("C1:OFST?"))
time_div = float(scope.query("TDIV?"))
sample_rate = float(scope.query("SARA?"))
print(f'{vdiv=}, {offset=}, {time_div=} {sample_rate=}')
# First 15 bytes is a header, then the content is signed char
data = scope.query_binary_values("C1:WF? DAT2", datatype='b', container=np.array)
plt.plot(data[15:])
def benchmark(scope: Resource, N=1):
for i in range(N):
t0 = time.time()
data = scope.query_binary_values("C1:WF? DAT2", datatype='b', container=np.array)
n = len(data)
dt = time.time() - t0
print(f'{int(dt * 1000)}ms, n={n}')
rm = visa.ResourceManager()
scope = rm.open_resource("TCPIP0::192.168.1.250", timeout=3000, chunk_size=20*1024*1024)
scope.write("CHDR off")
plot_waveform(scope)
benchmark(scope)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment