I'm trying to connect a Tektronix TDS1001B to Ubuntu Precise. I have managed to connect the scope to a Windows XP machine running TekVISA OpenChoice so hardware is working.
Is there any tutorial how to connect such scope to Linux?
On Ubuntu Precise, I have followed this tutorial. I have installed python-gpib_3.2.11-0.2ubuntu7_i386.deb as well as libgpib0_3.2.11-0.2ubuntu7_i386.deb. I have matlab installed too. When I run this python code, I get:
root@laptop:~# dmesg -c [ 296.744133] usb 3-1: new full-speed USB device number 2 using uhci_hcd [ 296.918061] generic-usb 0003:0699:036B.0005: hiddev0,hidraw4: USB HID v1.00 Device [Tektronix, Inc. Tektronix TDS1001B] on usb-0000:00:1a.0-1/input0 [ 297.504214] usb 3-1: USB disconnect, device number 2 [ 299.432087] hub_port_connect_change: 30 callbacks suppressed [ 299.432099] hub 3-0:1.0: connect-debounce failed, port 1 disabled [ 299.732161] usb 3-1: new full-speed USB device number 3 using uhci_hcd [ 299.947136] usbcore: registered new interface driver usbtmc root@laptop:~# lsmod | grep usbtmc usbtmc 17996 0 root@laptop:~# ls -lah /dev/usbtmc0 crw------- 1 root root 180, 176 Feb 17 22:36 /dev/usbtmc0 root@laptop:~# cat /dev/usbtmc0 cat: /dev/usbtmc0: Connection timed out root@laptop:~# python tds-2012.py failed to open configuration file Traceback (most recent call last): File "tds-2012.py", line 34, in <module> gpib.find('scope') gpib.error: Find Error: can't find device! Any idea how I could figure out what is the name of my scope? Is there a command line library for gpib? Any idea how to manage to run this tutorial?
1 Answer
I have found a solution. First, forget libgpib0: you need to use usbtmc which is built in Ubuntu kernel. After plugging the scope, makes sure that you have the usbtmc stuff as in my first post:
root@laptop:~# dmesg -c [ 296.744133] usb 3-1: new full-speed USB device number 2 using uhci_hcd [ 296.918061] generic-usb 0003:0699:036B.0005: hiddev0,hidraw4: USB HID v1.00 Device [Tektronix, Inc. Tektronix TDS1001B] on usb-0000:00:1a.0-1/input0 [ 297.504214] usb 3-1: USB disconnect, device number 2 [ 299.432087] hub_port_connect_change: 30 callbacks suppressed [ 299.432099] hub 3-0:1.0: connect-debounce failed, port 1 disabled [ 299.732161] usb 3-1: new full-speed USB device number 3 using uhci_hcd [ 299.947136] usbcore: registered new interface driver usbtmc root@laptop:~# lsmod | grep usbtmc usbtmc 17996 0 root@laptop:~# ls -lah /dev/usbtmc0 crw------- 1 root root 180, 176 Feb 17 22:36 /dev/usbtmc0 Note that you can write and read to /dev/usbtmc0:
echo "*IDN?" > /dev/usbtmc0 cat /dev/usbtmc0 You should get something like:
TEKTRONIX,TDS 1001B,C062368,CF:91.1CT FV:v22.01 You might have to do:
chmod a+w /dev/usbtmc0 Then, I have updated and fixed the python script:
--- tds-2012.py 2013-02-23 11:26:54.902570542 -0800 +++ tds-2012.py 2013-02-23 11:40:59.506758703 -0800 @@ -21,8 +21,7 @@ # in /etc/gpib.conf. -from Gpib import * -from matplotlib.matlab import * +from matplotlib.pyplot import * from string import * from time import * from struct import * @@ -30,9 +29,23 @@ # how long to sleep after issuing a write sleeptime = 0.01 -# set up GPIB comms and clear device -scope = gpib.find('scope') -gpib.clear(scope) +class gpib_usbtmc: + def __init__(self): + self.usbtmc = open("/dev/usbtmc0", "r+") + + def write(self, wathever, string): + self.usbtmc.write(string + "\n") + + def read(self, whatever, size): + return self.usbtmc.readline().strip() + + def readbin(self, whatever, size): + return self.usbtmc.readline() + +scope = 0 +gpib = gpib_usbtmc() +#gpib.write(scope, '*IDN?') +#print "ID: ", gpib.read(scope, 128) # set SRQ operation gpib.write(scope,'DESE 1') @@ -172,7 +185,7 @@ axis([0,points,-5*voltsdiv,5*voltsdiv]) xlabel(sweep_string) ylabel(volt_string) -set(gca(), 'xticklabels', []) +setp(gca(), 'xticklabels', []) if not gca().is_first_col(): set(gca(), 'yticklabels', []) if not gca().is_last_row(): The whole script looks like now:
#!/usr/bin/env python # found on < <ftp:// # tds-2012.py # version 0.1 -- 27 Jan 2004 # # Plot display of Tektronix TDS-2012 (or other TDS-10xx or TDS-20xx DSO) # # Copyright 2004 by John R. Ackermann N8UR () # Licensed under the GPL version 2 or later; see the file COPYING # included with this distribution. I request, but do not require, that # any modifications that correct bugs or errors, or increase the program's # functionality, be sent via email to the author at the address above. # # Current status: # Version 0.1 -- first version, and first ever Python program. Note that # binary read requires updated linux-gpib python bindings (post version # 3.1.99). If you don't have that version, you can convert to use an # ASCII data read as commented below. Assumes that "scope" is defined # in /etc/gpib.conf. from matplotlib.pyplot import * from string import * from time import * from struct import * # how long to sleep after issuing a write sleeptime = 0.01 class gpib_usbtmc: def __init__(self): self.usbtmc = open("/dev/usbtmc0", "r+") def write(self, wathever, string): self.usbtmc.write(string + "\n") def read(self, whatever, size): return self.usbtmc.readline().strip() def readbin(self, whatever, size): return self.usbtmc.readline() scope = 0 gpib = gpib_usbtmc() #gpib.write(scope, '*IDN?') #print "ID: ", gpib.read(scope, 128) # set SRQ operation gpib.write(scope,'DESE 1') gpib.write(scope,'*ESE 1') gpib.write(scope,'*SRE 32') # turn off response headers and set waveform output to default binary # it seems like these need to be sent separately and not concatenated gpib.write(scope,'head 0') # for ASCII dump, send 'dat ASCII' instead gpib.write(scope,'dat INIT') sleep(sleeptime) # get instrument settings gpib.write(scope,'ch1:scale?') sleep(sleeptime) voltsdiv = float(gpib.read(scope,80)) if voltsdiv >= 1: volt_string = '%i V / div' % (voltsdiv) else: volt_string = '%i mv / div' % (voltsdiv * 1000) gpib.write(scope,'hor:mai:sca?') sleep(sleeptime) tmp = float(gpib.read(scope,80)) rawsweep = tmp if tmp >= 1: sweep_val = tmp sweep_suf = "S" if tmp < 1: sweep_val = tmp * 10e2 sweep_suf = "mS" if tmp < 0.001: sweep_val = tmp * 10e5 sweep_suf = "uS" if tmp < 0.000001: sweep_val = tmp * 10e8 sweep_suf = "nS" sweep_val = '%.f' % sweep_val sweep_string = sweep_val + ' ' + (sweep_suf) + " / div" # acquire gpib.write(scope,'acquire:state on') sleep(sleeptime) # get the waveform preamble gpib.write(scope,'wfmpre?') sleep(sleeptime) tmp = gpib.read(scope,256) preamble = split(tmp,';') # number of points in trace points = int(preamble[5]) # volts per bit (-127 to +128) voltsbit = float(preamble[12]) # get the curve gpib.write(scope,'curv?') sleep(sleeptime) # binary data read and convert to list tmp = gpib.readbin(scope,4096) # for ASCII read, use 'gpib.read(scope,16384)' instead of the above, and # delete the next two lines. You'll need to use 'split' to convert the # comma-delimited values returned in 'tmp' to a list of values called # 'tmplist', and you may need to adjust the offsets used in the 'for' loop # to end up with the proper number of points formatstring = '%ib' % (len(tmp)) tmplist = unpack(formatstring,tmp) trace = [] # there's a newline at the end of the data, thus the strange slice for x in tmplist[len(tmplist)-points-1:-1]: trace.append(int(x)*voltsbit) # get some measurements, just for fun tmp = 9.9E37 gpib.write(scope,'measu:imm:typ PK2;:measu:imm:sou CH1') sleep(sleeptime) gpib.write(scope,'measu:imm:val?') sleep(sleeptime) tmp = float(gpib.read(scope,80)) if tmp != 9.9E37: peak_string = 'Pk-Pk: %.3f V' % (tmp) else: peak_string = '' gpib.write(scope,'measu:imm:typ MEAN;:measu:imm:sou CH1') sleep(sleeptime) gpib.write(scope,'measu:imm:val?') tmp = float(gpib.read(scope,80)) if tmp != 9.9E37: mean_string = 'Mean: %.3f V' % (tmp) else: mean_string = '' gpib.write(scope,'measu:imm:typ PERI;:measu:imm:sou CH1') sleep(sleeptime) gpib.write(scope,'measu:imm:val?') tmp = float(gpib.read(scope,80)) if tmp >= 1: period_val = tmp period_suf = "S" if tmp < 1: period_val = tmp * 10e2 period_suf = "mS" if tmp < 0.001: sweep_val = tmp * 10e5 sweep_suf = "uS" if tmp < 0.000001: period_val = tmp * 10e8 period_suf = "nS" if tmp != 9.9E37: period_string = 'Period: %.3f' % (period_val) + ' ' + period_suf else: period_string = '' gpib.write(scope,'measu:imm:typ FREQ;:measu:imm:sou CH1') sleep(sleeptime) gpib.write(scope,'measu:imm:val?') tmp = float(gpib.read(scope,80)) if tmp < 1e3: freq_val = tmp freq_suf = "Hz" if tmp < 1e6: freq_val = tmp / 10e2 freq_suf = "kHz" if tmp >= 1e6: freq_val = tmp / 10e5 freq_suf = "MHz" if tmp != 9.9E37: freq_string = 'Freq: %.3f' % (freq_val) + ' ' + freq_suf else: freq_string = '' # plot plot(trace) axis([0,points,-5*voltsdiv,5*voltsdiv]) xlabel(sweep_string) ylabel(volt_string) setp(gca(), 'xticklabels', []) if not gca().is_first_col(): set(gca(), 'yticklabels', []) if not gca().is_last_row(): set(gca(), 'xticklabels', []) grid(1) text(0.03*points,-4.9*voltsdiv, peak_string) text(0.03*points,-4.4*voltsdiv, mean_string) text(0.72*points,-4.93*voltsdiv, freq_string) text(0.72*points,-4.4*voltsdiv, period_string) show() And it's working! Yes, you can thank me ;-)