problem with usbtmc-communication

Jean Dubois jeandubois314 at gmail.com
Thu Dec 6 08:50:01 EST 2012


On 5 dec, 23:21, w... at mac.com wrote:
> On Dec 5, 2012, at 3:38 PM, Jean Dubois <jeandubois... at 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 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
> > --
> >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 had to worry about a single controller model - single relay model to one where I 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 bytes written, 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 writing command 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('Problem writing 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 will read 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('Problem writing 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('Problem writing 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 will read 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





More information about the Python-list mailing list