You can use PyVISA to get data from an oscilloscope. For the installation method, refer to VISA in Python --Qiita. Also, in my case, I got an error when using PyVISA, so [[Note] pyvisa.errors.VisaIOError: VI_ERROR_INV_OBJECT (-1073807346): The given session or object reference is invalid. --Qiita] I installed NI-VISA by referring to (https://qiita.com/grinpeaceman/items/9a580c137f1cbbfe5ba7).
Below are the code and descriptive comments.
import numpy as np
import visa
rm = visa.ResourceManager()
#In this place, rm.list_resources()From inside
#Select the desired device and rm.open_resource()Please pass to
inst = rm.open_resource(rm.list_resources()[0])
#timeout setting
scope.timeout = 30000 #30 seconds
# Setting source as Channel 1
scope.write('DATA:SOU CH1') 
scope.write('DATA:WIDTH 1') 
scope.write('DATA:ENC ASCI')
#It is a setting to acquire data to FULL from the oscilloscope
#In my environment, commenting out this location seems to reduce the amount of data
scope.write('DATA:RESOLUTION FULL')
# Getting axis info
#The process of retrieving data is
# How to save Data from Oscilloscope using Python in Linux - Tech For Curious
# <https://techforcurious.website/how-to-save-data-from-oscilloscope-using-python-in-linux/#more-348>Or
# How do I get a waveform using the Instrument Control Toolbox in Matlab? | Tektronix
# <https://techforcurious.website/how-to-save-data-from-oscilloscope-using-python-in-linux/#more-348>
#I referred to
ymult = float(scope.query('WFMPRE:YMULT?')) # y-axis least count
yzero = float(scope.query('WFMPRE:YZERO?')) # y-axis zero error
yoff = float(scope.query('WFMPRE:YOFF?')) # y-axis offset
xincr = float(scope.query('WFMPRE:XINCR?')) # x-axis least count
xoff = float(scope.query('WFMP:PT_OFF?')) # x-axis offset
xzero = float(scope.query('WFMPRE:XZERO?')) # x-axis least count
#Get the data. In my environment about 6.It took 5 seconds
ADC_wave = scope.query_ascii_values('CURV?', container=np.array)
#data
volts = (ADC_wave - yoff) * ymult + yzero
time = np.arange(xzero, xincr * len(Volts) - xoff + xzero, xincr)
Here is the code above that allows you to get and display data in real time and save it.
import numpy as np
import matplotlib.pyplot as plt
import visa
from matplotlib import _pylab_helpers
import tkinter
from tkinter import filedialog
import threading
import csv
#Flag telling if to save
#Lock the thread when changing this variable
is_save_requested = False
def gui(lock):
    global is_save_requested
    def change_title():
        global is_save_requested
        lock.acquire()
        is_save_requested = True
        lock.release()
    root = tkinter.Tk()
    #button
    button1 = tkinter.Button(
        master=root,
        text="Save",          #initial value
        width=30,               #width
        bg="lightblue",         #color
        command=change_title    #Function to execute on click
        )
    button1.pack()
    root.mainloop()
def get_data_from_inst(rm , scope):
    scope.timeout = 30000
    # Setting source as Channel 1
    scope.write('DATA:SOU CH1') 
    scope.write('DATA:WIDTH 1') 
    scope.write('DATA:ENC ASCI')
    scope.write('DATA:RESOLUTION FULL')
    # Getting axis info
    ymult = float(scope.query('WFMPRE:YMULT?')) # y-axis least count
    yzero = float(scope.query('WFMPRE:YZERO?')) # y-axis zero error
    yoff = float(scope.query('WFMPRE:YOFF?')) # y-axis offset
    xincr = float(scope.query('WFMPRE:XINCR?')) # x-axis least count
    xoff = float(scope.query('WFMP:PT_OFF?')) # x-axis offset
    xzero = float(scope.query('WFMPRE:XZERO?')) # x-axis least count
    ADC_wave = scope.query_ascii_values('CURV?', container=np.array)
    Volts = (ADC_wave - yoff) * ymult + yzero
    Time = np.arange(xzero, xincr * len(Volts) - xoff + xzero, xincr)
    return (Time, Volts)
def main():
    rm = visa.ResourceManager()
    inst = rm.open_resource(rm.list_resources()[0])
    #Setting up a GUI that triggers Save
    global is_save_requested
    lock = threading.Lock()
    t1 = threading.Thread(target=gui, args=(lock,))
    t1.start()
    
    data = get_data_from_inst(rm, inst)
    
    x, y = data
	
    x = x * 1e6 # sec to micro sec
    y = y * 1e3 # V to mV
    
    fig, ax = plt.subplots(1, 1)
    ax.set_xlabel('time(μs)')
    ax.set_ylabel('Intensity (mV)')
    lines, = ax.plot(x, y)
    
    while True:
	
        manager = _pylab_helpers.Gcf.get_active()
        if manager is None: break
	
        #Update plot data
        data = get_data_from_inst(rm, inst)
        x, y = data
        x = x * 1e6 # sec to micro sec
        y = y * 1e3 # V to mV
        # data update
        lines.set_data(x, y)
        plt.pause(.01)
        #Save process
        lock.acquire()
        if is_save_requested:
            file =  filedialog.asksaveasfilename(initialfile='', title = "Select a save location",filetypes = [("csv file", ".csv")])
            if file:
                with open(file, mode='w',encoding="utf-8") as f:
                    writer = csv.writer(f, lineterminator='\n')
                    writer.writerows(np.array(data).T)
            is_save_requested = False
        lock.release()
if __name__ == "__main__":
    main()
pyVISA is very convenient!
Recommended Posts