[newbie] problem with usbtmc-communication

Discussion in 'Python' started by Jean Dubois, Dec 4, 2012.

  1. Jean Dubois

    Jean Dubois Guest

    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, Dec 4, 2012
    #1
    1. Advertising

  2. Jean Dubois

    Jean Dubois Guest

    Re: problem with usbtmc-communication

    On 4 dec, 15:33, wrote:
    > On Dec 4, 2012, at 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)
    > > #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)
    Jean Dubois, Dec 4, 2012
    #2
    1. Advertising

  3. Jean Dubois

    Terry Reedy Guest

    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
    Terry Reedy, Dec 4, 2012
    #3
  4. Jean Dubois

    Jean Dubois Guest

    Re: problem with usbtmc-communication

    On 5 dec, 16:26, wrote:
    > On Dec 4, 2012, at 11:12 AM, Jean Dubois <> wrote:
    >
    > > On 4 dec, 15:33, wrote:
    > >> On Dec 4, 2012, at 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

    >
    > 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
    Jean Dubois, Dec 5, 2012
    #4
  5. Re: problem with usbtmc-communication

    On Wed, 5 Dec 2012 12:38:04 -0800 (PST), Jean Dubois
    <> 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/websearch/21992F3750B967ED86256F47007B00B3

    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
    HTTP://wlfraed.home.netcom.com/
    Dennis Lee Bieber, Dec 5, 2012
    #5
  6. Jean Dubois

    Jean Dubois Guest

    Re: problem with usbtmc-communication

    On 5 dec, 23:21, wrote:
    > On Dec 5, 2012, at 3:38 PM, Jean Dubois <> 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, Dec 6, 2012
    #6
  7. Jean Dubois

    Jean Dubois Guest

    Re: problem with usbtmc-communication

    On 4 dec, 20:55, Terry Reedy <> 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, Dec 6, 2012
    #7
  8. Jean Dubois

    Jean Dubois Guest

    Re: problem with usbtmc-communication

    On 4 dec, 20:55, Terry Reedy <> 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, Dec 6, 2012
    #8
  9. Jean Dubois

    Jean Dubois Guest

    Re: problem with usbtmc-communication

    On 6 dec, 15:50, wrote:
    > On Dec 6, 2012, at 8:50 AM, Jean Dubois <> 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
    Jean Dubois, Dec 6, 2012
    #9
  10. Jean Dubois

    Dave Angel Guest

    Re: problem with usbtmc-communication

    On 12/06/2012 02:41 PM, Jean Dubois wrote:
    > On 6 dec, 15:50, 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
    Dave Angel, Dec 6, 2012
    #10
  11. Jean Dubois

    Terry Reedy Guest

    Re: problem with usbtmc-communication

    On 12/6/2012 10:44 AM, Jean Dubois wrote:

    > 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?


    I am not familiar with the protocol at all, but my guess (without
    looking at the octave code) is that two of these three commands

    > usbkeith.write("SYST:REM" + "\n")
    > usbkeith.write(":SENS:VOLT:pROT 1.5\n")
    > usbkeith.write(":OUTP:STAT ON\n")


    before the loop have responses that you need to read (and toss?)

    usbkeith.readline(); usbkeith.readline()

    so that the first values you read in the loop are the one that should be
    first. In other words, make sure the read buffer is clear before the loop.

    --
    Terry Jan Reedy
    Terry Reedy, Dec 6, 2012
    #11
  12. Jean Dubois

    Jean Dubois Guest

    Re: problem with usbtmc-communication

    On 6 dec, 21:15, wrote:
    > On Dec 6, 2012, at 2:41 PM, Jean Dubois <> wrote:
    >
    >
    >
    >
    >
    >
    >
    >
    >
    > > On 6 dec, 15:50, wrote:
    > >> On Dec 6, 2012, at 8:50 AM, Jean Dubois <> 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
    > > --
    > >http://mail.python.org/mailman/listinfo/python-list

    >
    > Several comments:
    >
    > 1)  I can't be sure, but that would seem to be asking the Keithley to be providing 10,000 readings.  I don't know about the GPIB bus (which thisUSBTMC library seems to be trying >to emulate), but most serial devices expect to provide one answer per read-write handshake.  That is, you send one read command and get one answer back.  That answer may contain >several bytes, but I'd be surprised it it contained 10,000.  The typical cycle is something like send-an-initialize, read-status, send-mode-set-up, read-status, send trigger >command, read-answer…  lather and repeat.   (Or some logical equivalent of all that).  On the assumption that the USBTMC API handles most of that, I'd try usbkeith.read(n) where >"n" is the numberof decimal digits you expect to get back plus sign.

    10000 wasn't a good guess indeed
    > -------------
    >
    > 2) I took a quick look at the Keithley and National Instruments web sites(where the documentation is at best, VERY poorly indexed and hard to search for).  USBTMC *appears* to be a software layer designed to allow newer Tektronix and Keithley instruments to be driven using older software that drove GPIB equipment.  To make matters worse, if I'm reading it right (I didn't study in detail) it appears to ALSO be providing a GPIB-like API to Windows versions of National Instruments LabView.
    >
    > 3)  If I understand what you are trying to do, you want to go straight from python to the Keithley USB port, without detouring (USB-to-GPIB and GPIB back to USB).
    >

    Yes indeed, that's exactly what I want

    > 4)  I did find (but did not try to read in detail) the following link:  http://www.ni.com/white-paper/4478/en which documents direct USB control of instruments.  The python serial >library provides quite transparentcontrol of reading and writing to the USB interface.  Maybe following this link will get you going.

    Thanks for the link, but as you can see there they want to push NI-
    VISA forward as the solution, which under Linux means more complexity
    and surely isn't as simple to install as they claim, so if possible
    I'd avoid ni-visa.

    I'll experiment further Monday with read() and keep you informed

    regards,
    Jean
    Jean Dubois, Dec 7, 2012
    #12
  13. Jean Dubois

    Jean Dubois Guest

    Re: problem with usbtmc-communication

    On 6 dec, 21:28, Terry Reedy <> wrote:
    > On 12/6/2012 10:44 AM, Jean Dubois wrote:
    >
    >
    >
    >
    >
    >
    >
    >
    >
    > > 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?

    >
    > I am not familiar with the protocol at all, but my guess (without
    > looking at the octave code) is that two of these three commands
    >
    >  > usbkeith.write("SYST:REM" + "\n")
    >  > usbkeith.write(":SENS:VOLT:pROT 1.5\n")
    >  > usbkeith.write(":OUTP:STAT ON\n")
    >
    > before the loop have responses that you need to read (and toss?)

    No they don't need to have there responses be red,
    first command sets remote mode
    second command sets limit on voltage across output terminals
    3rd command connects terminals with DUT


    > usbkeith.readline(); usbkeith.readline()

    This doesn't work because nothing is sent back
    > so that the first values you read in the loop are the one that should be
    > first. In other words, make sure the read buffer is clear before the loop..
    >
    > --
    > Terry Jan Reedy


    I'll look at it further monday

    regards,
    jean
    Jean Dubois, Dec 7, 2012
    #13
  14. Jean Dubois

    Jean Dubois Guest

    Re: problem with usbtmc-communication

    On 7 dec, 14:46, Jean Dubois <> wrote:
    > On 6 dec, 21:15, wrote:
    >
    > > On Dec 6, 2012, at 2:41 PM, Jean Dubois <> wrote:

    >
    > > > On 6 dec, 15:50, wrote:
    > > >> On Dec 6, 2012, at 8:50 AM, Jean Dubois <> 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 theusbtmc-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
    > > > --
    > > >http://mail.python.org/mailman/listinfo/python-list

    >
    > > Several comments:

    >
    > > 1)  I can't be sure, but that would seem to be asking the Keithley tobe providing 10,000 readings.  I don't know about the GPIB bus (which thisUSBTMClibrary seems to be trying >to emulate), but most serial devices expect to provide one answer per read-write handshake.  That is, you send one read command and get one answer back.  That answer may contain >several bytes, but I'd be surprised it it contained 10,000.  The typical cycle is something like send-an-initialize, read-status, send-mode-set-up, read-status, send trigger >command, read-answer…  lather and repeat.   (Or some logical equivalent of all that).  On the assumption that theUSBTMCAPI handles most of that, I'd try usbkeith.read(n) where >"n" is the number of decimal digits you expect to get back plus sign.

    >
    > 10000 wasn't a good guess indeed> -------------
    >
    > > 2) I took a quick look at the Keithley and National Instruments web sites (where the documentation is at best, VERY poorly indexed and hard to search for).  USBTMC*appears* to be a software layer designed to allow newerTektronix and Keithley instruments to be driven using older software that drove GPIB equipment.  To make matters worse, if I'm reading it right (I didn't study in detail) it appears to ALSO be providing a GPIB-like API to Windows versions of National Instruments LabView.

    >
    > > 3)  If I understand what you are trying to do, you want to go straight from python to the Keithley USB port, without detouring (USB-to-GPIB and GPIB back to USB).

    >
    > Yes indeed, that's exactly what I want
    >
    > > 4)  I did find (but did not try to read in detail) the following link:  http://www.ni.com/white-paper/4478/en which documents direct USB control of instruments.  The python serial >library provides quite transparent control of reading and writing to the USB interface.  Maybe following this link will get you going.

    >
    > Thanks for the link, but as you can see there they want to push NI-
    > VISA forward as the solution, which under Linux means more complexity
    > and surely isn't as simple to install as they claim, so if possible
    > I'd avoid ni-visa.
    >
    > I'll experiment further Monday with read() and keep you informed
    >
    > regards,
    > Jean

    I changed the program as below an experimentally found out I have to
    use an number of characters between 11 and 4095
    I doesn't seem to make any difference which value I choose in that
    interval, however the results are as follows:
    0.0077219 0.0295029; this is rubbish
    0.0249596 0.261837; this should have been the first data pair
    0.0499763 0.516741; this should have been the 2nd data pair
    0.0750685 0.767388; this should have been the 3rd data pair
    4th data pair is missing

    As you can see this approach suffers from the same "buffer problem" as
    the approach with readline did. One now good argue as a workaround:
    get rid of the first data pair and add an extra measure command for
    the missing data pair, however this still does not explain why this
    problem is there in Python and not in Octave and I also fear I'll get
    more trouble when sending combined commands e.g. such as that to
    create a staircase current
    So my question is, how to modify the Python-code such that the first
    data pair is indeed the first data pair

    thanks,
    jean

    Here follows the new code:
    #!/usr/bin/python
    import time
    import os
    import sys
    measurementcurr=''
    measurementvolt=''
    timesleepdefault=5
    print "Enter a numofchar (11 =<numchar =<4095):",
    numofchar = int(raw_input())
    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.read(numofchar)
    print 'Measured current %d: ' % number, measurementcurr
    usbkeith.write(":MEAS:VOLT?\n")
    measurementvolt=usbkeith.read(numofchar)
    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()
    Jean Dubois, Dec 10, 2012
    #14
  15. Jean Dubois

    Jean Dubois Guest

    Re: problem with usbtmc-communication

    On 10 dec, 16:34, wrote:
    > On Dec 10, 2012, at 8:31 AM, Jean Dubois <> wrote:
    >
    > [byte]
    >
    >
    >
    >
    >
    >
    >
    >
    >
    > > As you can see this approach suffers from the same "buffer problem" as
    > > the approach with readline did. One now good argue as a workaround:
    > > get rid of the first data pair and add an extra measure command for
    > > the missing data pair, however this still does not explain why this
    > > problem is there in Python and not in Octave and I also fear I'll get
    > > more trouble when sending combined commands e.g. such as that to
    > > create a staircase current
    > > So my question is, how to modify the Python-code such that the first
    > > data pair is indeed the first data pair

    >
    > > thanks,
    > > jean

    >
    > > Here follows the new code:
    > > #!/usr/bin/python
    > > import time
    > > import os
    > > import sys
    > > measurementcurr=''
    > > measurementvolt=''
    > > timesleepdefault=5
    > > print "Enter a numofchar (11 =<numchar =<4095):",
    > > numofchar = int(raw_input())
    > > filename ='mydata.txt'
    > > usbkeith = open('/dev/usbtmc1','r+')
    > > usbkeith.flush()
    > > usbkeith.write("*IDN?\n")

    >
    > It seems like a real leap of faith to be opening /dev/usbtmc1 as though it were a file-oriented device.  I've never heard of ANY instrument interface implemented this way.
    > Where did you see example code that did that.

    I found examples in the usbtmc kernel driver documentation (the
    examples there are given in C):
    http://www.home.agilent.com/upload/cmc_upload/All/usbtmc.htm?&cc=BE&lc=dut


    >  Have you tried to access /dev/usbtmc1 as though it were a serial device?

    Yes, I did, as I used to do when communicating with rs232 devices. I
    first tried to communicate to with the Keithley using cutecom but I
    soon discovered you can't work that way because as soon as you open
    the device it closes immediately thereafter. You really have to use
    usbtmc (unfortunately) I'm missing the correct "flushing commands" to
    do it correctly in Python...Maybe I should try to call the octave code
    from within Python?


    thanks
    jean
    >
    >
    >
    >
    >
    >
    >
    > > #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.read(numofchar)
    > >   print 'Measured current %d: ' % number, measurementcurr
    > >   usbkeith.write(":MEAS:VOLT?\n")
    > >   measurementvolt=usbkeith.read(numofchar)
    > >   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()
    > > --
    > >http://mail.python.org/mailman/listinfo/python-list
    Jean Dubois, Dec 11, 2012
    #15
  16. Jean Dubois

    Jean Dubois Guest

    Re: problem with usbtmc-communication

    On 11 dec, 15:34, wrote:
    > On Dec 11, 2012, at 1:58 AM, Jean Dubois <> wrote:
    >
    >
    >
    >
    >
    >
    >
    >
    >
    > > On 10 dec, 16:34, wrote:
    > >> On Dec 10, 2012, at 8:31 AM, Jean Dubois <> wrote:

    >
    > >> [byte]
    > >>> As you can see this approach suffers from the same "buffer problem" as
    > >>> the approach with readline did. One now good argue as a workaround:
    > >>> get rid of the first data pair and add an extra measure command for
    > >>> the missing data pair, however this still does not explain why this
    > >>> problem is there in Python and not in Octave and I also fear I'll get
    > >>> more trouble when sending combined commands e.g. such as that to
    > >>> create a staircase current
    > >>> So my question is, how to modify the Python-code such that the first
    > >>> data pair is indeed the first data pair

    >
    > >>> thanks,
    > >>> jean

    >
    > >>> Here follows the new code:
    > >>> #!/usr/bin/python
    > >>> import time
    > >>> import os
    > >>> import sys
    > >>> measurementcurr=''
    > >>> measurementvolt=''
    > >>> timesleepdefault=5
    > >>> print "Enter a numofchar (11 =<numchar =<4095):",
    > >>> numofchar = int(raw_input())
    > >>> filename ='mydata.txt'
    > >>> usbkeith = open('/dev/usbtmc1','r+')
    > >>> usbkeith.flush()
    > >>> usbkeith.write("*IDN?\n")

    >
    > >> It seems like a real leap of faith to be opening /dev/usbtmc1 as though it were a file-oriented device.  I've never heard of ANY instrument interface implemented this way.
    > >> Where did you see example code that did that.

    > > I found examples in theusbtmckernel driver documentation (the
    > > examples there are given in C):
    > >http://www.home.agilent.com/upload/cmc_upload/All/usbtmc.htm?&cc=BE&l....

    >
    > OK - I see where the examples came from, and I notice -
    >
    >         int my_inst;
    >         my_inst=open(“/dev/usbtmc1”,O_RDWR);
    >         write(my_inst,”*RST\n”,5);
    >         close(my_inst);
    >
    > and similarly in another place -
    >
    >         retval=write(myfile,"*IDN?\n",6);
    >
    > Note that both write commands contain a byte count of the number of characters to be written (\n counts as one character).
    > Again, the read commands contain byte counts.  I'm very suspicious thata write command with no byte count writes nothing, but does move a buffer pointer.
    >
    > -Bill


    Does Python support/implement simular commands? Can I use
    usbkeith.write("*IDN?\n",6) and something simular for the reading
    commands?

    thanks,
    jean
    Jean Dubois, Dec 11, 2012
    #16
  17. Jean Dubois

    Jerry Hill Guest

    Re: problem with usbtmc-communication

    On Tue, Dec 11, 2012 at 1:58 AM, Jean Dubois <> wrote:
    >
    > I found examples in the usbtmc kernel driver documentation (the
    > examples there are given in C):
    > http://www.home.agilent.com/upload/cmc_upload/All/usbtmc.htm?&cc=BE&lc=dut


    Thanks for that link. I think it explains how the driver works pretty
    well. I haven't done any work with devices like this, but I see a few
    things in those docs that might help.

    In their example code, they open the device with: open(“/dev/usbtmc1â€,O_RDWR);

    That's not exactly the same as what you've been doing. I would try
    opening the file this way in python:
    usb_device = open('/dev/usbtmc1', 'w+', buffering=0)

    That truncates the file after it opening it, and disables any
    buffering that might be going on.

    Then, I would try writing to the device with usb_device.write() and
    usb_device.read(). read() attempts to read to end-of-file, and based
    on the docs, the driver will work okay that way. Doing that, along
    with turning off buffering when you open the file, should eliminate
    any issues with the driver failing to emit newlines someplace.

    Personally, I would probably try playing with the device from python's
    interactive interpreter. I think that could shed a lot of light on
    the behavior you're seeing.

    --
    Jerry
    Jerry Hill, Dec 12, 2012
    #17
  18. Jean Dubois

    Guest

    Re: problem with usbtmc-communication

    On Dec 11, 2012, at 3:48 PM, Jean Dubois <> wrote:

    [byte]

    >>
    >> OK - I see where the examples came from, and I notice -
    >>
    >> int my_inst;
    >> my_inst=open(“/dev/usbtmc1”,O_RDWR);
    >> write(my_inst,”*RST\n”,5);
    >> close(my_inst);
    >>
    >> and similarly in another place -
    >>
    >> retval=write(myfile,"*IDN?\n",6);
    >>
    >> Note that both write commands contain a byte count of the number of characters to be written (\n counts as one character).
    >> Again, the read commands contain byte counts. I'm very suspicious that a write command with no byte count writes nothing, but does move a buffer pointer.
    >>
    >> -Bill

    >
    > Does Python support/implement simular commands? Can I use
    > usbkeith.write("*IDN?\n",6) and something simular for the reading
    > commands?
    >
    > thanks,
    > jean
    > --
    > http://mail.python.org/mailman/listinfo/python-list


    Yes of course. BUT, that isn't really a python question, it depends on how the device driver implements the function call.

    -Bill
    , Dec 12, 2012
    #18
  19. Jean Dubois

    Jean Dubois Guest

    Re: problem with usbtmc-communication

    On 12 dec, 01:49, Jerry Hill <> wrote:
    > On Tue, Dec 11, 2012 at 1:58 AM, Jean Dubois <> wrote:
    >
    > > I found examples in theusbtmckernel driver documentation (the
    > > examples there are given in C):
    > >http://www.home.agilent.com/upload/cmc_upload/All/usbtmc.htm?&cc=BE&l....

    >
    > Thanks for that link.  I think it explains how the driver works pretty
    > well.  I haven't done any work with devices like this, but I see a few
    > things in those docs that might help.
    >
    > In their example code, they open the device with: open(“/dev/usbtmc1”,O_RDWR);
    >
    > That's not exactly the same as what you've been doing.  I would try
    > opening the file this way in python:
    > usb_device = open('/dev/usbtmc1', 'w+', buffering=0)
    >
    > That truncates the file after it opening it, and disables any
    > buffering that might be going on.
    >
    > Then, I would try writing to the device with usb_device.write() and
    > usb_device.read().  read() attempts to read to end-of-file, and based
    > on the docs, the driver will work okay that way.  Doing that, along
    > with turning off buffering when you open the file, should eliminate
    > any issues with the driver failing to emit newlines someplace.
    >
    > Personally, I would probably try playing with the device from python's
    > interactive interpreter.  I think that could shed a lot of light on
    > the behavior you're seeing.
    >
    > --
    > Jerry


    Thanks a thousand times Jerry!!!, the buffering issue has disappeared
    after following your recommendations. The test program now looks like
    below and performs as expected.

    #!/usr/bin/python
    import time
    import os
    import sys
    timesleepdefault=5
    print "Enter name of data file",
    filename = raw_input()
    #the following line is very important, especially the buffering=0
    usbkeith = open('/dev/usbtmc1','w+', buffering=0)
    usbkeith.write("*IDN?\n")
    identification=usbkeith.read().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.read()
    print 'Measured current %d: ' % number, measurementcurr
    usbkeith.write(":MEAS:VOLT?\n")
    measurementvolt=usbkeith.read()
    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()

    regards,
    Jean
    Jean Dubois, Dec 12, 2012
    #19
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Dave Bartlett

    newbie question: interprocess communication

    Dave Bartlett, May 13, 2004, in forum: ASP .Net
    Replies:
    1
    Views:
    492
    DalePres
    May 13, 2004
  2. Rune Andresen
    Replies:
    2
    Views:
    1,935
    Phil Powell
    Sep 17, 2003
  3. Michelle
    Replies:
    2
    Views:
    420
    Michelle
    Jul 19, 2004
  4. Replies:
    3
    Views:
    780
  5. Replies:
    6
    Views:
    554
    Dennis Lee Bieber
    Mar 31, 2007
Loading...

Share This Page