# Static assignment of USB/serial adapters

<abstract>
When using USB-to-Serial converters, there is sometimes a need to statically assign logical devices to physical USB ports regardless of the order in which the USB-serial converters are plugged into their respective USB ports. This ensures that each device maintains the same device name regardless of the order in which they are connected, which is particularly important for applications that communicate with specific hardware devices through serial ports.
</abstract>

This is the output of the <code>lsusb</code> command when I insert an USB-serial converter into each of the available USB ports:

	$ lsusb
	
	Bus 001 Device 028: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port / Mobile Phone Data Cable
	Bus 001 Device 030: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port / Mobile Phone Data Cable
	Bus 001 Device 029: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port / Mobile Phone Data Cable
	Bus 001 Device 003: ID 0424:ec00 Microchip Technology, Inc. (formerly SMSC) SMSC9512/9514 Fast Ethernet Adapter
	Bus 001 Device 002: ID 0424:9514 Microchip Technology, Inc. (formerly SMSC) SMC9514 Hub
	Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

The first three lines are related to the detected usb-to-serial converters.

	$ ls -al /dev/ttyUSB*
	
	crw-rw-rw- 1 root dialout 188, 0 Mar  4 16:56 /dev/ttyUSB0
	crw-rw-rw- 1 root dialout 188, 1 Mar  4 16:56 /dev/ttyUSB1
	crw-rw-rw- 1 root dialout 188, 2 Mar  4 16:57 /dev/ttyUSB2	

These are the devices created dynamically. The assignment between the logical device and the physical port depends exclusively on the sequence of insertion of the adapters.

To understand which logical device corresponds to which physical USB port, we give for example the following command:

	$ udevadm info /dev/ttyUSB0 | grep "ID_PATH="

	E: ID_PATH=platform-fe980000.usb-usb-0:1.4:1.0

This means that the device <code>/dev/ttyUSB0</code> physically matches with USB port 4.

In this photo, it is possible to see the numbering of the USB ports of the CM-Panel POE:

<img src="./usb-ports-numbering.jpg" style="max-width:640px; width:100%;"> 

To fix the assignment between physical USB port and logical serial device, these three lines can be inserted into the file <code>/etc/udev/rules.d/99-usb-serial.rules</code>.

	$ sudo nano /etc/udev/rules.d/99-usb-serial.rules
	
	ENV{ID_PATH}=="platform-fe980000.usb-usb-0:1.2:1.0", SUBSYSTEM=="tty", ATTRS{idVendor}=="067b", ATTRS{idProduct}=="2303", SYMLINK+="ttySerial1", GROUP="dialout", MODE="0666"
	ENV{ID_PATH}=="platform-fe980000.usb-usb-0:1.3:1.0", SUBSYSTEM=="tty", ATTRS{idVendor}=="067b", ATTRS{idProduct}=="2303", SYMLINK+="ttySerial2", GROUP="dialout", MODE="0666"
	ENV{ID_PATH}=="platform-fe980000.usb-usb-0:1.4:1.0", SUBSYSTEM=="tty", ATTRS{idVendor}=="067b", ATTRS{idProduct}=="2303", SYMLINK+="ttySerial3", GROUP="dialout", MODE="0666"

Disconnect the adapter and reconnect to the same port or type this command.

	sudo udevadm control --reload-rules && sudo udevadm trigger

Then type:

	$ watch -n 1 ls -al /dev/ttySerial1 /dev/ttySerial2 /dev/ttySerial3

	lrwxrwxrwx 1 root root 7 Mar  4 17:36 /dev/ttySerial1 -> ttyUSB0
	lrwxrwxrwx 1 root root 7 Mar  4 17:36 /dev/ttySerial2 -> ttyUSB1
	lrwxrwxrwx 1 root root 7 Mar  4 17:37 /dev/ttySerial3 -> ttyUSB2

The assignment of the logical device to the physical port is now as follows, regardless of the insertion order_

<img src="./usb-serial-devices.jpg" style="max-width:640px; width:100%;"> 


<hr>

@include='adv_cmpanel'

<!--

## Check the port assignment To view this test more quickly, we can use this Python script:

Run command:

	$ sudo apt update
	$ sudo apt install python3-termcolor

Launch this command:

	$ nano serialmonitor.py
	
Insert:

	#!/usr/bin/python
	
	import time
	import os
	import serial.tools.list_ports as ports
	from termcolor import colored, cprint   # ( Require pip install termcolor )
	
	
	while True:
    	time.sleep(.2)

    	os.system("clear")

    	print "===================================================================="
    	cprint(' FIX SERIAL USB ADAPTER - PORT MONITOR', 'blue', attrs=['bold', 'blink'])
    	print "===================================================================="

	    ser_ports = list(ports.comports()) # List serial port
	
	    cprint('\nUSB Serial Port device:', 'blue', attrs=['bold', 'blink'])
	
	    for i in ser_ports:    
	        vn = i.device
	        p = time.strftime("%Y-%m-%d %H:%M:%S") + "\t" + vn
	
	        if ( vn.find('ttyS') > 0 ):
	            cprint(p + ' - (Use this port)', 'green', attrs=['bold'])
	        else:
	            cprint(p, 'red', attrs=['bold'])
	
	
	    cprint('\nSimlink Serial Port:', 'yellow', attrs=['bold', 'blink'])
	    os.system("ls -la /dev/tty* | grep \" ->\"")
	
	    time.sleep(.2)
	
-->
