[PYTHON] Get data from an oscilloscope with pyVISA

Introduction

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).

Python code

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()

in conclusion

pyVISA is very convenient!

Recommended Posts

Get data from an oscilloscope with pyVISA
[Note] Get data from PostgreSQL with Python
Get data from Cloudant with Bluemix flask
Get structural data from CHEMBLID
Get Youtube data with python
Get data from database via ODBC with Python (Access)
Get data from analytics API with Google API Client for python
Get data from Quandl in Python
Get one column from DataFrame with DataFrame
[Python] Get economic data with DataReader
Get data from Twitter using Tweepy
Get data from MySQL on a VPS with Python 3 and SQLAlchemy
I get an error with import pandas.
Receive textual data from mysql with python
When I get an error with PyInstaller
Scraping from an authenticated site with python
Operate an oscilloscope with a Raspberry Pi
Get time series data from k-db.com in Python
Get stock price data with Quandl API [Python]
Generate an insert statement from CSV with Python.
Get 10 or more data from SSM parameter store
I get an error with all yum commands
Extract data from a web page with Python
How to scrape image data from flickr with python
Get schedule from Garoon SOAP API with Python + Zeep
Reading Note: An Introduction to Data Analysis with Python
Get data from GPS module at 10Hz in Python
How to get more than 1000 data with SQLAlchemy + MySQLdb
Get comments and subscribers with the YouTube Data API
Get mail from Gmail and label it with Python3
[Basics of data science] Collecting data from RSS with python
Data analysis with python 2
Extract data from S3
Visualize data with Streamlit
Reading data with TensorFlow
Get started with MicroPython
Data manipulation with Pandas!
Get Tweets with Tweepy
Get Gzip-compressed data on-memory
Shuffle data with pandas
Data Augmentation with openCV
Get started with Mezzanine
Normarize data with Scipy
Data analysis with Python
LOAD DATA with PyMysql
Get an image from a web page and resize it
[Python] Send an email from gmail with two-step verification set
Let's get started with Python ~ Building an environment on Windows 10 ~
Getting Started with Drawing with matplotlib: Creating Diagrams from Data Files
I tried sending an email from Amazon SES with Python
[Linux] Copy data from Linux to Windows with a shell script
Check! Get sensor data via Bluetooth with Raspberry Pi ~ Preparation
Create an environment for "Deep Learning from scratch" with Docker
Get rid of dirty data with Python and regular expressions
Xpath summary when extracting data from websites with Python Scrapy
[Python] Get the script execution directory with an absolute path
Try to get data while port forwarding to RDS with anaconda.
How to get an overview of your data in Pandas
Get additional data to LDAP with python (Writer and Reader)
Get message from first offset with kafka consumer in python
[Introduction to Python] How to get data with the listdir function