System designTroubleshooting

Depth camera timeout with other USB devices: one shared controller

Why a depth camera times out only when a second USB device is attached, the tests that separate bandwidth, enumeration and power, and the fix that holds.

LumaSpec Vision12 min read Share on LinkedIn

On this page 9 sections
  1. 01What the symptom tells you
  2. 02Read the topology before you touch a setting
  3. 03Worked example: does a 1 MP depth stream plus a serial scale fit one controller?
  4. 04The causes in order of probability, and the test that settles each
  5. 05The fix that holds: give the camera its own path
  6. 06When the usual answers are wrong
  7. 07Prevention: budget the link before the second device arrives
  8. 08Quick checklist
  9. 09Questions

A depth camera that streams frame after frame on its own, then fails the moment you plug in a scale or any other USB device, is not misconfigured. The camera and the newcomer are sharing one USB controller, and they are contending for one of four resources: link bandwidth, enumeration order, port power, or CPU and interrupt time. This guide gives you the commands that separate those four in minutes, a bandwidth budget you can run before ordering anything, and the fixes that still hold when the next device arrives on the same bench.

What the symptom tells you

The signature is specific. Alone, the camera runs for hours. The second device — in the classic case a counting scale whose readings arrive over a USB-serial adapter as /dev/ttyUSB0 — works normally from the moment it attaches. Only the camera fails, consistently, with a frame-wait error such as Frame didn't arrive within 5000.

Read the number in that error as milliseconds: 5,000 ms. At 30 fps it spans 150 frame periods, so the stream is not slow — it has stopped. The scale still answering is diagnostic too. A serial adapter moves bytes per second; the camera moves megabytes per second. A contended bus starves the video stream long before the serial device notices, which is why the symptom points at the camera when the bus is the real suspect.

The conclusion follows: something shared changed at the plug event. On a desktop with several controllers this is rare. On a compact embedded ARM host it is the norm, because many such boards hang every USB port off a single controller that itself sits on one small upstream link — one pipe and one interrupt budget for everything you plug in.

Read the topology before you touch a setting

Two commands answer most of the question. lsusb -t prints the USB tree as the kernel sees it: everything under one bus line shares one controller. Note which bus the camera sits on, then run dmesg -w in a second terminal and plug the scale in.

Watch the camera's lines while the scale enumerates. Disconnect or reset messages against the camera at that moment convict enumeration or power, not bandwidth. A silent camera log shifts suspicion to device naming: list /dev/ttyUSB* before and after, because a shifted node means your scale reader may now be opening the wrong device while your camera code holds a stale one.

Make the naming permanent so it cannot recur. A udev rule that matches the adapter's vendor, product and serial attributes and creates a fixed symlink such as /dev/scale pins the reader; opening the camera by its own serial number instead of enumeration order pins the video side. Both patterns are worked through in selecting each depth camera on one host by serial number and in fixing a USB port ID that is the same for all cameras.

Note where the camera physically sits as well. Behind an unpowered hub it shares that hub's bus and power with everything added later — the most common self-inflicted version of this fault, covered step by step in why a USB hub drops camera frame rate.

Worked example: does a 1 MP depth stream plus a serial scale fit one controller?

The inputs, with their sources:

  • Depth stream: 1,024 × 768 px, 16 bit (2 B per pixel), 30 fps — a representative mid-size industrial depth map; substitute your own resolution and frame rate.
  • Scale: readings over a USB-serial adapter at 115,200 baud, or 0.115 Mbit/s of line rate worst case.
  • Ceilings: a high-speed USB 2 segment carries 480 Mbit/s of signaling and about 240-320 Mbit/s of real payload once transaction overhead is paid; a SuperSpeed USB 3 path carries 5 Gbit/s of signaling, which 8b/10b coding reduces to 4 Gbit/s ≈ 500 MB/s, and sustains roughly 3,200-3,800 Mbit/s in practice.

The rule in words: stream rate equals width times height times bytes per pixel times frame rate; add every stream on the controller, divide by its practical ceiling, and keep the result under a 70% planning line so enumeration bursts and retries have slack.

stream (MB/s) = width × height × bytes-per-pixel × fps ÷ 1,000,000 utilisation (%) = 100 × (camera + other streams) ÷ practical ceiling

The arithmetic:

  • Pixels per frame: 1,024 × 768 = 786,432 px.
  • Bytes per frame: 786,432 × 2 B = 1,572,864 B ≈ 1.57 MB.
  • Stream rate: 1,572,864 B × 30 = 47,185,920 B/s ≈ 47 MB/s.
  • In line-rate terms: 47,185,920 × 8 = 377,487,360 bit/s ≈ 377 Mbit/s.
  • Scale: 0.115 Mbit/s, or 0.115 ÷ 377 ≈ 0.03% of the stream — bandwidth noise.

The result: on a high-speed segment the depth stream alone exceeds the practical 240-320 Mbit/s budget, so a stream this size cannot live on a USB 2 path at 30 fps at all. On the shared SuperSpeed link it uses 377 ÷ 3,500 ≈ 11% of the ceiling, far below the 70% line.

The decision: if your own numbers land under 70%, bandwidth is exonerated — go straight to the enumeration, power and CPU tests below. If they land above 70%, or the camera is sitting on a high-speed segment, split the devices across controllers before touching any setting.

What moves the number: 15 fps halves the stream to 786,432 × 2 B × 15 ≈ 24 MB/s ≈ 189 Mbit/s, which fits a high-speed segment's physical budget but sits at 189 ÷ 240 ≈ 79% of it, above the planning line once anything else joins. Adding a 640 × 480 RGB companion stream at 30 fps adds 640 × 480 × 3 B × 30 ≈ 27.6 MB/s for a total of ≈ 75 MB/s ≈ 600 Mbit/s — about 17% of a shared SuperSpeed link, and well over a high-speed segment's entire budget.

The causes in order of probability, and the test that settles each

  1. One controller, no headroom. The camera and the scale landed on the same bus, and the link was already close to its practical ceiling. Test: the budget above, confirmed with lsusb -t — ports you assume are separate often are not. Fix: a dedicated port on another controller.
  2. Enumeration collision or a moved device node. The plug event re-ordered device names, and a reader or the camera's own auxiliary interface grabbed the wrong node. Test: dmesg -w at the plug event plus a before-and-after listing of /dev/ttyUSB*. Fix: the udev symlink and serial-number opening described above.
  3. Port power brownout. Compact hosts budget milliamps per port, and a scale that draws against that rail drags the bus down in bursts exactly when it samples. Test: power the scale from a separately powered hub — a timeout that disappears convicts the rail. Fix: powered hub for peripherals, camera direct to a root port.
  4. CPU and interrupt starvation. On a small SoC, USB interrupt load plus a busy-polling serial reader can starve the frame-delivery thread even with wire to spare. Test: top during a failure — one core pegged by the reader is the signature. Fix: event-driven reads or a slower poll rate; a second controller spreads the interrupt load as well. The bandwidth and CPU budget for a depth camera on an ARM board runs the processor side of the same math.
  5. A marginal link that only fails under load. A long or damaged cable can pass when it is alone and fail once real bus activity rises. Test: a short known-good cable straight into the host, no hub; the length and data-rate limits of USB-C cables on a USB3 camera set the safe span.

The fix that holds: give the camera its own path

Every durable fix separates the devices at the hardware level, then pins the software names:

  • Desktop or full-size host: move the camera to a port on the other root hub, or add a USB controller on a PCIe card and keep the camera alone on it.
  • Embedded board with a spare UART: move the scale onto the UART through an RS-232 or RS-485 transceiver and it leaves the USB bus entirely.
  • Embedded board with neither: put the scale behind a network serial adapter so it speaks Ethernet instead of USB, or hang it off a hub on a different controller if the board exposes one.
  • Software, in every case: the udev symlink for the adapter, the camera opened by serial number, and the frame timeout left exactly where it is until the hardware is settled.

When the board has no second controller to give, the host is the part to change. A PC-class vision controller brings several USB 3 ports, its own GigE NICs and cores to spare, so the camera keeps a port to itself. The MV-VC2140-128G40-1T carries two USB 3 ports and several GigE LAN ports with 8 GB of memory and a 128 GB SSD, which suits a single-camera station.

Vision controllersHikrobot MV-VC2140-128G40-1T VC2100 Vision Controller, N97, 8GB+128G SSD+ 1THDDMV-VC2140-128G40-1T
LAN ports
3-4 LAN ports
USB 3 ports
2 USB 3 ports
Light outputs
4 built-in channels
Memory
8 GB
$1,679.00View partBuild a system with it

For more ports or built-in lighting in the same move, the MV-VC3301H-128G66 runs a Core i3 with 8 GB of memory, carries five or more LAN ports and three or four USB 3 ports, and supports a PCIe expansion card — the clean way to add the dedicated second controller this fault asks for. It includes the VM6200Pro vision license.

Vision controllersHikrobot MV-VC3301H-128G66 I3-8100, 8GB+128G SSD, No PoE, PCIe expansion supported, Incl. VM6200Pro licenseMV-VC3301H-128G66
LAN ports
5+ LAN ports
USB 3 ports
3-4 USB 3 ports
Light outputs
4 built-in channels
Memory
8 GB
$2,419.00View partBuild a system with it

The MV-VC5525-256G70-NN steps up to a 12th-generation Core i5 with 32 GB of memory, PoE camera ports and eight built-in light channels, which covers a cell that mixes depth cameras, area cameras and strobed lights on one host.

Vision controllersHikrobot MV-VC5525-256G70-NN VC5000 Vision Controller, 12th-I5, 32GB+256G SSD, Supported PCIEMV-VC5525-256G70-NN
LAN ports
5+ LAN ports
USB 3 ports
3-4 USB 3 ports
PoE
PoE camera ports
Light outputs
8 built-in channels
$4,479.00 · quotedView and quoteBuild a system with it

Browse the vision controllers category to compare the models above by USB 3 and LAN port counts, and use the expert support line through the contact page if you want help sizing controller, camera and lighting together for one host.

When the usual answers are wrong

Two reflexes waste afternoons here. The first is raising the timeout from 5,000 to 15,000 ms, which turns a hard failure into a slow one without moving a single extra frame across the wire. The second is reinstalling or re-tuning the SDK: when identical code runs cleanly the moment the hardware moves to a laptop, software was never the suspect. Convict the host, not the driver.

Two look-alikes deserve a check before you blame contention. If the camera runs inside a virtual machine or container, the passthrough layer has its own failure modes — start with camera USB passthrough inside containers. If the timeouts began when you switched the color stream on next to depth, rather than when a device was plugged in, that is the dual-stream bandwidth case covered in the depth and color stream bandwidth check.

Run the worked example's arithmetic for every stream you plan, sum it per controller, and keep each sum under about 70% of that controller's practical ceiling. The 70% line is a planning rule of thumb, not a physical constant: it exists so enumeration bursts, retries and one device you have not thought of yet still have slack. Record which physical port belongs to which controller when you commission the station, and label the ports.

For several cameras on one host the same discipline scales — planning host bandwidth under heavy multi-camera use extends it to a whole cell — and the 3D sensors category with its camera finder is where the depth cameras themselves live.

Quick checklist

Work down the list in order; each line either finds the cause or clears one.

  • Before connecting: check with lsusb -t which controller each planned port belongs to.
  • Budget: width × height × bytes per pixel × fps for every stream, summed per controller, against 240-320 Mbit/s (high-speed) or 3,200-3,800 Mbit/s (SuperSpeed), kept under 70%.
  • At the first failure: dmesg -w while plugging, watching for camera disconnect lines and shifted /dev/ttyUSB* names.
  • Power: move the newcomer to a separately powered hub; a disappearing timeout convicts the rail.
  • CPU: top during a stall; a core pegged by the serial reader calls for event-driven reads or a lower poll rate.
  • Cable: short known-good cable, straight into the host, no hub.
  • Fix and pin: camera alone on its controller, serial device elsewhere, udev symlink in place, camera opened by serial number.
  • If nothing separates: run the same software on a PC-class host — if it streams cleanly, rebuild the station on a vision controller and keep the board for lighter duty.

If the diagnosis ends at the host, rebuild on a vision controller from the shortlist above and keep the embedded board for single-device duty. More failure-specific fixes for fussy USB hosts sit on the systems topic page, and the guides hub collects the rest of the series.

Questions

Why does the scale keep working while the depth camera times out?

A USB-serial adapter needs almost no bandwidth: a scale reporting one weight per second moves a few hundred bytes, well under 0.01 Mbit/s even at 115,200 baud. The camera's continuous stream needs hundreds of Mbit/s, so when a shared controller runs short, video stalls first while the serial device keeps answering. That asymmetry is why the fault shows on the camera when the bus is the real suspect.

How much bandwidth does a depth camera stream actually need?

Multiply width by height by bytes per pixel by frame rate. A 1,024 × 768 depth map at 16 bit and 30 fps needs 786,432 × 2 B × 30 ≈ 47 MB/s, or about 377 Mbit/s. Halving the frame rate drops it to roughly 24 MB/s; adding a 640 × 480 RGB stream at 30 fps raises the total to roughly 75 MB/s ≈ 600 Mbit/s. Keep the per-controller sum under about 70% of the practical ceiling.

Should I raise the 5000 ms frame timeout?

Only after the bus is fixed. At 30 fps, 5,000 ms already spans 150 frame periods, so a stall long enough to trip it means frames are lost, not merely late. Extending it to 15,000 ms hides the symptom for a few extra seconds and adds latency to every genuine drop. Once the hardware is settled, set the timeout to cover the worst gap your process tolerates, plus margin.

Do USB 3 and USB 2 devices share bandwidth when they sit on adjacent ports?

They use separate wiring inside the plug, but on hosts where all ports hang off one controller both lanes terminate in the same chip and share its upstream link and interrupt budget. A SuperSpeed camera does not get a private pipe just because it uses the faster port. Treat every port on one controller as one budget, and confirm the split with lsusb -t before assuming two ports are two buses.

When is moving to a dedicated vision controller the right fix?

When the board has no second controller to offer and no spare UART for the serial device, or when CPU sits near its ceiling during streaming. A PC-class vision controller keeps the camera on one USB 3 port and peripherals on another, with separate GigE NICs for network traffic and cores to spare for processing. If you also want PoE cameras or built-in light channels, step up within the same controller families.