Python Smart Terminal Technical Details

From OpenCircuits
Jump to navigation Jump to search

This page is for some fairly fine scale detail on how things are implemented in the Smart Terminal, they may be useful as techniques in other applications. See also: Russ Python Tips and Techniques

Finding the Arduino - Comm Port Details

In the parameter file there is a setting for the comm port, this is typical of all communications programs. Other parameters hold other comm port values. Again typical. There are however, some less typical additions.

Comm Port Validation

  • So you open a comm port, the first level of validation is that the port opens.
  • The second level of validation is that the port can send and receive, this is checked by sending a text string and looking for a response.
  • The third level is to look at the received string. If it contains the correct substring then the port is valid.

For example the terminal may send "v<cr>", recieve "GreenHouse Monitor v3 2017 01 24.01<cr>", and look for "GreenHouse" in the recieved string. This would validate the port.

So what does the terminal send and what does it look for -- see the parameter file:

        # next used in a port probe routine to help identify the port with an arduino
        # the arduino is supposed to respond to a version request with a string
        # containing this, they are part of the name of an Arduino application
        self.get_arduino_version    = "v"

        self.arduino_version        = "GreenHouse"

What are the Possible Comm Ports

The SmartTerminal uses two methods for this. One is just back to the parameter file:

        # used to probe around for ports
        if  self.os_win:
            self.port_list  =  [ "COM1",  "COM2",  "COM3",  "COM4",  "COM5",  "COM6",  "COM7",  "COM8",  "COM9",  "COM10",
                                "COM11", "COM12", "COM13", "COM14", "COM15", "COM16", "COM17", "COM18",  "COM19", "COM20",
                               ]

        else:
            self.port_list  =  [ "/dev/ttyUSB0", "/dev/ttyUSB1", "/dev/ttyUSB2",
                                "/dev/ttyACM0", "/dev/ttyACM1", "/dev/ttyACM2",
  

The above uses the automatic detection of the operating system. You could of course skip that part of the implementation.

The second method. There is a Python function for detecting ports. It is documented as not always being right. Here it is:

     list(serial.tools.list_ports.comports())

So finally when making a list of ports to probe I make a list ( in the order the ports will be tested ):

  • Start with port in the parameter file.
  • Add the ports reported by python ( no duplicates ).
  • Add the ports in the parameter port list ( no duplicates ).

If no ports are actually present you can test 20 ports in seconds. Sending and receiving strings takes longer. Note that all of this is done using the baud rate and other parameters in the parameter file, we do not probe using variations on them. Actually, in most cases, the baud rate.... are part of the identification of the arduino.

So with this list we loop through it trying to validate each port.

Code in SmartTerminal

  • Review this for the inner inner details. Send questions if not clear.
  • in smart_terminal_helper.HelperThread.test_ports( self, a_port_list, a_get, a_valid_response ) is the probe and validation routine, but this needs the port list, the probe string and the valid response.
  • above uses, in the same object, test_port()
  • first subroutine above is called from ( same object ) find_arduino( ) which constructs the port list and get parameters as needed from parameters.