Tektronix TDS540C - Macintosh PyVISA Python GPIB-USB-HS Python Anaconda - Page 1
Forum section: electronics / testgear

author: Tantratron
author_rank: Frequent Contributor
timestamp: May 23, 2020, 08:10:40 am
content: I've been trying to find in the forum different threads or return of experience from step by step use of PyVISA in order to program under Python communication between legacy TDSxxx and MacOS. Maybe this has been done with Windows or Linux, maybe the steps are the same so if some of you would offer some guidance, it would be appreciated.Few months ago after purchasing an used interface GPIB-USB-HS (National Instruments model), I was able to quite easily connect my MacBook Air under MacOS 10.12.6 to my TDS540C oscilloscope. The good thing with NI, their Visa application once downloaded and run on my Mac runs seamless. Some example of use can be found in these two threads, one is about hacking some features of the TDS (i.e. FFT enable), seehttps://www.eevblog.com/forum/repair/gpib-usb-control-between-macbook-air-(macintosh)-and-tds540c/Another to save, write NVRAM, EEPROM and flash memory... please seehttps://www.eevblog.com/forum/repair/tekfwtool-for-tds540c-firmware-upgrade/msg2861266/#msg2861266It seems there is a consensus to go after Anaconda in order to have a stable Python but I what do you recommend to install PyVISA so all the parts will self-work together ?My project requires to dynamically upload, compute many parameters found inside the TDS540C processor because the screen limits only to 4 parameters live display ?Ideally a graphical Python or say low cost labView style would be preferred, idea is to automatize and show more specific probing results of a running lab test.Thank you, Albert

author: digi
author_rank: Contributor
timestamp: May 23, 2020, 10:40:03 pm
content: I haven't used pyvisa with macos, but it should be pretty similar to windows. I would recommend either Anaconda or miniconda (which is the stripped down version that only includes the most basic python libraries) in order to keep your python environment separate from the macos python installation.Here's how you would get up and running:Install anaconda/miniconda. Make sure to match the bitness (32/64 bit) with your NI VISA installationMake sure conda is activated in your terminal. You should see that the terminal prompt is pre-fixed with "(base)" if it isn't then type "activate" to activate condapip install pyvisaFollow examples athttps://pyvisa.readthedocs.io/en/latest/You should be able to get started pretty quickly, but if you want a gui in python you'll have to do all the work using a graphical library like QT, tkinter, etc. You might want to take a look into jupyter notebooks which will allow you to add widgets likes buttons to (sort-of) generate a gui.

author: Tantratron
author_rank: Frequent Contributor
timestamp: May 25, 2020, 05:03:51 am
content: Thank you @digi where so far, so good... see attached screenshot of my MacBook Air showing Anaconda, Conda, Terminal with (base).As for uploading the PyVISA from GitHub, it seems to be many different builds or evolutions, some unstable or stable... which package do you recommend ?

author: alm
author_rank: Super Contributor
timestamp: May 25, 2020, 08:15:32 pm
content: I would just install the latest release, which is 1.10.1 right now:https://pypi.org/project/PyVISA/To install it within conda, I believe you would do, on a shell prompt with conda activated (bottom left window in your screenshot, the prompt looks like(base) ...$):Code:conda install pippip install pyvisaThis should install the latest version of PyVISA from PyPI to the conda environment you have activate at that time.

author: Tantratron
author_rank: Frequent Contributor
timestamp: May 30, 2020, 12:44:25 pm
content: Many thanks where now all environment works within my MacBook Air, the PyVISA, the National Instruments GPIB-USB-HS interface and Visual Studio code launched from the Anaconda Navigator. See attached two pictures where the TDS540C is showing specific channel measurements which have been dumped through the GPIB to my Macintosh.Since I'm on my learning curve with the GPIB command proper to the TDS540C oscilloscope, I have another query. Theses TDSxxx serie C or serie D offers different features like SNAPSHOT for each channel. It consists of 25 automatic measurements computed and display on the CRT then when pressing MEASUREMENT button, we can choose up to 4 measurements to be displayed on the CRT.However do you know if the TDS does store internally all the channels and their respective live values so they could be directly read via GPIB network ?In other words, the TDS display can only provide live up to 4 parameters (MEAS1 MEAS2 MEAS3 and MEAS4) the apparently a hidden IMMED. Each measurement can be chosen from a set of 25 automatic measurements parameter computed by the DSP but what is the command to read all of them ?Thank you, Albert

author: Venturi962
author_rank: Regular Contributor
timestamp: May 30, 2020, 01:12:46 pm
content: I don't have a Tek 540C, but will share a few thoughts after looking at the documentation (http://w140.com/tekwiki/images/c/cd/070-8709-07.pdf)Q: Theses TDSxxx serie C or serie D offers different features like SNAPSHOT for each channel. It consists of 25 automatic measurements computed and display on the CRT then when pressing MEASUREMENT button, we can choose up to 4 measurements to be displayed on the CRT.The snapshot commands in the manual says that you can only clear or display the Snapshot - but not return all of the results.MEASUrement:CLEARSNapshot - Removes the measurement snapshot display.MEASUrement:SNAPShot - Displays the measurement snapshot.Q: However do you know if the TDS does store internally all the channels and their respective live values so they could be directly read via GPIB network ?Looking at the Programmer's Manual for the Tek implies that only 4 (+ 1) Measurements are actively calculated:"In addition to the four displayed measurements, the measurement commands let you specify a fifth measurement, 'IMMed'. The immediate measurement has no front-panel equivalent. Immediate measurements are never displayed.Because they are computed only when needed, immediate measurements slow the waveform update rate less than displayed measurements."If you wanted to read through all 25 measurements, you could write a Loop that runs through them all - although it sounds like this will slow down the waveform update rate (perhaps not a problem if you're reading a consistent signal). The Reserved Keywords in the Appendix has all the measurements.

author: Tantratron
author_rank: Frequent Contributor
timestamp: May 30, 2020, 01:42:10 pm
content: Quote from: Venturi962 on May 30, 2020, 01:12:46 pmSo I guess then my previous post with image of my Python code would be the only sequential manner to obtain many parameters through IMMed hidden variable as you mentionedCode:tek.write('MEASUrement:IMMED:SOURCE CH1')tek.write('MEASUrement:IMMED:Type FREQuency')print(tek.query('MEASUrement:IMMED:VALUE?'),'Hz')tek.write('MEASUrement:IMMED:Type Crms')print(tek.query('MEASUrement:IMMED:VALUE?'),'V(rms)')tek.write('MEASUrement:IMMED:SOURCE CH2')tek.write('MEASUrement:IMMED:Type Crms')print(tek.query('MEASUrement:IMMED:VALUE?'),'A(rms)')tek.write('MEASUrement:IMMED:SOURCE MATH1')tek.write('MEASUrement:IMMED:Type Cmean')print(tek.query('MEASUrement:IMMED:VALUE?'),'W')For example, I choose the CHx then Type of measurement then extract the VAlue

author: Venturi962
author_rank: Regular Contributor
timestamp: May 30, 2020, 02:26:11 pm
content: Yes, it seems that way. Here's an example of a Loop (not sure this will 100% work) but should be able to base your work off:Code:channels = ['CH1', 'CH2', 'CH3', 'CH4', 'MATH1']measurements = ['FREQuency', 'CRMs', 'CMEan']measurementNames = ['Frequency', 'Cycle RMS', 'Cycle Average']for channel in channels:tek.write(f'MEASUrement:IMMED:SOURCE {channel}')for measurement, measurementName in zip(measurements, measurementNames):tek.write(f'MEASUrement:IMMED:Type {measurement}')print(tek.query(f'MEASUrement:IMMED:VALUE?'), measurementName)

author: Tantratron
author_rank: Frequent Contributor
timestamp: May 30, 2020, 03:11:27 pm
content: Thanks @Venturi962Maybe another route I could follow, have you done some programming to upload directly say 4 channels stored in the TDS memory ?This project has 3 probes so 3 channels plus single M1 mathematical channel (CH1 x CH 2) so it computes the RF active power (CH1 is voltage and CH2 current).I assume these TDS could save at the same time 4 channels or 4 displays curves with no de-skew or shift... then it is a matter to download via Python and GPIB each stored logical data then post-processing to obtain my parameters.Have you done this by any chance ?

author: digi
author_rank: Contributor
timestamp: May 30, 2020, 03:52:41 pm
content: Here's some code I've used to get raw trace data from a Tek scope (difference model):Code:import numpy as np# configure the data format# no header# verbose off# 1 byte per data point# use binary encoding# signed integer binaray data# use MSBtek.write('HEAD OFF;VERB OFF;WFMP:BYT_N 1;WFMP:ENC BIN;WFMP:BN_F RI;WFMP:BYT_O MSB')# source = CH1, CH2, etctek.write('DAT:SOU ' + source)# get raw trace data and convert to a numpy arrayraw_trace_data = np.array(map(float, tek.query('CURV?').split(',')))# vertical gainvgain = float(tek.query('WFMP:YMU?'))# horizontal internvalhorizontal_interval = float(tek.query('WFMP:XIN?'))# multiply data by vertical gain# data should contain the vertical offsettrace_data = raw_trace_data * vgain# construct time axist_axis = np.arange(len(data)) * horizontal_intervalI used the numpy library is this example to create arrays, but you could lists.

author: Tantratron
author_rank: Frequent Contributor
timestamp: May 31, 2020, 04:08:59 am
content: Quote from: digi on May 30, 2020, 03:52:41 pmI've tried to embed then run your code but what isself.visa.query(...)function ?In my case, I start with import pyvisa then can use tek.write() or tek.read() or tek.query() ?

author: digi
author_rank: Contributor
timestamp: May 31, 2020, 12:43:31 pm
content: Quote from: Tantratron on May 31, 2020, 04:08:59 amYou would use "tek.query(...)"

author: Tantratron
author_rank: Frequent Contributor
timestamp: June 01, 2020, 12:15:02 pm
content: Hello @digi,I've tried running your example and replaced with tek.query() but there seems to be an issue when running on my TD540C. Do you know what could be wrong in the attached python code and why these errorsPython programCode:import pyvisaimport numpy as nprm = pyvisa.ResourceManager()rm.list_resources()tek = rm.open_resource('GPIB0::1::INSTR')tek.write_termination = '\n'tek.read_termination = '\n'print(' ')print(tek.query('*IDN?'))print(' ')# configure the data format# no header# verbose off# 1 byte per data point# use binary encoding# signed integer binaray data# use MSBtek.write('HEAD OFF;VERB OFF;WFMP:BYT_N 1;WFMP:ENC BIN;WFMP:BN_F RI;WFMP:BYT_O MSB')# source = CH1, CH2, etctek.write('DATa:SOUrce CH2')# get raw trace data and convert to a numpy arrayraw_trace_data = np.array(map(float, tek.query('CURV?').split(',')))# vertical gainvgain = float(tek.query('WFMP:YMU?'))# horizontal internvalhorizontal_interval = float(tek.query('WFMP:XIN?'))# multiply data by vertical gain# data should contain the vertical offsettrace_data = raw_trace_data * vgain# construct time axis#t_axis = np.arange(len(data)) * horizontal_intervalTerminal reportCode:macbook-air-de-tantratron-2:~ tantratron$ source /opt/anaconda3/bin/activateconda activate base(base) macbook-air-de-tantratron-2:~ tantratron$ conda activate base(base) macbook-air-de-tantratron-2:~ tantratron$ /opt/anaconda3/bin/python /Users/tantratron/Dropbox/TDS-GPIB-PyVISA/TDS540C-Induction-Lamp3.pyTEKTRONIX,TDS 540C,0,CF:91.1CT FV:v5.2eTraceback (most recent call last):File "/Users/tantratron/Dropbox/TDS-GPIB-PyVISA/TDS540C-Induction-Lamp3.py", line 27, in <module>raw_trace_data = np.array(map(float, tek.query('CURV?').split(',')))File "/opt/anaconda3/lib/python3.7/site-packages/pyvisa/resources/messagebased.py", line 613, in queryreturn self.read()File "/opt/anaconda3/lib/python3.7/site-packages/pyvisa/resources/messagebased.py", line 427, in readmessage = self._read_raw().decode(enco)UnicodeDecodeError: 'ascii' codec can't decode byte 0x88 in position 808340: ordinal not in range(128)(base) macbook-air-de-tantratron-2:~ tantratron$Thanks, Albert

author: digi
author_rank: Contributor
timestamp: June 01, 2020, 12:37:43 pm
content: Quote from: Tantratron on June 01, 2020, 12:15:02 pmThe code is breaking when trying convert returned values to floating pt numbers.Try replacing:Code:raw_trace_data = np.array(map(float, tek.query('CURV?').split(',')))with:Code:raw_trace_data = np.array(tek.query_binary_values('CURV?', datatype='b', is_big_endian=True))

author: Tantratron
author_rank: Frequent Contributor
timestamp: June 01, 2020, 01:54:35 pm
content: Quote from: digi on June 01, 2020, 12:37:43 pmJust did as suggested, here is the terminal resultCode:macbook-air-de-tantratron-2:~ tantratron$ source /opt/anaconda3/bin/activate(base) macbook-air-de-tantratron-2:~ tantratron$ conda activate base(base) macbook-air-de-tantratron-2:~ tantratron$ /opt/anaconda3/bin/python /Users/tantratron/Dropbox/TDS-GPIB-PyVISA/TDS540C-Induction-Lamp3.pyTEKTRONIX,TDS 540C,0,CF:91.1CT FV:v5.2e/opt/anaconda3/lib/python3.7/site-packages/pyvisa/resources/messagebased.py:532: FutureWarning: Reading binary data without a known length is error prone, and should be avoided. This capability will will be removed in future versions.If the instrument does not report the length of the block as part of the transfer, it may be because the size is fixed or can be accessed from the instrumentin using a specific command. You should find the expected number of points and pass it using the `data_points` keyword.warnings.warn(msg, FutureWarning)Traceback (most recent call last):File "/Users/tantratron/Dropbox/TDS-GPIB-PyVISA/TDS540C-Induction-Lamp3.py", line 31, in <module>vgain = float(tek.query('WFMP:YMU?'))File "/opt/anaconda3/lib/python3.7/site-packages/pyvisa/resources/messagebased.py", line 613, in queryreturn self.read()File "/opt/anaconda3/lib/python3.7/site-packages/pyvisa/resources/messagebased.py", line 427, in readmessage = self._read_raw().decode(enco)File "/opt/anaconda3/lib/python3.7/site-packages/pyvisa/resources/messagebased.py", line 400, in _read_rawchunk, status = self.visalib.read(self.session, size)File "/opt/anaconda3/lib/python3.7/site-packages/pyvisa/ctwrapper/functions.py", line 1584, in readret = library.viRead(session, buffer, count, byref(return_count))File "/opt/anaconda3/lib/python3.7/site-packages/pyvisa/ctwrapper/highlevel.py", line 193, in _return_handlerraise errors.VisaIOError(ret_value)pyvisa.errors.VisaIOError: VI_ERROR_TMO (-1073807339): Timeout expired before operation completed.(base) macbook-air-de-tantratron-2:~ tantratron$What tektronix oscilloscope have you used and run your software ?

author: digi
author_rank: Contributor
timestamp: June 01, 2020, 02:03:00 pm
content: Quote from: Tantratron on June 01, 2020, 01:54:35 pmI've used newer MDO models, but the idea should be the same to download raw data. You'll have to try and parse the response from "tek.query('CURV?')"Feel free to PM me - I might be able to figure something out if I see the raw data returned.

author: Tantratron
author_rank: Frequent Contributor
timestamp: June 04, 2020, 03:23:49 pm
content: Quote from: digi on June 01, 2020, 02:03:00 pmSpecial thanks to @digi who spend private time off-line in order to solve some issues why the old TDS540C would not systematically transfer the data. Now it is solved, see attached an exemple sketch written in Python based on PyVISA where I transfer the content of CH1 and CH2 as seen on the TDS540C screen the locally compute the product. Make a note the TDS540C is displaying MATH1 which is the live product computed by its internal DSP.Code:# example to transfer and display CH1 and CH2 from TDS540Cimport pyvisaimport numpy as npimport matplotlib.pyplot as plt# initialize the PyVISA, the GPIB-USB-HS interface and TDS540Crm = pyvisa.ResourceManager()rm.list_resources()tek = rm.open_resource('GPIB0::1::INSTR')tek.write_termination = '\n'tek.read_termination = '\n'# configure the data format (no header, verbose off, ascii formatted data)tek.write('HEAD OFF;VERB OFF;WFMP:ENC ASC')# source = CH1, CH2... MATH1, MATH2... REF1, REF2...source='CH1'tek.write('DATa:SOUrce ' + source)# forces to read from 1st acquired sample and total number of samplestek.write('DATA:START 1')tek.write('DATA:STOP 500')# stop RUNNING acquisition to freeze memories storage inside the TDS540Ctek.write('ACQuire:STATE STOP')# get raw trace data and convert to a numpy arrayraw_trace_data = np.array(list(map(float, tek.query('CURV?').split(','))))# vertical gain (100V per division)vgain = float(tek.query('WFMP:' + source + ':YMU?'))# horizontal intervalhorizontal_interval = float(tek.query('WFMP:' + source + ':XIN?'))# multiply data by vertical gain without vertical offsettrace_data1 = raw_trace_data * vgain# construct time axis (TDS540C 1uS per division)t_axis = np.arange(len(raw_trace_data)) * horizontal_interval * 1000000# plot view of CH1 on the Macintoshplt.plot(t_axis, trace_data1, "b", label="P5010")# the TDS540C still frozen so now we transfer CH1source='CH2'tek.write('DATa:SOUrce ' + source)# get raw trace data and convert to a numpy arrayraw_trace_data = np.array(list(map(float, tek.query('CURV?').split(','))))# vertical gain (100mV per division)vgain = float(tek.query('WFMP:' + source + ':YMU?'))*1000# multiply data by vertical gain without vertical offsettrace_data2 = raw_trace_data * vgain# plot view of CH2 on the Macintoshplt.plot(t_axis, trace_data2, "r", label="P6021")# compute then plot the active power (P5010 voltage probe on CH1, P6021 current probe on CH1)plt.plot(t_axis, trace_data1 * trace_data2 / 1000, "k", label="Watts")# Show legendsplt.legend()# Show final plot CH1, CH2 and CH1*CH2plt.show()# start running again acquisition of the TDS540Ctek.write('ACQuire:STATE RUN')I'd like to also thank Matthieu Dartiailh how is one key worldwide person in charge to maintain PyVisa on github who did help me setup my Macintosh with the GPIB-USB-HS interface then run the Pythonhttps://github.com/pyvisa/pyvisa/tree/black-cisP.S. There is still an issue where for some reason, I cannot transfer in BINary mode which is why I kept ASCII mode (much slower).Albert

author: Tantratron
author_rank: Frequent Contributor
timestamp: June 07, 2020, 03:22:16 am
content: Quote from: Tantratron on June 04, 2020, 03:23:49 pmNow it works with BINary case where both ASC or BIN provides the same valuesCode:# example to transfer and display CH1 and CH2 from TDS540Cimport pyvisaimport numpy as npimport matplotlib.pyplot as plt# initialize the PyVISA, the GPIB-USB-HS interface and TDS540Crm = pyvisa.ResourceManager()rm.list_resources()tek = rm.open_resource('GPIB0::1::INSTR')tek.write_termination = '\n'tek.read_termination = '\n'# configure the data format (no header, verbose off, ascii formatted data)tek.write('HEAD OFF;VERB OFF;WFMP:ENC ASC')# source = CH1, CH2... MATH1, MATH2... REF1, REF2...tek.write('DATa:SOUrce CH1')# forces to read from 1st acquired sample and total number of samplestek.write('DATA:START 1')tek.write('DATA:STOP 80')# stop RUNNING acquisition to freeze memories storage inside the TDS540Ctek.write('ACQuire:STATE STOP')# get raw trace data and convert to a numpy array#raw_trace_data = np.array(list(map(float, tek.query('CURV?').split(','))))print(tek.query('CURV?'))print(' ')# configure the data format (no header, verbose off, binary formatted data)tek.write('HEAD OFF;VERB OFF;WFMP:ENC BIN')print(tek.query_binary_values('CURV?', datatype='b', is_big_endian=True))print(' ')# start running again acquisition of the TDS540Ctek.write('ACQuire:STATE RUN')