RS232 comm issue with B&K Precision Programmable DC Load

Discussion in 'Computing and Networks' started by maverik007, Jul 6, 2009.

  1. maverik007

    Thread Starter Member

    Feb 6, 2009
    25
    0
    Hi everyone,

    I am trying to communicate with the a programmable dc load device through the serial port, using python scripts (Reason for python? The s/w library from the manufacturer is written in python ;))

    The serial port monitor's Request-View dump for the custom software provided by the manufacturer (it has limited functionality) can be seen below...

    Code ( (Unknown Language)):
    1.  
    2.     [COLOR=black][FONT=&quot]Port opened by process "PV8500.exe" (PID: 4736)[/FONT][/COLOR]
    3.      [B][COLOR=black][FONT=&quot]Request: 7/6/2009 9:57:39 AM.50964 (+424.8825 seconds)[/FONT][/COLOR][/B]
    4.      [COLOR=red][FONT=&quot] AA FF 6A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 13                     [/FONT][/COLOR]
    5.      [B][COLOR=black][FONT=&quot]Answer: 7/6/2009 9:57:39 AM.53764 (+0.0280 seconds)[/FONT][/COLOR][/B]
    6.      [COLOR=blue][FONT=&quot] AA 00 6A 38 35 31 33 43 83 01 36 33 37 37 30 30 31 30 38 34 00 00 00 00 00 B0                     [/FONT][/COLOR]
    7.      [B][COLOR=black][FONT=&quot]Request: 7/6/2009 9:57:39 AM.73564 (+0.1680 seconds)[/FONT][/COLOR][/B]
    8.      [COLOR=red][FONT=&quot] AA FF 20 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 CA                     [/FONT][/COLOR]
    9.      [B][COLOR=black][FONT=&quot]Answer: 7/6/2009 9:57:39 AM.76764 (+0.0320 seconds)[/FONT][/COLOR][/B]
    10.      [COLOR=blue][FONT=&quot] AA 00 12 80 35 31 33 43 83 01 36 33 37 37 30 30 31 30 38 34 00 00 00 00 00 A0                     [/FONT][/COLOR]
    11.      [B][COLOR=black][FONT=&quot]Request: 7/6/2009 9:57:39 AM.82264 (+0.0350 seconds)[/FONT][/COLOR][/B]
    12.      [COLOR=red][FONT=&quot] AA FF 22 C0 D4 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 60                     [/FONT][/COLOR]
    13.      [B][COLOR=black][FONT=&quot]Answer: 7/6/2009 9:57:39 AM.87764 (+0.0550 seconds)[/FONT][/COLOR][/B]
    14.      [COLOR=blue][FONT=&quot] AA 00 12 80 35 31 33 43 83 01 36 33 37 37 30 30 31 30 38 34 00 00 00 00 00 A0                     [/FONT][/COLOR]
    15.  
    16.  
    As we can see here, the frames that are sent, get a complementary response frame from the dc load device.

    However, for some unknown reason, i can't get my python scripts to extract a response from the darn thing! :confused:

    The serial port monitor dump for my code can be seen below,

    Code ( (Unknown Language)):
    1.  
    2.    [COLOR=black][FONT=&quot]Port opened by process "python.exe" (PID: 5236)[/FONT][/COLOR]
    3.      [B][COLOR=black][FONT=&quot]Request: 7/6/2009 9:50:34 AM.12464 (+51.3691 seconds)[/FONT][/COLOR][/B]
    4.    [COLOR=red][FONT=&quot] AA FF 6A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 13                     [/FONT][/COLOR]
    5.  
    This thing just gets stuck after sending the first command itself...NO RESPONSE at all after that! :mad: I've checked the baud rate settings, and other basic configuration information for the serial comm (8-bits, no parity, 1 stop bit) for both sides...the settings are the same. Still nothing :(

    Could you guys suggest some troubleshooting methods?

    NOTE: The device's manual is attached to this post. Jump to page-45 for RS232 related details.

    Thanks for having a look :) Comments/suggestions would be greatly appreciated!!!

    Regards,
    mav
     
  2. someonesdad

    Senior Member

    Jul 7, 2009
    1,585
    141
    Hi, maverik007:

    I've used the 8500 DC load a bit, so I might be able to help. I need more information though.

    Your first RS-232 dump: is that a dump of a working connection with the DC load? If yes, then it indicates that you are able to communicate with the load. If no, then where did it come from?

    The TTL-to-RS232 translator has two very helpful LEDs on it. If you're using one, one LED flashes when a message is sent to the DC load and the other LED flashes when the DC load responds. (There's a USB to TTL translator too, but I haven't used it and don't know if it has the LEDs.)

    It has been a year or more since I messed with the DC load, but if I recall correctly, I had similar problems when I didn't have the USB to RS232 adapter configured correctly (I used the wrong RS232 number, IIRC). This led to the same symptoms you've described. However, if your first trace came from communication with the actual load, this isn't the problem.

    You don't post any of the code you've used, so it's difficult to provide any advice about the software.

    I'd divide the system up into the following subsystems:

    1. USB/RS232 hardware and drivers
    2. Python/COM, libraries, and drivers
    3. RS-232 communication cable
    4. DC load
    5. Your python script

    The basic questions to ask are "How do I know this subsystem is working?" or "How do I know this subsystem isn't working?".

    If your second RS232 trace came from talking to a DC load via your computer, then it's almost guaranteed that the problem is in your python script. Otherwise, more work is needed to check each subsystem.
     
  3. maverik007

    Thread Starter Member

    Feb 6, 2009
    25
    0
    Hey someonesdad,

    Thanks for your time and patience in writing such a detailed reply :)

    I'll answer your questions below,

    This dump came from the communication of the PV8500 software provided with the load, with the DC load. I got this dump from a serial port sniffer software which allows me to monitor the serial port data frame exchange real time.

    Not a problem there...coz i connected the cable correctly and referred to the LEDs. When PV8500 is used, both directions' LEDs flash...however, when I use my script, LED flashes only for data transmission from laptop to the load...

    I am using the RS232 cable, not the USB one...so on issue with drivers there...


    My bad!!! Here it is :)

    Code ( (Unknown Language)):
    1.  
    2.     # Serial communication library
    3. import serial
    4.  
    5.     # Number of bytes in a packet
    6. length_packet = 26
    7.  
    8.  
    9.     # Used to sen the command to B&K load over the serial port
    10. def DumpCommand(bytes):
    11.  
    12.     # Check for a condition
    13.     assert(len(bytes) == length_packet)
    14.    
    15.     # Define the space-header
    16.     header = " "*3
    17.    
    18.     # Create space on the screen
    19.     print header,
    20.  
    21.     # Dissect the command bytes for display
    22.     for i in xrange(length_packet):
    23.  
    24.         if i % 10 == 0 and i != 0:
    25.             print
    26.             print header,
    27.            
    28.         if i % 5 == 0:
    29.             print " ",
    30.         s = "%02x" % ord(bytes[i])
    31.        
    32.         if s == "00":
    33.             s = chr(250)*2
    34.         print s,
    35.     print
    36.    
    37.  
    38.     # Used to calculate the checksum value appended at the end of each command packet (26th byte)
    39. def CalculateChecksum(cmd):
    40.  
    41.     # Check whether either of the conditions are true or not
    42.     assert((len(cmd) == length_packet - 1) or (len(cmd) == length_packet))
    43.    
    44.     # Initialize checksum
    45.    
    46.     checksum = 0
    47.     # Calculate checksum
    48.     for i in range(length_packet - 1):        # Range from 0 through 24 (25 elements)
    49.         checksum += ord(cmd[i])
    50.    
    51.     # Modulo arithmetic for correct representation
    52.     checksum %=256
    53.    
    54.     # Return value to calling function
    55.     return checksum
    56.  
    57.  
    58.     # Use this function to send a command
    59. def sendCommand(sp, deviceAddress, cmd_part, on_off):
    60.  
    61.    
    62.         # Frame terminator
    63.     LF = chr(0x0A)
    64.     CR = chr(0x0D)
    65.     terminator = CR
    66.    
    67.         # Construct a set to remote command
    68.     cmd    = chr(0xaa) + chr(deviceAddress) + chr(cmd_part)    # First three bytes
    69.     cmd += chr(on_off) + chr(0x00)*(length_packet - 5)
    70.     cmd += chr(CalculateChecksum(cmd))
    71.    
    72.         # Check for proper length of packet
    73.     assert(len(cmd) == length_packet)
    74.  
    75.         # Send command to DC load
    76.     sp.write(cmd)
    77.    
    78.         # Send the terminator
    79.     sp.write(terminator)
    80.    
    81.         # Print command contents on screen
    82.     print ' Command sent :'
    83.     DumpCommand(cmd)
    84.    
    85.     return None
    86.    
    87.  
    88.     # Get response from B&K #8510
    89. def getResponse(sp):
    90.  
    91.     # Get response from DC load
    92.     response = sp.read(length_packet)
    93.  
    94.     debugString('received response')
    95.    
    96.     # Verify length of packet status packet
    97.     assert(len(response) == length_packet)
    98.    
    99.     # Print response packet's contents
    100.     print "Response:"
    101.     DumpCommand(response)
    102.    
    103.     return None
    104.  
    105.  
    106.     # Function for debugging purposes
    107. def debugString(str):
    108.  
    109.     # Print debugging string to figure out current location
    110.     print str
    111.     print
    112.    
    113.     return None
    114.    
    115.  
    116.     # This is where the fun begins!! :)
    117. def main():
    118.  
    119.         #--------------------------------------------------------------------------------
    120.         # Specify the COM port for your machine. Value is (COM_PORT_NUMBER - 1)
    121.     port = 0    # I have COM-1, so value is 0
    122.    
    123.         # Specify baud rate (bps)
    124.     baudrate = 9600
    125.    
    126.         # Device address
    127.     deviceAddress = 0xff
    128.    
    129.         # Command to send to the device
    130.     commandSent = 0x6a
    131.    
    132.         # On or off?
    133.     on_off = 0x00
    134.    
    135.         # Byte size
    136.     byte_size = 8
    137.    
    138.         # Parity
    139.     par = serial.PARITY_NONE
    140.    
    141.         # Stop bits
    142.     stop_bits = 1
    143.    
    144.         #--------------------------------------------------------------------------------
    145.    
    146.         # Create a Serial Port object from Serial Class
    147.     sp = serial.Serial(port, baudrate, byte_size, par, stop_bits) # Open serial connection
    148.    
    149.         # Select remote control Mode
    150.     sendCommand(sp, deviceAddress, commandSent, on_off)
    151.    
    152.         # Get response from B&K #8510
    153.     getResponse(sp)
    154.  
    155.    
    156.     # Start execution here
    157. main()
    158. [/i][/i]
    NOTE: My code doesn't use the dcload.py set of wrapper modules provided by B&K Precision...I just wanted to talk to the load more directly...hence chose to instantiate serial class objects itself...let me know if that was a BAD idea :confused::confused:


    thanks for suggesting this approach! :)

    lets discuss my code first...i'll look into the other sub-systems subsequently...

    Thanks! I really appreciate your help :)
     
  4. someonesdad

    Senior Member

    Jul 7, 2009
    1,585
    141
    OK, things are a bit clearer. First, you can talk to the DC load via the PV8500 software. That establishes that your serial port works, the cable works, and the DC load is working. In my subsystems list, that means items 1, 3, and 4 are known to be working (or, more accurately, to have worked at one time :)).

    The only other things that enter the equation now are: python, the serial library, and your script. Python has been used by millions of people for millions of applications, so the chance it has the problem is very, very small. The serial library is perhaps not so well tested, but it has also been used by thousands if not hundreds of thousands of people, so it's not likely to be the problem. That leaves your script. :)

    I'm not going to read through your script and try to find where the problem is -- that's something you can do. But I can suggest a method you can use to find the problem. I recommend you use B&K's dcload.py library and first get the things you want the DC load to do working using that library. The 6A command you're using is trying to get the product information -- that's a good choice for a first command because you'll get something back that's easy to interpret. I recommend you execute that same command using the dcload.py library and first verify that the command works -- use your serial port monitor. The dcload.py library has a method to do what you want: GetProductInformation. Thus, it should only take a few lines of code to get things working using the dcload.py library. You might even figure out what's wrong by comparing your code to what's in the dcload.py file.

    Then, once you see that works, you can compare the command string you generate and the one the dcload.py library generates. If those are the same, then a likely explanation is that you're not setting up the serial object correctly. Use the debugger or print statements in the dcload.py library to see exactly how the serial object is set up and make sure you do exactly the same thing.

    If you want a back of the envelope guess as to what's wrong, I'd put my money on the communication parameters not being set up correctly.

    I've done the low-level type talking to the DC load like you're trying to do and I've used the dcload.py library. Both can work. But, trust me, the dcload.py library is a lot less work in the long run. :p

    I think it's good that you're trying to do some low-level stuff to see how things work. You'll learn more in the long run. But it can be frustrating when things don't work right and you scratch your head trying to figure out what's wrong. The dcload.py library was written to reduce the work a programmer has to do to effectively use the DC load. Once you've seen how the low-level stuff works, you'll probably want to switch to the dcload.py library -- it will make the day-to-day stuff go faster. It could also be a good model for a library written in a different language -- most of the programming work has been done.
     
Loading...