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