3D visionTroubleshooting

Event camera external trigger stops with multiple cameras open

External-trigger callbacks fire once, then stop when a second event camera opens. A counted pulse test separates a sync-role cause from an SDK one.

LumaSpec Vision9 min read Share on LinkedIn

On this page 9 sections
  1. 01The symptom and why it points the wrong way
  2. 02Likely causes, most probable first
  3. 03Test 1: count pulses per camera, alone and as a pair
  4. 04Worked example: 100 Hz for 10 s on a primary and a secondary
  5. 05The fix: make the role map match the trigger plan
  6. 06When one camera per process is the answer
  7. 07Checks before you scale past two cameras
  8. 08The decision, case by case
  9. 09Questions

You open two event cameras in one process, arm the external trigger, and each camera delivers exactly one ExtTrigger event. The pulse train keeps running and nothing further arrives. Two separate executables seem to bring the callbacks back, which makes the SDK's process handling look guilty. Before you restructure the application, work through the tests below. They separate the common cause — a primary/secondary sync role that has quietly claimed the trigger line — from real shared-resource trouble between two SDK instances. You finish with a count per camera per run and a decision: re-map the roles, or commit to one camera per process and merge the recordings afterwards.

The symptom and why it points the wrong way

The signature is specific. The first pulse produces an ExtTrigger event; every later pulse produces nothing, on one camera or on both. Trigger-out still pulses, the cable tests fine, and the configuration reads back exactly as set. Because the failure first appears when the second camera joins the process, a global handle or a shared static inside the SDK is the natural first suspect.

The suspicion rarely survives a controlled repeat. Run the same pulse test with one camera per process and the silence follows the camera, not the layout. That clears the address space and puts the sync roles on the bench. Primary and secondary exist to align event timestamps, so assuming they leave trigger delivery alone is reasonable — and wrong. Once the roles are set, the shared line carries sync traffic, and the primary no longer consumes its trigger input as a trigger source.

Likely causes, most probable first

  1. A sync role has claimed the trigger line. The camera set as primary drives the shared line for clock synchronization; secondaries consume it. Loopback testing then fires trigger-in events on the secondary and none on the primary. Check this first: it matches the one-then-silence signature exactly.
  2. Trigger configuration applied to one handle only. The second camera opened with defaults and its trigger-in never armed. Frame cameras carry the same trap in their free-run default, as covered in hardware trigger configuration per camera: stop the free-run default.
  3. The pulse itself. Level, polarity or a missing common ground fails in every process layout, which is what separates it from the causes above. If the train comes from a PLC output rather than the partner camera, industrial camera PLC external trigger solutions covers the camera-side trigger options and wiring.
  4. Genuine contention between two SDK instances in one address space. The rarest of the four, and it does not look like this. A starved instance drops event data or shows timestamp gaps; trigger-in is latched in hardware and does not ride the event stream, and each camera on its own USB 3 link has dedicated wire bandwidth in any case.

Test 1: count pulses per camera, alone and as a pair

  1. Drive a counted pulse train into the camera under test — a signal generator, or that camera's own trigger-out with its trigger input set to loopback.
  2. Log the trigger-in events for a fixed run and compare the count with the number of pulses sent.
  3. Repeat with both cameras open in one process.
  4. Repeat with one camera per process: same train, same duration, same roles.
  5. Read the count against the table below.
Count across layouts Cause Fix
Full count as a secondary, near zero as the primary, same in both layouts Sync role claims the line Re-map roles; keep consumers on secondary
Full count only in separate processes SDK instance contention One camera per process, merge afterwards
Low count in every layout Pulse wiring or trigger mode Scope the pulse, arm trigger-in on every handle

A camera that passes alone and fails once the pair is cabled for sync is the role case. A camera that changes behavior only in the single-process build is the contention case, and splitting the processes is then the real fix, not a workaround.

Worked example: 100 Hz for 10 s on a primary and a secondary

The inputs, and where each comes from: two event cameras on one host, each on its own USB 3 link, with the connection probe reporting 5,000 Mbit/s per camera (the diagnosed pair); camera A assigned primary, camera B secondary, the two cabled for clock sync; a 100 Hz, 10 s pulse train from the bench generator, chosen so the expected count is too large to miss; camera B's trigger input on loopback.

The rule in words: expected events per camera equal the pulse rate multiplied by the run time.

E = pulse rate × run time E = 100 pulses/s × 10 s = 1,000 events per camera

Observed: camera B, the secondary, logs 1,000 events — 1,000 / 1,000 = 100 % delivery. Camera A, the primary, logs 1 event — 1 / 1,000 = 0.1 %. Repeat the run with both cameras in separate processes: A still logs 1. The process layout never moved the number.

The decision, with its threshold: a camera passes at 990 or more of 1,000 expected events, a 1 % margin that absorbs edge artifacts at the pulse transitions. A camera at 1 of 1,000 is not consuming the line at all. With the cable and the trigger mode verified, that leaves the sync role: A's trigger input is on clock duty. Make B, the secondary, the trigger consumer, or take A out of cable sync and run it in its own process with timestamps aligned in software.

The fix: make the role map match the trigger plan

Decide in writing which camera drives and which consumes, then assign the roles to match.

When one camera per process is the answer

The single recording file that pulled both cameras into one process is still achievable. Each process opens its own device by serial number, writes its own stream, and a merge step joins the takes with timestamps aligned in software. Each process then owns its callbacks outright, and the architecture takes a third and fourth camera without reopening the question. The failure mode to watch is the opposite one: two processes, roles still assigned, and one camera quietly carrying a primary role nobody re-checked after the last cabling change.

Checks before you scale past two cameras

  • Run the counted pulse test after every role, firmware or cabling change, and log expected versus actual counts per camera in the run metadata.
  • Record each camera's firmware build beside its results. The diagnosed pair ran two different builds and the roles still explained the silence; the recorded builds are what let you rule firmware out on paper months later.
  • Keep a written serial-to-role map with the cell documentation; enumeration order is not an identity.
  • On a mixed line, arm trigger-in on every handle you open. Frame cameras boot into free-run and ignore the trigger until the acquisition mode is switched, which reads as the same silence.

The decision, case by case

  • The camera that must consume pulses is the sync primary. Re-map: consumers take secondary, the driver keeps primary, and the counted pulse run confirms it before wiring day.
  • Behavior differs only in the single-process build. The SDK instances genuinely contend. Commit to one camera per process and merge the recordings.
  • The camera under-counts in every layout. The pulse line or the trigger mode is at fault. Scope the pulse and arm trigger-in on every handle.

Planning the rig rather than debugging one? Start from the 3D sensors category, narrow the choice in the 3D camera finder, and the 3D topic page collects the other multi-camera timing fixes. If the trigger plan still reads ambiguously, send it through the contact page before the cable goes in.

Questions

Is this caused by a bug in the camera SDK?

Rarely. The one-event-then-silence signature matches a sync role claim on the trigger line, and that reproduces across process layouts. A genuine SDK defect is still possible: if the counted pulse run shows full counts with one camera per process and silence only when two instances share one process, you have a clean reproduction — device serials, SDK build, pulse rate and logged counts — that a maintainable bug report needs.

Can both cameras deliver trigger-in events in one synced pair?

Only the consumers. In a synced pair one camera takes the primary role to drive clock synchronization and the others take secondary on the same line, so plan every external pulse to arrive at a secondary. If the application needs trigger-in events on the clock primary itself, take that camera out of cable sync, run it in its own process, and align timestamps in software during the merge.

What count should a healthy camera log, and what do low counts mean?

One event per pulse, at any rate: a 1 kHz train run for 1 s expects 1,000 events, just as 100 Hz for 10 s does. A count a few percent low points at signal quality on the pulse line. A count in single digits while the train runs means the camera is not consuming the line at all, so look at the sync role, the trigger mode or the callback registration.

Why does opening each camera by serial number matter for triggers?

Role settings follow the device, so which physical camera ends up as primary must not depend on USB enumeration order, which can swap after a reboot or a hub change. Open each camera by its serial number and keep a written serial-to-role map with the cell documentation. The counted pulse test after any reboot then catches a swapped role in minutes instead of costing a shift of silence.

Do the two cameras need matching firmware before the trigger test means anything?

No. The silence in the diagnosed pair reproduced across process layouts with the cameras on builds 2.2.0 and 2.1.4, so the roles explained it with mixed firmware installed. Record each build next to every test result anyway: matching builds remove one variable, and a build noted beside a passing or failing count is what separates a role change from a firmware change weeks later.