RS232 comm issue with B&K Precision Programmable DC Load

Thread Starter

maverik007

Joined Feb 6, 2009
25
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...

Rich (BB code):
    Port opened by process "PV8500.exe" (PID: 4736)
     Request: 7/6/2009 9:57:39 AM.50964 (+424.8825 seconds)
      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                     
     Answer: 7/6/2009 9:57:39 AM.53764 (+0.0280 seconds)
      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                     
     Request: 7/6/2009 9:57:39 AM.73564 (+0.1680 seconds)
      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                     
     Answer: 7/6/2009 9:57:39 AM.76764 (+0.0320 seconds)
      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                     
     Request: 7/6/2009 9:57:39 AM.82264 (+0.0350 seconds)
      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                     
     Answer: 7/6/2009 9:57:39 AM.87764 (+0.0550 seconds)
      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                     
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,

Rich (BB code):
   Port opened by process "python.exe" (PID: 5236)
     Request: 7/6/2009 9:50:34 AM.12464 (+51.3691 seconds)
    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                     
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
 

Attachments

someonesdad

Joined Jul 7, 2009
1,583
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.
 

Thread Starter

maverik007

Joined Feb 6, 2009
25
Hey someonesdad,

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

I'll answer your questions below,

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

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.)
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...

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.
I am using the RS232 cable, not the USB one...so on issue with drivers there...


You don't post any of the code you've used, so it's difficult to provide any advice about the software.
My bad!!! Here it is :)

Rich (BB code):
    # Serial communication library
import serial

    # Number of bytes in a packet
length_packet = 26


    # Used to sen the command to B&K load over the serial port
def DumpCommand(bytes):

    # Check for a condition
    assert(len(bytes) == length_packet)
    
    # Define the space-header
    header = " "*3
    
    # Create space on the screen
    print header,

    # Dissect the command bytes for display
    for i in xrange(length_packet):

        if i % 10 == 0 and i != 0:
            print
            print header,
            
        if i % 5 == 0:
            print " ",
        s = "%02x" % ord(bytes)
        
        if s == "00":
            s = chr(250)*2
        print s,
    print
    

    # Used to calculate the checksum value appended at the end of each command packet (26th byte)
def CalculateChecksum(cmd):

    # Check whether either of the conditions are true or not
    assert((len(cmd) == length_packet - 1) or (len(cmd) == length_packet))
    
    # Initialize checksum
    
    checksum = 0
    # Calculate checksum
    for i in range(length_packet - 1):        # Range from 0 through 24 (25 elements)
        checksum += ord(cmd)
    
    # Modulo arithmetic for correct representation
    checksum %=256
    
    # Return value to calling function
    return checksum


    # Use this function to send a command
def sendCommand(sp, deviceAddress, cmd_part, on_off):

    
        # Frame terminator
    LF = chr(0x0A)
    CR = chr(0x0D)
    terminator = CR
    
        # Construct a set to remote command
    cmd    = chr(0xaa) + chr(deviceAddress) + chr(cmd_part)    # First three bytes
    cmd += chr(on_off) + chr(0x00)*(length_packet - 5)
    cmd += chr(CalculateChecksum(cmd))
    
        # Check for proper length of packet
    assert(len(cmd) == length_packet)

        # Send command to DC load
    sp.write(cmd)
    
        # Send the terminator
    sp.write(terminator)
    
        # Print command contents on screen
    print ' Command sent :'
    DumpCommand(cmd)
    
    return None
    

    # Get response from B&K #8510
def getResponse(sp):

    # Get response from DC load
    response = sp.read(length_packet)

    debugString('received response')
    
    # Verify length of packet status packet
    assert(len(response) == length_packet)
    
    # Print response packet's contents
    print "Response:"
    DumpCommand(response)
    
    return None


    # Function for debugging purposes
def debugString(str):

    # Print debugging string to figure out current location
    print str
    print
    
    return None
    

    # This is where the fun begins!! :)
def main():

        #--------------------------------------------------------------------------------
        # Specify the COM port for your machine. Value is (COM_PORT_NUMBER - 1)
    port = 0    # I have COM-1, so value is 0
    
        # Specify baud rate (bps) 
    baudrate = 9600
    
        # Device address
    deviceAddress = 0xff
    
        # Command to send to the device
    commandSent = 0x6a
    
        # On or off?
    on_off = 0x00
    
        # Byte size
    byte_size = 8
    
        # Parity
    par = serial.PARITY_NONE
    
        # Stop bits
    stop_bits = 1
    
        #--------------------------------------------------------------------------------
    
        # Create a Serial Port object from Serial Class
    sp = serial.Serial(port, baudrate, byte_size, par, stop_bits) # Open serial connection
    
        # Select remote control Mode
    sendCommand(sp, deviceAddress, commandSent, on_off)
    
        # Get response from B&K #8510
    getResponse(sp)

    
    # Start execution here
main()
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:


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?".
thanks for suggesting this approach! :)

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.
lets discuss my code first...i'll look into the other sub-systems subsequently...

Thanks! I really appreciate your help :)
 

someonesdad

Joined Jul 7, 2009
1,583
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.
 
Top