Last active
January 4, 2022 18:38
-
-
Save dannas/5cb06b883b306704e8319261c61878cb to your computer and use it in GitHub Desktop.
WIP Siglent SCPI experiments
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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