Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Python (http://www.velocityreviews.com/forums/f43-python.html)
-   -   [newbie] problem with usbtmc-communication (http://www.velocityreviews.com/forums/t955107-newbie-problem-with-usbtmc-communication.html)

Jean Dubois 12-04-2012 12:14 PM

[newbie] problem with usbtmc-communication
 
The following test program which tries to communicate with a Keithley
2200 programmable power supply using usbtmc in Python does not work as
expected. I have connected a 10 ohm resistor to its terminals and I
apply 0.025A, 0.050A, 0.075A en 0.1A,
I then measure the current and the voltage en write them in a file
De data produced looks like this:
0.00544643 0.254061; first current value is wrong, voltage value is
correct
0.0250807 0.509289; second current value is wrong, but it corresponds
to the first, second voltage is correct
0.0501099 0.763945; 3rd current value is wrong, but it corresponds to
the second, 3rd voltage is right
0.075099 1.01792; 4th current value is wrong, it corresponds to the
3rd, 4th voltage is right
4th correct current value is missing

But is should be (numerical inaccuracy taking into account)(these data
were produced by a similar octave-program):
0.0248947 0.254047
0.0499105 0.509258
0.0749044 0.764001
0.0998926 1.01828

Here is the python-program:
#!/usr/bin/python
import time
import os
import sys
measurementcurr=''
measurementvolt=''
timesleepdefault=1
filename ='mydata.txt'
usbkeith = open('/dev/usbtmc1','r+')
usbkeith.flush()
usbkeith.write("*IDN?\n")
#strip blank line:
identification=usbkeith.readline().strip()
print 'Found device: ',identification
usbkeith.write("SYST:REM" + "\n")
usbkeith.write(":SENS:VOLT:PROT 1.5\n")
keithdata = open(filename,'w')
#start first measurement
usbkeith.write(":SOUR:CURR 0.025\n")
usbkeith.write(":OUTP:STAT ON\n")
time.sleep(timesleepdefault)
usbkeith.write(":MEAS:CURR?\n")
time.sleep(timesleepdefault)
measurementcurr=usbkeith.readline()
print 'Measured current 1: ',measurementcurr
usbkeith.write("MEAS:VOLT?\n")
time.sleep(timesleepdefault)
measurementvolt=usbkeith.readline()
print 'Measured voltage 1: ',measurementvolt
keithdata.write(measurementcurr.strip()+' '+measurementvolt)
#start second measurement
usbkeith.write("SOUR:CURR 0.050\n")
time.sleep(timesleepdefault)
usbkeith.write("MEAS:CURR?\n")
time.sleep(timesleepdefault)
measurementcurr=usbkeith.readline()
print 'Measured current 2: ',measurementcurr
usbkeith.write("MEAS:VOLT?\n")
time.sleep(timesleepdefault)
measurementvolt=usbkeith.readline()
print 'Measured voltage 2: ',measurementvolt
keithdata.write(measurementcurr.strip()+' '+measurementvolt)
#start 3rd measurement
time.sleep(timesleepdefault)
usbkeith.write("SOUR:CURR 0.075\n")
time.sleep(timesleepdefault)
usbkeith.write("MEAS:CURR?\n")
time.sleep(timesleepdefault)
measurementcurr=usbkeith.readline()
print 'Measured current 3: ',measurementcurr
usbkeith.write("MEAS:VOLT?\n")
time.sleep(timesleepdefault)
measurementvolt=usbkeith.readline()
print 'Measured voltage 3: ',measurementvolt
keithdata.write(measurementcurr.strip()+' '+measurementvolt)
#start 4th measurement
time.sleep(timesleepdefault)
usbkeith.write("SOUR:CURR 0.1\n")
time.sleep(timesleepdefault)
usbkeith.write("MEAS:CURR?\n")
time.sleep(timesleepdefault)
measurementcurr=usbkeith.readline()
print 'Measured current 4: ',measurementcurr
usbkeith.write("MEAS:VOLT?\n")
time.sleep(timesleepdefault)
measurementvolt=usbkeith.readline()
print 'Measured voltage 4: ',measurementvolt
keithdata.write(measurementcurr.strip()+' '+measurementvolt)
usbkeith.write(":OUTP:STAT OFF\n")
print "Goodbye, data logged in file:"
print filename
usbkeith.close()
keithdata.close()

can anyone here what is going wrong and how to get it right?

thanks
jean

Jean Dubois 12-04-2012 04:12 PM

Re: problem with usbtmc-communication
 
On 4 dec, 15:33, w...@mac.com wrote:
> On Dec 4, 2012, at 7:14 AM, Jean Dubois <jeandubois...@gmail.com> wrote:
>
>
>
> > The following test program which tries to communicate with a Keithley
> > 2200 programmable power supply using usbtmc in Python does not work as
> > expected. I have connected a 10 ohm resistor to its terminals and I
> > apply 0.025A, 0.050A, 0.075A en 0.1A,
> > I then measure the current and the voltage en write them in a file
> > De data produced looks like this:
> > 0.00544643 0.254061; first current value is wrong, voltage value is
> > correct
> > 0.0250807 0.509289; second current value is wrong, but it corresponds
> > to the first, second voltage is correct
> > 0.0501099 0.763945; 3rd current value is wrong, but it corresponds to
> > the second, 3rd voltage is right
> > 0.075099 1.01792; 4th current value is wrong, *it corresponds to the
> > 3rd, 4th voltage is right
> > * * * * * * * * * * * * * *4th correct current value is missing

>
> > But is should be (numerical inaccuracy taking into account)(these data
> > were produced by a similar octave-program):
> > 0.0248947 0.254047
> > 0.0499105 0.509258
> > 0.0749044 0.764001
> > 0.0998926 1.01828

>
> > Here is the python-program:
> > #!/usr/bin/python
> > import time
> > import os
> > import sys
> > measurementcurr=''
> > measurementvolt=''
> > timesleepdefault=1
> > filename ='mydata.txt'
> > usbkeith = open('/dev/usbtmc1','r+')
> > usbkeith.flush()
> > usbkeith.write("*IDN?\n")
> > #strip blank line:
> > identification=usbkeith.readline().strip()
> > print 'Found device: ',identification
> > usbkeith.write("SYST:REM" + "\n")
> > usbkeith.write(":SENS:VOLT:PROT 1.5\n")
> > keithdata = open(filename,'w')
> > #start first measurement
> > usbkeith.write(":SOUR:CURR 0.025\n")
> > usbkeith.write(":OUTP:STAT ON\n")
> > time.sleep(timesleepdefault)
> > usbkeith.write(":MEAS:CURR?\n")
> > time.sleep(timesleepdefault)
> > measurementcurr=usbkeith.readline()
> > print 'Measured current 1: ',measurementcurr
> > usbkeith.write("MEAS:VOLT?\n")
> > time.sleep(timesleepdefault)
> > measurementvolt=usbkeith.readline()
> > print 'Measured voltage 1: ',measurementvolt
> > keithdata.write(measurementcurr.strip()+' '+measurementvolt)
> > #start second measurement
> > usbkeith.write("SOUR:CURR 0.050\n")
> > time.sleep(timesleepdefault)
> > usbkeith.write("MEAS:CURR?\n")
> > time.sleep(timesleepdefault)
> > measurementcurr=usbkeith.readline()
> > print 'Measured current 2: ',measurementcurr
> > usbkeith.write("MEAS:VOLT?\n")
> > time.sleep(timesleepdefault)
> > measurementvolt=usbkeith.readline()
> > print 'Measured voltage 2: ',measurementvolt
> > keithdata.write(measurementcurr.strip()+' '+measurementvolt)
> > #start 3rd measurement
> > time.sleep(timesleepdefault)
> > usbkeith.write("SOUR:CURR 0.075\n")
> > time.sleep(timesleepdefault)
> > usbkeith.write("MEAS:CURR?\n")
> > time.sleep(timesleepdefault)
> > measurementcurr=usbkeith.readline()
> > print 'Measured current 3: ',measurementcurr
> > usbkeith.write("MEAS:VOLT?\n")
> > time.sleep(timesleepdefault)
> > measurementvolt=usbkeith.readline()
> > print 'Measured voltage 3: ',measurementvolt
> > keithdata.write(measurementcurr.strip()+' '+measurementvolt)
> > #start 4th measurement
> > time.sleep(timesleepdefault)
> > usbkeith.write("SOUR:CURR 0.1\n")
> > time.sleep(timesleepdefault)
> > usbkeith.write("MEAS:CURR?\n")
> > time.sleep(timesleepdefault)
> > measurementcurr=usbkeith.readline()
> > print 'Measured current 4: ',measurementcurr
> > usbkeith.write("MEAS:VOLT?\n")
> > time.sleep(timesleepdefault)
> > measurementvolt=usbkeith.readline()
> > print 'Measured voltage 4: ',measurementvolt
> > keithdata.write(measurementcurr.strip()+' '+measurementvolt)
> > usbkeith.write(":OUTP:STAT OFF\n")
> > print "Goodbye, data logged in file:"
> > print filename
> > usbkeith.close()
> > keithdata.close()

>
> > can anyone here what is going wrong and how to get it right?

>
> > thanks
> > jean
> > --
> >http://mail.python.org/mailman/listinfo/python-list

>
> Just guessing here - it looks as though you are setting the current and THEN turning the output on. *That might be the correct sequence or it might not.
> *If not, it would explain the offset between that and the subsequent readings.

I changed the order of the two commands (first turn the source on then
set the current) and this is the result
0.0994434 0.253431; first current value wrong but the value seems what
the last one should be!, voltage correct
0.0251083 0.508319; second current value wrong but this is what the
first should be, voltage correct
0.0501242 0.762834; 3rd current value wrong but this is what the
second current value should ve, voltage correct
0.0749226 1.0167: 4th current value wrong but this is what the 3rd
current value should be, voltage correct

>
> This is really a Keithley problem, not a Python problem.

I thought also it was a Keithley problem but then I programmed exactly
the same in octave and with octave I do get the correct results, so I
think now it is at least a Python-related problem. Here is the octave-
code so you see what I mean and maybe find what should be changed in
the Python-code.

clear
file_id = fopen('mydata.txt', 'w');
readbytes = 10000;
timesleepdefault=1
fd = usbtmc_open("/dev/usbtmc1");
usbtmc_write(fd,"*IDN?");
result = char(usbtmc_read(fd,readbytes))
usbtmc_write(fd,"SYST:REM");
usbtmc_write(fd,"SENS:VOLT:PROT 1.5");
#start 1st measurement
usbtmc_write(fd,"SOUR:CURR 0.025");
usbtmc_write(fd,"OUTP:STAT ON");
pause (timesleepdefault)
usbtmc_write(fd,"MEAS:CURR?");
resultcurr = char(usbtmc_read(fd,readbytes))
#strip line termination
resultcurr = resultcurr(1:end-1);
usbtmc_write(fd,"MEAS:VOLT?");
resultvolt = char(usbtmc_read(fd,readbytes))
fprintf(file_id,'%s',resultcurr,' ',resultvolt)
#start 2nd measurement
usbtmc_write(fd,"SOUR:CURR 0.050");
pause (timesleepdefault)
usbtmc_write(fd,"MEAS:CURR?");
resultcurr = char(usbtmc_read(fd,readbytes))
#strip line termination
resultcurr = resultcurr(1:end-1);
usbtmc_write(fd,"MEAS:VOLT?");
resultvolt = char(usbtmc_read(fd,readbytes))
fprintf(file_id,'%s',resultcurr,' ',resultvolt)
#start 3rd measurement
usbtmc_write(fd,"SOUR:CURR 0.075");
pause (timesleepdefault)
usbtmc_write(fd,"MEAS:CURR?");
resultcurr = char(usbtmc_read(fd,readbytes))
#strip line termination
resultcurr = resultcurr(1:end-1);
usbtmc_write(fd,"MEAS:VOLT?");
resultvolt = char(usbtmc_read(fd,readbytes))
fprintf(file_id, '%s',resultcurr,' ',resultvolt)
#start 4th measurement
usbtmc_write(fd,"SOUR:CURR 0.1");
pause (timesleepdefault)
usbtmc_write(fd,"MEAS:CURR?");
resultcurr = char(usbtmc_read(fd,readbytes))
#strip line termination
resultcurr = resultcurr(1:end-1);
usbtmc_write(fd,"MEAS:VOLT?");
resultvolt = char(usbtmc_read(fd,readbytes))
fprintf(file_id,'%s',resultcurr,' ', resultvolt)
usbtmc_close(fd);
fclose(file_id)


Terry Reedy 12-04-2012 07:55 PM

Re: [newbie] problem with usbtmc-communication
 
On 12/4/2012 7:14 AM, Jean Dubois wrote:
> The following test program which tries to communicate with a Keithley
> 2200 programmable power supply using usbtmc in Python does not work as
> expected. I have connected a 10 ohm resistor to its terminals and I
> apply 0.025A, 0.050A, 0.075A en 0.1A,
> I then measure the current and the voltage en write them in a file
> De data produced looks like this:
> 0.00544643 0.254061; first current value is wrong, voltage value is
> correct
> 0.0250807 0.509289; second current value is wrong, but it corresponds
> to the first, second voltage is correct
> 0.0501099 0.763945; 3rd current value is wrong, but it corresponds to
> the second, 3rd voltage is right
> 0.075099 1.01792; 4th current value is wrong, it corresponds to the
> 3rd, 4th voltage is right
> 4th correct current value is missing
>
> But is should be (numerical inaccuracy taking into account) (these data
> were produced by a similar octave-program):
> 0.0248947 0.254047
> 0.0499105 0.509258
> 0.0749044 0.764001
> 0.0998926 1.01828
>
> Here is the python-program:
> #!/usr/bin/python
> import time
> import os
> import sys


> measurementcurr=''
> measurementvolt=''
> timesleepdefault=1
> filename ='mydata.txt'
> usbkeith = open('/dev/usbtmc1','r+')
> usbkeith.flush()
> usbkeith.write("*IDN?\n")
> #strip blank line:
> identification=usbkeith.readline().strip()
> print 'Found device: ',identification
> usbkeith.write("SYST:REM" + "\n")
> usbkeith.write(":SENS:VOLT:PROT 1.5\n")
> keithdata = open(filename,'w')


> #start first measurement
> usbkeith.write(":SOUR:CURR 0.025\n")
> usbkeith.write(":OUTP:STAT ON\n")
> time.sleep(timesleepdefault)
> usbkeith.write(":MEAS:CURR?\n")
> time.sleep(timesleepdefault)
> measurementcurr=usbkeith.readline()
> print 'Measured current 1: ',measurementcurr
> usbkeith.write("MEAS:VOLT?\n")
> time.sleep(timesleepdefault)
> measurementvolt=usbkeith.readline()
> print 'Measured voltage 1: ',measurementvolt
> keithdata.write(measurementcurr.strip()+' '+measurementvolt)

[3 near repetitions snipped]

This sort of repetitious code without even line breaks is painful for me
to read. Python has looping statements for a reason. Replace all four
nearly identical blocks with the following. (If you are not familiar
with built-in enumerate, you should be. Read its entry in the library
manual.)

for number, current_in in enumerate(
('0.025', '0.050'. '0.075', '0.100'), 1)
usbkeith.write(":SOUR:CURR %s\n" % current_in)
...
print 'Measured current %d: ' % number, measurementcurr
...
print 'Measured voltage %d: ' % number, measurementvolt

Now you can make changes in only one place and easily add more test values.

> print "Goodbye, data logged in file:"
> print filename
> usbkeith.close()
> keithdata.close()
>
> can anyone here what is going wrong and how to get it right?


No, but if both the python and octave programs used loops, it would be
easier to see if both are doing the same things before, within, and
after the loop.

--
Terry Jan Reedy


Jean Dubois 12-05-2012 08:38 PM

Re: problem with usbtmc-communication
 
On 5 dec, 16:26, w...@mac.com wrote:
> On Dec 4, 2012, at 11:12 AM, Jean Dubois <jeandubois...@gmail.com> wrote:
>
> > On 4 dec, 15:33, w...@mac.com wrote:
> >> On Dec 4, 2012, at 7:14 AM, Jean Dubois <jeandubois...@gmail.com> wrote:

>
> >>> The following test program which tries to communicate with a Keithley
> >>> 2200 programmable power supply using usbtmc in Python does not work as

>
> Is usbtmc a software layer (library of some sort) or some sort of hardware adapter?

This is the information concerning usbtmc from the National
Instruments site:
USBTMC stands for USB Test & Measurement Class. USBTMC is a protocol
built on top of USB that allows GPIB-like communication with USB
devices. From the user's point of view, the USB device behaves just
like a GPIB device. For example, you can use VISA Write to send the
*IDN? query and use VISA Read to get the response. The USBTMC protocol
supports service request, triggers and other GPIB specific operations.

>
>
>
>
>
>
>
>
> >>> expected. I have connected a 10 ohm resistor to its terminals and I
> >>> apply 0.025A, 0.050A, 0.075A en 0.1A,
> >>> I then measure the current and the voltage en write them in a file
> >>> De data produced looks like this:
> >>> 0.00544643 0.254061; first current value is wrong, voltage value is
> >>> correct
> >>> 0.0250807 0.509289; second current value is wrong, but it corresponds
> >>> to the first, second voltage is correct
> >>> 0.0501099 0.763945; 3rd current value is wrong, but it corresponds to
> >>> the second, 3rd voltage is right
> >>> 0.075099 1.01792; 4th current value is wrong, *it corresponds to the
> >>> 3rd, 4th voltage is right
> >>> * * * * * * * * * * * * * *4th correct current value is missing

>
> >>> But is should be (numerical inaccuracy taking into account)(these data
> >>> were produced by a similar octave-program):
> >>> 0.0248947 0.254047
> >>> 0.0499105 0.509258
> >>> 0.0749044 0.764001
> >>> 0.0998926 1.01828

>
> >>> Here is the python-program:
> >>> #!/usr/bin/python
> >>> import time
> >>> import os
> >>> import sys
> >>> measurementcurr=''
> >>> measurementvolt=''
> >>> timesleepdefault=1
> >>> filename ='mydata.txt'
> >>> usbkeith = open('/dev/usbtmc1','r+')
> >>> usbkeith.flush()
> >>> usbkeith.write("*IDN?\n")
> >>> #strip blank line:
> >>> identification=usbkeith.readline().strip()
> >>> print 'Found device: ',identification
> >>> usbkeith.write("SYST:REM" + "\n")
> >>> usbkeith.write(":SENS:VOLT:PROT 1.5\n")
> >>> keithdata = open(filename,'w')
> >>> #start first measurement
> >>> usbkeith.write(":SOUR:CURR 0.025\n")
> >>> usbkeith.write(":OUTP:STAT ON\n")
> >>> time.sleep(timesleepdefault)
> >>> usbkeith.write(":MEAS:CURR?\n")
> >>> time.sleep(timesleepdefault)
> >>> measurementcurr=usbkeith.readline()
> >>> print 'Measured current 1: ',measurementcurr
> >>> usbkeith.write("MEAS:VOLT?\n")
> >>> time.sleep(timesleepdefault)
> >>> measurementvolt=usbkeith.readline()

>
> Without knowing anything about the usbtmc hardware/software it is hard tomake real recommendations, but it seems pretty clear that you are being stepped on by a buffer problem of some sort. *I'm VERY suspicious of using of readline() as a way of getting the data out of the usbtmc thingy. *That makes python treat the Keithley as a file-like object and there are way too many ways the file pointer may not be where you think it is.
>
> I note that in your Octave example you are reading characters rather thanlines. *It seems to me that you have two choices here, either do the equivalent in python or dig through the Keithley documentation to find the hexcodes that usbtmc is presumably translating your commands into. *If you can find those, and if you are interested, I can send you off-line the handler I wrote a couple of years ago that used a dictionary to translate English commands into hex, then assembled those with a checksum and sent the string out to a Keyspan usb to serial converter.


If you could show me how to "do the equivalent in Python" I'd
appreciate that very much

best regards,
jean

Dennis Lee Bieber 12-05-2012 11:08 PM

Re: problem with usbtmc-communication
 
On Wed, 5 Dec 2012 12:38:04 -0800 (PST), Jean Dubois
<jeandubois314@gmail.com> declaimed the following in
gmane.comp.python.general:

> This is the information concerning usbtmc from the National
> Instruments site:
> USBTMC stands for USB Test & Measurement Class. USBTMC is a protocol
> built on top of USB that allows GPIB-like communication with USB
> devices. From the user's point of view, the USB device behaves just
> like a GPIB device. For example, you can use VISA Write to send the
> *IDN? query and use VISA Read to get the response. The USBTMC protocol
> supports service request, triggers and other GPIB specific operations.
>


Off-hand, that seems to imply that you might need a GPIB library to
talk to the "virtual" GPIB provided by USBTMC -- or something that talks
to the USBTMC library directly.

Note that the NEXT paragraph reads:

NI> SBTMC allows instrument manufacturers to upgrade the physical layer
from GPIB to USB while maintaining software compatibility with existing
software, such as instrument drivers and any application that uses VISA.
This is also what the VXI-11 protocol provides for TCP/IP.

So now you have to consider what "VISA" is...

http://digital.ni.com/manuals.nsf/we...256F47007B00B3

Since usable from M$ VB the question becomes: .NET or native API...
If native API, the win32 extension library on Windows should allow for
using the API from Python. If .NET, the ctypes library may allow access.
NOTE: I've not bothered downloading the docs -- it's your hardware <G>




--
Wulfraed Dennis Lee Bieber AF6VN
wlfraed@ix.netcom.com HTTP://wlfraed.home.netcom.com/


Jean Dubois 12-06-2012 01:50 PM

Re: problem with usbtmc-communication
 
On 5 dec, 23:21, w...@mac.com wrote:
> On Dec 5, 2012, at 3:38 PM, Jean Dubois <jeandubois...@gmail.com> wrote:
>
> [byte]
>
>
>
> >> I note that in your Octave example you are reading characters rather than lines. *It seems to me that you have two choices here, either do the equivalent in python or dig through the Keithley documentation to find the hex codes thatusbtmcis presumably translating your commands into. *If youcan find those, and if you are interested, I can send you off-line the handler I wrote a couple of years ago that used a dictionary to translate English commands into hex, then assembled those with a checksum and sent the string out to a Keyspan usb to serial converter.

>
> > If you could show me how to "do the equivalent in Python" I'd
> > appreciate that very much

>
> > best regards,
> > jean
> > --
> >http://mail.python.org/mailman/listinfo/python-list

>
> OK - I've excerpted some of the relevant code (the original was much longer and included a lot of error checking). *Please understand that the comments were for my own use, this was never intended to see the light of day (as it were). *Also, the structure grew from a situation where I only hadto worry about a single controller model - single relay model to one whereI had to be able to deal with two controllers and two relay models. *This was all python 2.7 of course.
>
> ........................cut on dotted line..........................
> """
> *serial_port = /dev/tty.KeySerial1, 2, 3, etc.
> *X10_controller = 1132B *or TI103
> *Relay_model = UM506 *or RBn04
> *Relay_address = B2
>
> """
> import serial, string
>
> def checksum256(st):
> * * temp = reduce(lambda x,y:x+y, map(ord,st)) % 256
> * * if temp < 9:
> * * * * hex_temp = '0'+str(temp)
> * * * * return hex_temp
> * * hex_temp = hex(temp).upper()[2:]
> * * return hex_temp
>
> letr_address_dict = {'A':'\x46', 'B':'\x4E', 'C':'\x42', 'D':'\x4A', 'E':'\x41', 'F':'\x49', 'G':'\x45', 'H':'\x4D', 'I':'\x47', *'J':'\x4F', *'K':'\x43', *'L':'\x4B', *'M':'\x40', *'N':'\x48', *'O':'\x44', *'P':'\x4C' }
> numb_address_dict = {'1':'\x4C', '2':'\x5C', '3':'\x44', '4':'\x54', '5':'\x42', '6':'\x52', '7':'\x4A', '8':'\x5A', '9':'\x4E', '10':'\x5E', '11':'\x46', '12':'\x56', '13':'\x40', '14':'\x50', '15':'\x48', '16':'\x58' }
> cmd_dict * * = * * *{'SoC':'\x63', 'All_Units_Off':'\x41', 'All_Lights_On':'\x43', 'ON':'\x45', 'OFF':'\x47', 'Dim':'\x49', 'Bright':'\x4B', 'All_Lights_Off':'\x4D', 'Rep_Cnt1':'\x41', 'Rep_Cnt2':'\x42'}
>
> def relay(port, controller_model, relay_model, relay_address, command):
> * * if controller_model == '1132B':
> * * * * if relay_model == 'UM506' or relay_model == 'UM7206':
> * * * * * * letr = letr_address_dict[relay_address[0]]
> * * * * * * numb = numb_address_dict[relay_address[1]]
> * * * * * * cmd = cmd_dict[command]
> * * * * * * cmd_string = '\x63'+letr+numb+cmd+'\x42' * * # Start-of-Command + address_letter + address_number + command + Rep-count
> * * * * * * ser = serial.Serial(port, 9600, timeout=1) * # Set up handle to serial port
> * * * * * * stat1 = ser.write('\x02') * * * * * * * * * *# Write attention to PowerLink, stat = number of byteswritten, not really an error return.
> * * * * * * ack1 = ser.read(2) * * * * * * * * * * * * * # Check to see if PowerLink is ready
> * * * * * * if ack1 == '\x06\r': * * * * * * * * * * * * # It returns ACK<CR> (\x06\r) if it is
> * * * * * * * * stat2 = ser.write(cmd_string)
> * * * * * * * * ack2 = ser.read(19)
> * * * * * * * * if command == 'ON' and ack2 == 'XN\\1\rXNE1\rXNE1\r' : status = 0
> * * * * * * * * if command == 'OFF' and ack2 == 'XN\\1\rXNG1\rXNG1\r': status = 0
> * * * * * * * * if command == 'ON' and ack2 != 'XN\\1\rXNE1\rXNE1\r' : status = 1
> * * * * * * * * if command == 'OFF' and ack2 != 'XN\\1\rXNG1\rXNG1\r': status = 1
> * * * * * * elif ack1 =='\x15': * * * * * * * * * * * * * # PowerLink sends NAC (hex 15) if it isn't.
> * * * * * * * * print('Received NAK from X10 Control, is there too much X10 traffic on the line?\n')
> * * * * * * else: * print("Something's wrong with X10 control. Ack returned was: " + ack1 + "\n")
> * * * * * * stat3 = ser.close() * * * * * * ** * * * * *# Close serial port
> * * * * * * return(status)
>
> ---------
> some irrelevant stuff was here, snipped
> ---------
> * * elif controller_model == 'TI103':
> * * * * if relay_model == 'UM506' or relay_model == 'UM7206':
> * * * * * * letr = relay_address[0]
> * * * * * * numb = relay_address[1]
> * * * * * * if int(relay_address[1]) <= 9: * numb = '0'+numb
>
> # * * * * * stat1 = ser.write('$>28001B02B02 BONBONCC#') # Tell TI103 to send "On" to device B2
>
> * * * * * * ser = serial.Serial(port, 9600, timeout=0.1) * # Set up handle to serial port
>
> * * * * * * cmd_string = '$>28001'+letr+numb+letr+numb+' '+letr+command+letr+command
> * * * * * * ck_sum = checksum256(cmd_string)
> * * * * * * cmd_string = cmd_string+ck_sum+'#'
>
> * * * * * * stat2 = ser.write(cmd_string)
> * * * * * * ack2 = ser.read(10)
> * * * * * * if ack2 != '$<2800!4B#': print('Problem writingcommand string, controller ACK =', ack2) *# $<2800!4B# == success
>
> * * * * * * stat3 = ser.close() * * * * * * ** * * * * * # Close serial port
> #
> #------ * * Now, check status of UM506 to be sure it took the command--------
> #
> * * * * * * ser = serial.Serial(port, 9600, timeout = 0.1)
> * * * * * * for i in range(0,3):
> * * * * * * * * cmd = 'SRQ' * * * * * * ** * * * * * * # Status request command
> * * * * * * * * cmd_string = '$>28001'+letr+numb+letr+numb+' '+letr+cmd+letr+cmd
> * * * * * * * * ck_sum = checksum256(cmd_string)
> * * * * * * * * cmd_string = cmd_string+ck_sum+'#'
> * * * * * * * * stat2 = ser.write(cmd_string)
> * * * * * * * * ack2 = ser.read(10)
> * * * * * * * * if ack2 != '$<2800!4B#': print('Problemwriting command string, controller ACK =', ack2, 'Trying ', i, 'times.')*# $<2800!4B# == success
> * * * * * * * * if ack2 == '$<2800!4B#': break
>
> * * * * * * cmd_string = '$>2800008C#' * * * * * * * * *# Relay response is in the TI123's buffer, this command willread it back
> * * * * * * stat2 = ser.write(cmd_string)
> * * * * * * ack2 = ser.read(150)
> * * * * * * stat3 = ser.close()
> * * * * * * temp = ack2.strip().split(' ')
> * * * * * * loc = str(temp).find(command)
> * * * * * * if loc >= 0: stat3 = True
> * * * * * * return(stat3)
>
> * * * * elif relay_model =='RF124':
> * * * * * * letr = relay_address[0]
> * * * * * * numb = relay_address[1]
> * * * * * * if int(relay_address[1]) <= 9: * numb = '0'+numb
>
> * * * * * * ser = serial.Serial(port, 9600, timeout=0.1) *# Again, set up serial port
>
> * * * * * * for i in range(0,3):
> * * * * * * * * cmd_string = '$>28001'+letr+numb+letr+numb+' '+letr+command+letr+command
> * * * * * * * * ck_sum = checksum256(cmd_string)
> * * * * * * * * cmd_string = cmd_string+ck_sum+'#'
> * * * * * * * * stat2 = ser.write(cmd_string)
> * * * * * * * * ack2 = ser.read(10)
> * * * * * * * * if ack2 == '$<2800!4B#': break
> * * * * * * * * if ack2 != '$<2800!4B#': print('Problemwriting command string, controller ACK =', ack2, 'Trying ', i, 'times.')*# $<2800!4B# == success
> * * * * * * * * if ack2 != '$<2800!4B#': log_write(log_file, 'Problem writing command string, controller ACK =', ack2, 'Trying ', i, 'times.')
>
> * * * * * * stat3 = ser.close() * * * * * * ** * * * * # Close serial port
> #
> # * * * * * Now, check status of RF124 to be sure it took the command
> #
> * * * * * * ser = serial.Serial(port, 9600, timeout = 0.1)
> * * * * * * for i in range(0,3):
> * * * * * * * * cmd = 'SRQ' * * * * * * ** * * * * * * # Status request command
> * * * * * * * * cmd_string = '$>28001'+letr+numb+letr+numb+' '+letr+cmd+letr+cmd
> * * * * * * * * ck_sum = checksum256(cmd_string)
> * * * * * * * * cmd_string = cmd_string+ck_sum+'#'
> * * * * * * * * stat2 = ser.write(cmd_string)
> * * * * * * * * ack2 = ser.read(10)
> * * * * * * * * if ack2 == '$<2800!4B#': break
> * * * * * * * * if ack2 != '$<2800!4B#': print('Problemwriting command string, controller ACK =', ack2, 'Trying ', i, 'times.')*# $<2800!4B# == success
> * * * * * * * * if ack2 != '$<2800!4B#': log_write(log_file, 'Problem writing command string, controller ACK =', ack2, 'Trying ', i, 'times.')
>
> * * * * * * cmd_string = '$>2800008C#' * * * * * * * * *# Relay response is in the TI123's buffer, this command willread it back
> * * * * * * stat2 = ser.write(cmd_string)
> * * * * * * ack2 = ser.read(150)
> * * * * * * stat3 = ser.close()
> * * * * * * temp = ack2.strip().split(' ')
> * * * * * * loc = str(temp).find(command)
> * * * * * * if loc >= 0: stat3 = True
> * * * * * * if loc == -1: stat3 = ack2
> * * * * * * return(stat3)


It seems there is some misunderstanding here. What I meant with how
to "do the equivalent in Python" refered to "reading characters
rather than lines".
I have written working code myself for another Keithleu which does use
RS232 for communication. The problem now is specifically for the new
Keithley which doesn't allow RS232 but only USB-communication over
usbtmc. So if the "buffer-problem" could be changed by reading
characters that would be great.

regards,
Jean



Jean Dubois 12-06-2012 02:05 PM

Re: problem with usbtmc-communication
 
On 4 dec, 20:55, Terry Reedy <tjre...@udel.edu> wrote:
> On 12/4/2012 7:14 AM, Jean Dubois wrote:
>
>
>
>
>
>
>
>
>
> > The following test program which tries to communicate with a Keithley
> > 2200 programmable power supply usingusbtmcin Python does not work as
> > expected. I have connected a 10 ohm resistor to its terminals and I
> > apply 0.025A, 0.050A, 0.075A en 0.1A,
> > I then measure the current and the voltage en write them in a file
> > De data produced looks like this:
> > 0.00544643 0.254061; first current value is wrong, voltage value is
> > correct
> > 0.0250807 0.509289; second current value is wrong, but it corresponds
> > to the first, second voltage is correct
> > 0.0501099 0.763945; 3rd current value is wrong, but it corresponds to
> > the second, 3rd voltage is right
> > 0.075099 1.01792; 4th current value is wrong, *it corresponds to the
> > 3rd, 4th voltage is right
> > * * * * * * * * * * * * * * *4th correct current value is missing

>
> > But is should be (numerical inaccuracy taking into account) *(these data
> > were produced by a similar octave-program):
> > 0.0248947 0.254047
> > 0.0499105 0.509258
> > 0.0749044 0.764001
> > 0.0998926 1.01828

>
> > Here is the python-program:
> > #!/usr/bin/python
> > import time
> > import os
> > import sys
> > measurementcurr=''
> > measurementvolt=''
> > timesleepdefault=1
> > filename ='mydata.txt'
> > usbkeith = open('/dev/usbtmc1','r+')
> > usbkeith.flush()
> > usbkeith.write("*IDN?\n")
> > #strip blank line:
> > identification=usbkeith.readline().strip()
> > print 'Found device: ',identification
> > usbkeith.write("SYST:REM" + "\n")
> > usbkeith.write(":SENS:VOLT:PROT 1.5\n")
> > keithdata = open(filename,'w')
> > #start first measurement
> > usbkeith.write(":SOUR:CURR 0.025\n")
> > usbkeith.write(":OUTP:STAT ON\n")
> > time.sleep(timesleepdefault)
> > usbkeith.write(":MEAS:CURR?\n")
> > time.sleep(timesleepdefault)
> > measurementcurr=usbkeith.readline()
> > print 'Measured current 1: ',measurementcurr
> > usbkeith.write("MEAS:VOLT?\n")
> > time.sleep(timesleepdefault)
> > measurementvolt=usbkeith.readline()
> > print 'Measured voltage 1: ',measurementvolt
> > keithdata.write(measurementcurr.strip()+' '+measurementvolt)

>
> [3 near repetitions snipped]
>
> This sort of repetitious code without even line breaks is painful for me
> to read. Python has looping statements for a reason. Replace all four
> nearly identical blocks with the following. (If you are not familiar
> with built-in enumerate, you should be. Read its entry in the library
> manual.)
>
> for number, current_in in enumerate(
> * * *('0.025', '0.050'. '0.075', '0.100'), 1)
> * *usbkeith.write(":SOUR:CURR %s\n" % current_in)
> * *...
> * *print 'Measured current %d: ' % number, measurementcurr
> * *...
> * *print 'Measured voltage %d: ' % number, measurementvolt
>
> Now you can make changes in only one place and easily add more test values.
>
> > print "Goodbye, data logged in file:"
> > print filename
> > usbkeith.close()
> > keithdata.close()

>
> > can anyone here what is going wrong and how to get it right?

>
> No, but if both the python and octave programs used loops, it would be
> easier to see if both are doing the same things before, within, and
> after the loop.
>
> --
> Terry Jan Reedy


Thank you for you reply. Of course you are right this kind of code is
not the normal way to program but as I mentioned in my initial post
this is merely a test program, I did avoid using a loop on purpose
because timing can be critical in this kind of application and I
didn't want to add unnecessary uncertainty in the timing which could
be caused by using a loop.
The final version will be more like you suggested here above.
As Bill stated in another e-mail the real trouble here is some kind of
"buffer-problem", according to him it could be caused by the use of
the readline()-statements. So if anyone could tell me how to
substitute those by some Python commands which read characters instead
does the Octave-code I'd appreciate that very much.

regards,
Jean

Jean Dubois 12-06-2012 03:44 PM

Re: problem with usbtmc-communication
 
On 4 dec, 20:55, Terry Reedy <tjre...@udel.edu> wrote:
> On 12/4/2012 7:14 AM, Jean Dubois wrote:
>
>
>
>
>
>
>
>
>
> > The following test program which tries to communicate with a Keithley
> > 2200 programmable power supply using usbtmc in Python does not work as
> > expected. I have connected a 10 ohm resistor to its terminals and I
> > apply 0.025A, 0.050A, 0.075A en 0.1A,
> > I then measure the current and the voltage en write them in a file
> > De data produced looks like this:
> > 0.00544643 0.254061; first current value is wrong, voltage value is
> > correct
> > 0.0250807 0.509289; second current value is wrong, but it corresponds
> > to the first, second voltage is correct
> > 0.0501099 0.763945; 3rd current value is wrong, but it corresponds to
> > the second, 3rd voltage is right
> > 0.075099 1.01792; 4th current value is wrong, *it corresponds to the
> > 3rd, 4th voltage is right
> > * * * * * * * * * * * * * * *4th correct current value is missing

>
> > But is should be (numerical inaccuracy taking into account) *(these data
> > were produced by a similar octave-program):
> > 0.0248947 0.254047
> > 0.0499105 0.509258
> > 0.0749044 0.764001
> > 0.0998926 1.01828

>
> > Here is the python-program:
> > #!/usr/bin/python
> > import time
> > import os
> > import sys
> > measurementcurr=''
> > measurementvolt=''
> > timesleepdefault=1
> > filename ='mydata.txt'
> > usbkeith = open('/dev/usbtmc1','r+')
> > usbkeith.flush()
> > usbkeith.write("*IDN?\n")
> > #strip blank line:
> > identification=usbkeith.readline().strip()
> > print 'Found device: ',identification
> > usbkeith.write("SYST:REM" + "\n")
> > usbkeith.write(":SENS:VOLT:PROT 1.5\n")
> > keithdata = open(filename,'w')
> > #start first measurement
> > usbkeith.write(":SOUR:CURR 0.025\n")
> > usbkeith.write(":OUTP:STAT ON\n")
> > time.sleep(timesleepdefault)
> > usbkeith.write(":MEAS:CURR?\n")
> > time.sleep(timesleepdefault)
> > measurementcurr=usbkeith.readline()
> > print 'Measured current 1: ',measurementcurr
> > usbkeith.write("MEAS:VOLT?\n")
> > time.sleep(timesleepdefault)
> > measurementvolt=usbkeith.readline()
> > print 'Measured voltage 1: ',measurementvolt
> > keithdata.write(measurementcurr.strip()+' '+measurementvolt)

>
> [3 near repetitions snipped]
>
> This sort of repetitious code without even line breaks is painful for me
> to read. Python has looping statements for a reason. Replace all four
> nearly identical blocks with the following. (If you are not familiar
> with built-in enumerate, you should be. Read its entry in the library
> manual.)
>
> for number, current_in in enumerate(
> * * *('0.025', '0.050'. '0.075', '0.100'), 1)
> * *usbkeith.write(":SOUR:CURR %s\n" % current_in)
> * *...
> * *print 'Measured current %d: ' % number, measurementcurr
> * *...
> * *print 'Measured voltage %d: ' % number, measurementvolt
>
> Now you can make changes in only one place and easily add more test values.
>
> > print "Goodbye, data logged in file:"
> > print filename
> > usbkeith.close()
> > keithdata.close()

>
> > can anyone here what is going wrong and how to get it right?

>
> No, but if both the python and octave programs used loops, it would be
> easier to see if both are doing the same things before, within, and
> after the loop.
>
> --
> Terry Jan Reedy

I followed your suggestion an now the code looks like this:
#!/usr/bin/python
import time
import os
import sys
measurementcurr=''
measurementvolt=''
timesleepdefault=2
filename ='mydata.txt'
usbkeith = open('/dev/usbtmc1','r+')
usbkeith.flush()
usbkeith.write("*IDN?\n")
#strip blank line:
identification=usbkeith.readline().strip()
print 'Found device: ',identification
usbkeith.write("SYST:REM" + "\n")
usbkeith.write(":SENS:VOLT:PROT 1.5\n")
keithdata = open(filename,'w')
usbkeith.write(":OUTP:STAT ON\n")
for number, current_in in enumerate(('0.025', '0.050', '0.075',
'0.100'), 1):
usbkeith.write(":SOUR:CURR %s\n" % current_in)
time.sleep(timesleepdefault)
usbkeith.write(":MEAS:CURR?\n")
measurementcurr=usbkeith.readline()
print 'Measured current %d: ' % number, measurementcurr
usbkeith.write(":MEAS:VOLT?\n")
measurementvolt=usbkeith.readline()
print 'Measured voltage %d: ' % number, measurementvolt
keithdata.write(measurementcurr.strip()+' '+measurementvolt)
usbkeith.write(":OUTP:STAT OFF\n")
print "Goodbye, data logged in file:"
print filename
usbkeith.close()
keithdata.close()

Still there is a "buffer-problem" as you can see in the output below:
0.00639725 0.0104065; these values are completely wrong
0.0248976 0.262959; these should have been be the first values
0.0500431 0.516602: these should been the second values
0.0749168 0.772616; these are the 3rd values
4th values are missing

any idea why this does what it does in Python?

jean

Jean Dubois 12-06-2012 07:41 PM

Re: problem with usbtmc-communication
 
On 6 dec, 15:50, w...@mac.com wrote:
> On Dec 6, 2012, at 8:50 AM, Jean Dubois <jeandubois...@gmail.com> wrote:
>
> [byte]
>
>
>
>
>
>
>
>
>
>
>
> > It seems there is some misunderstanding here. What I meant with *how
> > to "do the equivalent in Python" refered to *"reading characters
> > rather than lines".
> > I have written working code myself for another Keithleu which does use
> > RS232 for communication. The problem now is specifically for the new
> > Keithley which doesn't allow RS232 but only USB-communication over
> > usbtmc. So if the "buffer-problem" could be changed by reading
> > characters that would be great.

>
> > regards,
> > Jean

>
> > --
> >http://mail.python.org/mailman/listinfo/python-list

>
> Sorry about the misunderstanding (and subsequent waste of bandwidth). *However, if you will look at the serial reads and writes in that handler, you will see that it does things like "serial.read(n)" where "n" is an explicit number, the number of bytes to be read from the serial buffer.
>
> -Bill

I tried changing measurementcurr=usbkeith.readline() to
measurementcurr=usbkeith.read(10000)
but this leads to trouble with the usbtmc-thing:

Measured current 1:
Traceback (most recent call last):
File "./keith2200rev2.py", line 26, in <module>
measurementvolt=usbkeith.read(10000)
IOError: [Errno 110] Connection timed out

and hereafter I need to restart the Keithley...:-(

regards,
Jean

Dave Angel 12-06-2012 08:10 PM

Re: problem with usbtmc-communication
 
On 12/06/2012 02:41 PM, Jean Dubois wrote:
> On 6 dec, 15:50, w...@mac.com wrote:
>> <snip>
>> Sorry about the misunderstanding (and subsequent waste of bandwidth). However, if you will look at the serial reads and writes in that handler, you will see that it does things like "serial.read(n)" where "n" is an explicit number, the number of bytes to be read from the serial buffer.
>>
>> -Bill

> I tried changing measurementcurr=usbkeith.readline() to
> measurementcurr=usbkeith.read(10000)
> but this leads to trouble with the usbtmc-thing:
>
> Measured current 1:
> Traceback (most recent call last):
> File "./keith2200rev2.py", line 26, in <module>
> measurementvolt=usbkeith.read(10000)
> IOError: [Errno 110] Connection timed out
>
> and hereafter I need to restart the Keithley...:-(

I can't see why you used a count of 10000. Isn't the whole problem
supposed to be because it doesn't produce a whole line at a time? So
after requesting a measurement, if you know the size, use that in the
read() method. And if you don't know the size, read it one byte at a
time till it make sense.

--

DaveA



All times are GMT. The time now is 09:43 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.