2
votes

I have one peripheral device (say hardware circuit with microcontroller). I have to iput some commands to this peripheral device via serial communication. These commands are embedded into a python script. I am using USB-Serial cable to connect peripheral device to PC. Now I have to write the code in pyserial so that PC will automatically detect the com port on which Peripheral device is connected and connects the devide with PC successfully.(loop back can be possible)

Currently I am using following Code in Pyserial. I have explicitely mentioned that Peripheral is connected to PC on COM1 ---

try: 
        self.ser = serial.Serial(0)
        #self.ser.port='/dev/ttyS1'
        self.ser.baudrate = 9600
        self.ser.bytesize = serial.EIGHTBITS 
        self.ser.parity = serial.PARITY_NONE 
        self.ser.stopbits = serial.STOPBITS_ONE 
        self.ser.timeout = 1            
        self.ser.xonxoff = False     #disable software flow control
        self.ser.rtscts = False     #disable hardware (RTS/CTS) flow control
        self.ser.dsrdtr = False       #disable hardware (DSR/DTR) flow control
        self.ser.writeTimeout = 2     #timeout for write
    except Exception, e:
        print "error open serial port: " + str(e)

Please let me know that how can a COM port is automatically detected and gets connect afterwards?

1

1 Answers

0
votes

This is a common issue and can be solved by checking for a specific return code (usually an identification string) from the peripheral device. Here's an example, using pyserial:

from serial.tools import list_ports

def locate_port():
    """Attempt to locate the serial port to which the device
    is connected."""

    status_request_string = 'OI;'  # Output information
    expected_response = 'DISPENSEMATE'

    device_port = None
    for port_name, port_desc, hw_id in list_ports.comports():
        with serial.Serial(port=port_name, **device_serial_settings) as ser:
            ser.write(status_request_string)
            if ser.readline().startswith(expected_response):
                device_port = port_name
                break
    if not device_port:
        raise UserWarning('Could not find a serial port belonging to '
            'the asymtek dispensemate.')
    return device_port

Usually, the manual of the device you're communicating with has at least one command that does not change the state of the device, but merely echoes back your last line or returns its configuration, hardware ROM version or simply its name. It is this response (and the command that requests it), that you 'll need to fill in for expected_response and status_request_string respectively. The device_serial_settings is a dictionary that contains the parameters such as baudrate and parity bits; everything needed to connect properly to the device, except for its name. As you can see, the code above was written for an Asymtek Dispensemate (an old one too and thus difficult to get support for).

If you call that function, you can use its return value to simply connect to the device:

port = locate_port()
my_device = serial.Serial(port, **device_serial_settings)

There is one caveat though: if the computer is connected to several serial devices that are all powered on, it is possible that you send an illegal command to the other devices. In the best case, they simply reply with an error code and their state will be unaffected, but the command could also make changes to these devices, so check all other peripherals for their dictionaries of "allowed opcodes".