I have a Raspberry Pi 3 with a GPS module and an ELM327 adaptor both connected to USB ports. Typically, the GPS module comes up on /dev/ttyUSB0 and the ELM adaptor on /dev/ttyUSB1, which is fine, however every once in a while they will swap ports. This tends to upset my python scripts running on the device.

Is there a way I can control/configure which device will connect to which port? Is it a first come first serve when assigning port numbers?

Running Raspbian Jessie.

  • 1
    Have you considered adding logic to detect a specific device to your Python code instead of trying to control the enumeration? Something like this stackoverflow.com/questions/8110310/… or stackoverflow.com/questions/2487033/usb-device-identification. This would seem to be a more foolproof/futureproof solution. – Steve Robillard May 2 '17 at 15:41
  • I had considered it but was hoping to avoid it. I had a look at the posts you suggested. Although pyUSB showed the most promise, it still didn't quite hit the mark, as any dev.filename always came back None. But it did send me in a direction, and this is what I came up with: – Golgothen May 4 '17 at 14:28

I use pmount, and it does a very good job of keeping USB devices consistent.

You can get it like this:

sudo apt-get install pmount

It works great for serial and flash drive devices, so it is definitely worth a try.

  • Ill take a look when I get a chance... Cheers... My code work-around is a bit of an ugly hack, but works as long as devices aren't removed and added later on different ports (should be OK for an embedded pi system...) – Golgothen May 5 '17 at 17:05

So this is what I came up with... may not be pretty, but gives me what I needed...

import subprocess

devices = {}
# put all dmesg messages into a list
output_list = []
output_list = str(subprocess.check_output('dmesg')).split('\\n')

# Look for 'New USB device' messages   
filter_list = [x for x in output_list if 'New USB device found' in x]
for f in filter_list:
    # This message gives us vendor, product and bus ID's
    bus_id = f.split(':')[0].split(']')[1].strip()
    devices[bus_id] = {}
    devices[bus_id]['VENDOR'] =  f.split(',')[1].strip().split('=')[1]
    devices[bus_id]['PRODUCT'] =  f.split(',')[2].strip().split('=')[1]
    # list to store all other details about the device
    device_details = []
    # pull out all messages from dmesg in relation to the bus ID
    device_details = [x for x in output_list if bus_id in x]
    # Pick out the info we need:
    for d in device_details:
        if 'Product:' in d:
            # Product Name
            devices[bus_id]['NAME'] = d.split(':')[2].strip()
            if 'Manufacturer' in d:
                # Manufacturer Name
                devices[bus_id]['MANUFACTURER'] = d.split(':')[2].strip()
            if 'now attached to' in d:
                # Block device - if it has one 
                devices[bus_id]['FILE'] = d.split('now attached to')[1].strip()

for dev in devices:
    print('USB Bus ID: {}'.format(dev))
        for prop in devices[dev]:
            print('  {} = {}'.format(prop, devices[dev][prop]))
  • 1
    Udev will do this kind of thing for you (have a look at any file in /etc/udev/rules.d and you should get the idea). Also try udevadm monitor and watch what happens when you plug a device in and out. There's lots of stuff online about this, just don't include "raspberry pi" in your search terms; use "linux". It's been around for a long time. – goldilocks May 4 '17 at 15:28
  • Please accept your own answer with a click on the tick on its left side. Only this will finish the question and it will not pop up again year for year. – Ingo Dec 16 '19 at 14:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.