4

I have testing equipment that is made-up of the following:

  • a USB Hub connected to the master PC, the hub is embedded in the test jig and is used so that we have only 1 USB cable running from the jig to the PC.
  • an Arduino UNO, connected by USB to the Hub
  • a measurement instrument (powermeter) connected to the USB hub through USB
  • another measurement device (thermometer) connected to the USB hub by USB
  • a Python script that runs the testing procedure from the master PC and communicates to Arduino and both instruments.

All this works well with my first jig but I need now to duplicate the testing setup (3 testing jigs on one PC). I want to assign udev persistent rules for the devices so the testers later just need to select 1, 2 or 3 depending on which jig they use, so they don't need to fiddle with the port numbers.

Is there a way to do a rule that would basically say: assign symlink /dev/powermeter01 to the powermeter that is on the same USB hub as the Arduino with the serial xxxxxxx ?

For the Arduino, that is easy as there are proper serial numbers in the udevadm info, but for the powermeter, the serial number is always the same and for the thermometer, there is simply no serial number (thank you cheap suppliers!!!).

The USB hub also has apparently no serial.

3

Well, this is not an answer to the question but brings me a solution. so here it is.

I fiddle quite a bit with Udev rules, could not get anything better than my Arduino persistently appear on /dev/arduino01 (will use /dev/arduino02, /dev/arduino03,... for other jigs)

My testing script is in Python, I just found out that there is a nice library called pyudev so I decided to have a look at this route.

After just few minutes, I ended up with

from pyudev import *
context = Context()
Arduino = Device.from_device_file(context, '/dev/arduino01') 
Hub = Arduino.find_parent("usb","usb_device").find_parent("usb") #first find_parent brings me up to the USB device Arduino, another find_parent brings me to the Hub

Fixture = Enumerator(context)
for dev in Fixture.match_parent(Hub).match_subsystem('tty'):
    if (dev.get('ID_VENDOR_ID')=="10c4" and dev.get('ID_MODEL_ID')=="ea60"): #I got those ID through udevadm.
        powermeter=dev
    if (dev.get('ID_VENDOR_ID')=="067b" and dev.get('ID_MODEL_ID')=="2303"): #I got those ID through udevadm.
        temprecorder=dev

print('Arduino in on ' + str(Arduino.device_node)) #prints : Arduino is on /dev/ttyACM0
print('Powermeter in on ' + str(powermeter.device_node)) #prints : Powermeter is on /dev/ttyUSB1
print('Thermometer in on ' + str(temprecorder.device_node)) #prints : Thermometer is on /dev/ttyUSB0

This gives me the USB ports of my 3 devices of the test jig, I can now feed it to my testing routine script.

The more savvy between us will then have seen that my temprecorder is through a pl2303 USB-serial and my powermeter through a CP2102 USB-serial.

  • This is the best solution I could find. There are many obstacles if this implemented using udev rules which make this a fast direct way to resolve the issue: racing condition (USB-serial device node may created before arduino node), could be fixed with delayed RUN script. Need much shell to parse the unfriendly sysfs path (up/down) to scan for other hub child nodes looking for arduino serial. – user.dz Jul 15 '16 at 11:05
  • 1
    For the timing, I do not have much worry as the script will be run well after PC is started. I agree on your point for the path parsing. in my case it hapenned to be simple as 3 times the same architecture. but for more complex cases, one could think of a loop to define the "network" structure. – Memes Jul 15 '16 at 11:10
1

udev does not have only serials to match devices, you can use any property available.

So you can use almost any thing different in udevadm info /dev/... & udevadm info -a /dev/... from both devices with same serials.

If you can share those outputs for each device, I may able to help. From your answer, it seems you already got vendor/model not the same, so that could be used in udev rules.

  • 1
    this I knew, the problem was I had 2 identical devices, from same manufacturer to differentiate. in case 1, it was 2 USB-RS232 having both same serial number, in the other case, 2 USB-RS485 having no serial number. – Memes Jul 15 '16 at 4:32
  • @Memes , Just one point, Does the jig hub have a serial? or they have same issue: no serial or they are identical. Could you share the output of udevadm info -a ... – user.dz Jul 15 '16 at 10:54
  • 1
    the jig is what I made by putting together 3 devices : An Arduino connected by USB, a power meter connected through a USB-RS485 adapter, a temperature recorder connected through a USB-RS232 adapter. All 3 devices are connected to a USB hub. Everything is then put in an enclosure with a single USB cable running to the PC. I have 3 of these jigs. – Memes Jul 15 '16 at 10:58
  • Now thanks to udev, I can identify the Arduino as they have serial. then, thanks to pyudev, I can crawl back to the host hub, then discriminate which powermeter is coupled with which arduino, same for the temperature recorder or in other words, I can identify the elements of every one of my jigs without having serial on all of them. – Memes Jul 15 '16 at 11:00
  • 1
    and as I see I did not read properly your question : no, the jig hub have no serial and they are all 3 of them the same (i.e. same idVendor, same idModel) – Memes Jul 15 '16 at 11:02

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.