16

I have five USB cameras, same brand, same model (Canyon CNR-FWC120H). They are used to monitor different scenes 24/7. I need to somehow identify which camera is which from the Linux (Debian) console or programmatically (any language).

I’ve tried looking at the output of lsusb -vvv, there is a field iSerial which should be different for each camera but unfortunately this manufacturer decided not to bother and all cameras have the same serial at that place: 200901010001

Is there any other way I could identify which camera is which independently of USB ports to which they are connected because unfortunately in my specific scenario I can not rely on the fact that the same camera will always be connected to the same port.

UPDATE After some discussion in the comments I realize this is mission impossible. So forget the last paragraph or if you do have some ingenious idea, please, you are welcome to present it. I’m now interested if I could identify which USB port the device is connected to; I use the built-in USB ports on the motherboard and additional PCI USB controller cards to accommodate the cameras with enough bandwidth. I would need to uniquely identify the port, and the port number/identification should not change if for example the machine reboots and for some reason the USB controllers get initialized in different order. Is that possible?

UPDATE 2 I see in my logs for one of the cameras the following info:

[Wed Apr 30 18:35:02 2014] uvcvideo: Found UVC 1.00 device FULL HD 1080P Webcam (0bda:58b0)
[Wed Apr 30 18:35:02 2014] input: FULL HD 1080P Webcam as /devices/pci0000:00/0000:00:01.0/0000:01:00.0/usb3/3-2/3-2:1.0/input/input4

Using that, I’ve called this command:

udevadm info --query=all --path=/devices/pci0000:00/0000:00:01.0/0000:01:00.0/usb3/3-2/3-2:1.0/input/input4

And got this:

P: /devices/pci0000:00/0000:00:01.0/0000:01:00.0/usb3/3-2/3-2:1.0/input/input4
E: DEVPATH=/devices/pci0000:00/0000:00:01.0/0000:01:00.0/usb3/3-2/3-2:1.0/input/input4
E: EV=3
E: ID_BUS=usb
E: ID_INPUT=1
E: ID_INPUT_KEY=1
E: ID_MODEL=FULL_HD_1080P_Webcam
E: ID_MODEL_ENC=FULL\x20HD\x201080P\x20Webcam
E: ID_MODEL_ID=58b0
E: ID_PATH=pci-0000:01:00.0-usb-0:2:1.0
E: ID_PATH_TAG=pci-0000_01_00_0-usb-0_2_1_0
E: ID_REVISION=5801
E: ID_SERIAL=Generic_FULL_HD_1080P_Webcam_200901010001
E: ID_SERIAL_SHORT=200901010001
E: ID_TYPE=video
E: ID_USB_DRIVER=uvcvideo
E: ID_USB_INTERFACES=:0e0100:0e0200:010100:010200:
E: ID_USB_INTERFACE_NUM=00
E: ID_VENDOR=Generic
E: ID_VENDOR_ENC=Generic
E: ID_VENDOR_ID=0bda
E: KEY=100000 0 0 0
E: MODALIAS=input:b0003v0BDAp58B0e5801-e0,1,kD4,ramlsfw
E: NAME="FULL HD 1080P Webcam"
E: PHYS="usb-0000:01:00.0-2/button"
E: PRODUCT=3/bda/58b0/5801
E: PROP=0
E: SUBSYSTEM=input
E: UDEV_LOG=3
E: USEC_INITIALIZED=41090223

The things that differ between the cameras are DEVPATH, ID_PATH, ID_PATH_TAG, PHYS and (most interesting) USEC_INITIALIZED. Now the first four elements are probably related to the USB port, but the last one USEC_INITIALIZED looks like some sort of serial number. I can’t find any info about what it actually represents. Does anyone know anything about it? I thought that it is maybe the time in micro seconds when the camera initialized but the camera that initialized after this one has USEC_INITIALIZED=17919751, and then the one after that USEC_INITIALIZED=25609278 so it seems rather random. I’ll try to reboot the system and see, but I need to wait for a convenient time to do that.

And if anyone is wondering why I don’t just try reconnecting a camera and see if that remains the same. The answer is that I’m operating this PC remotely, and I’m investigating all this to prepare the system to be fully autonomous for any potential event in the future. Which for example might include disconnecting the cameras from USB ports.

17
  • Can it be non-programatic / non-software too? eg by marking the camera front glass with a marker (different colors)? If there are no differences in the hardware and/or serials then I doubt this will be possible without custom reprogramming, you could however connect the camera's via relays/hub's which ARE different?
    – Gizmo
    Apr 30, 2014 at 15:18
  • 1
    Unfortunately no for the marker idea, because I must not introduce anything to the picture itself. I was wondering if there is a possibility to overwrite the cameras serial number? Or any other camera setting/info... Does something like that exist? Writable, persistent memory? Apr 30, 2014 at 15:24
  • This is going to be really hard, especially when no unique information for the device's is provided, see this: stackoverflow.com/questions/14053764/… . As for overwriting the memory, you could try to find a firmware flashing utility, identify the serial in the firmware and HEX-EDIT it to something you like? However I can't find any tools for it. If you can find a way to change the usb device descriptor then it would be easy from there on.
    – Gizmo
    Apr 30, 2014 at 15:27
  • You can try the HID Descriptor tool here - usb.org/developers/hidpage - Ofcourse, only if your cam is HID
    – Gizmo
    Apr 30, 2014 at 15:34
  • damn, yup I guess this is impossible, there is also no firmware for this model so that idea is out too. I guess the only thing I could do is to enforce that each camera stays connected to the same port on the PC all the time... I will modify my question. Apr 30, 2014 at 15:35

5 Answers 5

2

Are the cameras in a fixed position? Are the scenes more or less constant? If so, you could use image recognition to identify the cameras by what they are seeing instead.

There are some decent python tools to do this, this answer has some good info on the topic: https://stackoverflow.com/questions/1927660/compare-two-images-the-python-linux-way

1
  • I had this solution in mind, however I hoped for something simpler. And I would have a problem because few cameras are actually overlooking a busy port, ships moving, sea surface is not constant because of the waves, etc. Jul 30, 2014 at 2:18
2

As you discovered, the problem can't be solved, if you can't get a unique identification from the device itself. The closest thing to a solution is to depend upon the physical connection of the unit. (This won't change on reboot. Only if you physically change the position of the connector)

Programmatically you can use sysfs to get the information the kernel has, about the device. Sysfs is a file-system-like representation of devices as the kernel sees them. (Its not real files on the disk)

With it, you can: - identify the device type with product and vendor ID - read the serial number of the device, if it has one. - read the physical connection number on the USB hub

You could start by finding your type of devices in /sys/class. In this example I use an USB→LPT port. But the principle is the same.

$ ls -l /sys/class/usbmisc
lp1 -> ../../devices/pci0000:00/0000:00:1d.0/usb4/4-1/4-1.5/4-1.5:1.0/usbmisc/lp1
lp2 -> ../../devices/pci0000:00/0000:00:1d.0/usb4/4-1/4-1.6/4-1.6:1.0/usbmisc/lp2

Grap the device name from the uevent file:

cat /sys/class/usbmisc/lp1/uevent
MAJOR=180
MINOR=1
DEVNAME=__usb/lp1__

add /dev so you get the device name to open: /dev/usb/lp1

Use the real path: $ cd -P /sys/class/usbmisc/lp1

Step back 3 branches:

$ cd ../../../
/sys/devices/pci0000:00/0000:00:1d.0/usb4/4-1/4-1.5

This directory contains a lot of the information on the device:

idProduct and idVendor can be used to uniquely identify the device type.

If there is a serial file and it contains a unique serial number, you are done.

Otherwise your option is to use the physical connection as identification, which is this directory name “4-1.5” It is unique for the physical connection, and will as you already mentioned change if you plug the device into another port.

2
  • I guess this is the best solution, or compromise in my case... Fixate the cameras to the same dedicated USB port. I say compromise because in my case I also had the requirement to identify the cameras if for example after a hardware maintenance the cameras would be connected to different ports by the person doing the maintenance. Mar 4, 2016 at 15:57
  • I agree. This is far from perfect. I wish it was common for vendors, to add a f... simple serialnumber to the device, as the protocol specifies. I hope you find a better solution! Mar 5, 2016 at 20:43
1

Simply unplug the camera's, plug 1 in and do a lsusb. Identify the camera and note down which USB port is used. Maybe put a little label on the cam. Then repeat for the other camera's and you'll get there. Nothing is mission impossible ;)

2
  • This makes sense. Just plug one camera in at a time and note which physical port it's attached to. Looks like you could even turn the individual ports on and off if you can't differentiate within your software, so only one would appear at a time. See askubuntu.com/questions/342061/… May 28, 2014 at 2:33
  • I admit I did not explain completely clear the purpose of my configuration. It is a PC on a remote location used for recording long duration(months) time-lapses. I wished for a solution which could automatically identify cameras without my intervention. Now after any power outage I actually have to log in and manually reconfigure the camera numbers. Jul 30, 2014 at 2:14
1

It is possible to identify all cameras. The command

 $ sudo lsusb -v -d 046d:082d | grep -i serial
   iSerial                 1 05C6D16F

returns the Serial number of my camera (a Logitech HD Pro Webcam, used as an example with the correct Vendor:Product codes obtained from a previous use of lsusb). Please notice that it is absolutely necessary to perform this operation as a privileged user: an unprivileged user does not get access to all info available thru the command.

The serial number is often, but not always, unique. If it is not unique (just compare the output of the above commands for two devices with the same Vendor:Product codes), you can set them so that they are distinct. There are guides all over Google for doing that, I will merely point to a couple of them, for the sake of thoroughness: here and here.

Now the command

$ sudo udevadm info --query=all /dev/video1 | grep 'VENDOR_ID\|MODEL_ID\|SERIAL_SHORT'
  E: ID_MODEL_ID=082d
  E: ID_SERIAL_SHORT=05C6D16F
  E: ID_VENDOR_ID=046d

returns the appropriate codes for this particular camera. Trial and error with all /dev/videoX devices allows pigeon-holing all of them.

1
  • It seems to me as if you maybe did not read my initial question post to the end. I've already mentioned in my post about using udevadm... The problem is that all the cameras have the same serial number so you can't tell them apart from that info. You mentioned "you can set them so that they are distinct" is there a way to "set"/change the serial number? Mar 4, 2016 at 15:49
-1

I've heard of someone delaying power on in sequence to devices during a boot up, which would allow you to identify them based on the order they turn on. It would require some addition hardware that could control power to individual usb ports in order.

You could hack a USB hub that has individual power switches for each port, hook that to an arduino and trigger which order they are turned on.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .