Search code examples
raspberry-piesp32ttyusbserial

Static binding serial ports in ubuntu on Raspberry Pi


I am running a setup of 4 ESP32 which are connected to a PI through serial connections. Is there a way to statically bind all of the ESPs, so the port order after every boot doesn't matter? It also has to be ID unspecific, since I'm running several similar setups and the code should fit all. Also, in case of a replacement, I just want the system to know that there is the same device on the same port.

I'm sorry if I wrote it confusing, but generally, I want the ESPs to be replaceable, while the port describes the function of the device.

Thanks guys and happy coding


Solution

  • The only practical approach is ID based, sorry. USB devices are created in the same order they are initialized, so no guarantees whatsoever. If it helps, here's an udev rule which creates symlinks from the serial number of the Silabs USB-serial chip, e.g. /dev/EDK-d80d38b81e. Tested with DevKitC and LOLIN32 boards.

    # udev rules for the Espressif ESP32-DevKitC and Wemos LOLIN32 dev boards to
    # allocate symlinks with fixed names for each device using its serial number.
    
    # CP2102N/CP2104N with idVendor=10c4, idProduct=ea60
    #
    # Instructions:
    # 1. Copy udev rules and restart daemon:
    #   $ sudo ln -s "$PWD/70-cp210xn_ESP32-DevKitC.rules" /etc/udev/rules.d/ && sudo systemctl restart udev
    # 2. Disconnect and connect the board to USB
    
    # Espressif ESP32-DevKitC with CP2102N.
    # Sample serial in chip is "7063b99e4b74ea11b6f52208cf25bb41" where only first
    # 10 chars seem to be unique. We cut the serial down to those and create a
    # symlink from the result, e.g. "/dev/EDK-7063b99e4b"
    SUBSYSTEMS=="usb", KERNEL=="ttyUSB*", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", ATTRS{manufacturer}=="Silicon Labs", ATTRS{product}=="CP2102N USB to UART Bridge Controller",  PROGRAM="/usr/bin/awk -- 'BEGIN { print substr(\"$attr{serial}\",1,10) }'" SYMLINK+="EDK-%c", GROUP="dialout", MODE="0660"
    
    # Wemos LOLIN32 with CP2104N, sample serial in chip is "01DFA32C".
    # We create a symlink "EDK-01DFA32C" (cropping to first 10 chars just in case).
    SUBSYSTEMS=="usb", KERNEL=="ttyUSB*", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", ATTRS{manufacturer}=="Silicon Labs", ATTRS{product}=="CP2104 USB to UART Bridge Controller",  PROGRAM="/usr/bin/awk -- 'BEGIN { print substr(\"$attr{serial}\",1,10) }'" SYMLINK+="EDK-%c", GROUP="dialout", MODE="0660"