Python Smart Terminal Technical Details
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
Contents
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
In the "manual" mode you would press the Open button on the GUI and hopefully the port will open ( it will if the port exists and is available for opening ). Then typically you will send something to the micro controller and look for a reasonable response. This is fine. You can also automate the process by using the method find_arduino( ) in HelperThread instance. Here is what it does.
- Works through your list of comm ports as specified in parameters.port.
- For each port try to open it with the other comm parameters in parameters.py
- If a port opens waits a bit ( for the arduino to reset ... time specified by: parameters.not_done_yet ...... now hardcoded
- The second level of validation is that the port can send and receive to the desired arduino, this is checked by sending a text string ( as specified in parameters.get_arduino_version) and looking for a response.
- The third level is to look at the received string. If it contains the correct substring ( as specified in parameters.arduino_version) then the port is valid.
- Stops looking at the port list if a comm port passes this validation test.
For example the terminal may send "v<cr>", recieve "GreenHouse Monitor v3 2017 01 24.01<cr>", and look for "GreenHouse" in the received string. This would validate the port.
So what does the terminal send and what does it look for -- see the parameter file; you should find something like this:
# 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" # send to the port to get a response from the arduino. self.arduino_version = "GreenHouse" # the received response from the arduino should contain this as a substring if the comm port is valid.
Note that the find_arduino() method does not try different baud rates, you need to get that one right yourself.
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.