3D visionHow-to

Sync a depth camera and a third-party camera on one external pulse

Wire one external sync pulse generator to a depth camera and a third-party camera: pulse width, level shifting, exposure timing and verification steps.

LumaSpec Vision11 min read Share on LinkedIn

On this page 11 sections
  1. 01Master camera or external generator: the one-step decision
  2. 02The pulse: positive, 100 µs wide, one per frame
  3. 03What you need
  4. 04Wire the pulse to both cameras
  5. 05Set frame rate and exposure inside the pulse window
  6. 06Worked example: 30 fps depth camera plus 12 MP camera over a conveyor
  7. 07Verify the sync before you trust it
  8. 08Common mistakes
  9. 09When one pulse is not enough
  10. 10Before the first run
  11. 11Questions

Two free-running cameras will not stay aligned. Each has its own clock, and the depth-to-image registration you calibrated slips as the frame periods drift apart: a bandwidth-limited camera running at 29.9 instead of 30 fps loses a full frame every ten seconds. The fix for a mixed rig is one shared pulse — an external sync pulse generator sends the same short edge to every camera, and each camera starts its frame on that edge. This how-to gives you the documented pulse specification, the wiring and level shifting, the exposure budget, and a verification procedure you can run in an afternoon. It is written for the mixed case, a depth camera plus another maker's depth camera or a 2D area camera, where a master/slave sync bus cannot reach.

Master camera or external generator: the one-step decision

If every depth camera in the rig belongs to one family, use that family's master/slave scheme: designate one camera as the master, set the rest as slaves, and they share timing over a short sync bus. Some vendors call this mode genlock. It needs no extra hardware and it is the documented path for same-family rigs.

A third-party camera breaks the scheme, because it does not speak the master's sync protocol. The dependable answer for a mixed rig is an external generator feeding every camera in parallel: the 3D sensors on the depth side, the area scan cameras on the 2D side, one pulse line touching both. A generator also survives camera swaps — replace either camera later and the wiring does not change.

The simpler cousin of this job, two cameras of the same connector family, is covered in the two-USB-camera hardware sync guide; this recipe adds level shifting and a foreign protocol. Depth cameras in these rigs fall into three classes — projected structured light, time-of-flight and laser-galvanometer stereo:

3D sensorsHikrobot MV-DPS200P-02 Projected structured-light 3D cameraMV-DPS200P-02
Type
Stereo / structured light
$8,829.00 · quotedView and quote
3D sensorsHikrobot MV-DT01WMU ToF sensing cameraMV-DT01WMU
Type
Depth / ToF camera
Price on requestView and quote
3D sensorsHikrobot MV-DLS300P-04 Laser galvanometer stereo cameraMV-DLS300P-04
Type
Stereo / structured light
$16,579.00 · quotedView and quote

The pulse: positive, 100 µs wide, one per frame

The depth camera's external-synchronization specification defines the signal: a positive-going pulse 100 µs wide, issued at the nominal frame rate. At 30 fps that is one pulse every 33.33 ms, and the duty cycle works out to 0.1 ms ÷ 33.33 ms = 0.3%. At 15 fps the period stretches to 66.67 ms and the pulse width stays 100 µs.

T = 1 / fps duty = pulse_width / T

Keep the pulse short. A 10 ms pulse at 30 fps is already 30% duty, which squeezes the quiet gap before the next edge and invites double-triggering on a noisy line. The 100 µs width also sits comfortably inside what a machine-vision trigger input accepts.

The depth camera's functional specification names the pulse input HW SYNC; its VSYNC signal marks the start of the stereo frame sent to the host, which is the camera's output rather than the pulse you drive. The generator contract follows: 30 Hz, positive-going, 100 µs wide, driven at 3.3 V logic — the common level for these inputs, and the one to target unless an I/O table says otherwise.

What you need

  • A pulse source: a bench pulse generator at 30 Hz, a microcontroller board driving a hardware timer pin (use the timer peripheral, not a software delay loop — interrupt load jitters the edge), or a frame grabber generating the pulse train itself.
  • A PLC works too, but ladder logic quantizes pulse width to the scan time, so build it as a dedicated one-shot pulse, not a timed bit.
  • Level shifting when the source is 5 V and the input is 3.3 V: two resistors or a logic buffer chip.
  • Shielded cable for the pulse line, shield tied to ground at the generator end.
  • An oscilloscope or logic analyzer for a one-time check of width, level and period.
  • The depth camera set to its external sync mode, and a 2D camera with a hardware trigger input — hardware-triggered frame rates follow the pulse train exactly.

On the 2D side, prefer a global-shutter sensor: it exposes the whole frame at one instant, which is what a shared pulse assumes. An example of the class, 12 MP on a 1.1-inch global-shutter IMX304 sensor over USB3:

Area scan camerasHikrobot MV-CH120-11UC 12 MP Area Scan Camera, USB3, IMX304, High-speed version, ColorMV-CH120-11UC
Sensor format
1.1"
Lens mount
C-mount
Interface
USB3
Resolution
12 MP
$2,339.00 · quotedView and quoteBuild a system with it

Any global-shutter model in the camera finder suits the same wiring; resolution is irrelevant to the pulse.

Wire the pulse to both cameras

  1. Set the drive level. A 3.3 V generator output connects directly. From a 5 V source, divide down: a 1.8 kΩ series resistor into a 3.3 kΩ resistor to ground gives 5 V × 3.3 kΩ ÷ (1.8 kΩ + 3.3 kΩ) = 3.24 V at the camera end.
  2. Run one line per camera. Generator output to the depth camera's sync input, and a second line to the 2D camera's trigger input. Star the grounds: generator ground to both cameras' I/O grounds, not daisy-chained through the first camera's chassis.
  3. Fan out within reason. Two 10 kΩ inputs in parallel load a generator output negligibly — 5 kΩ against a 50 Ω source impedance drops the level about 1%. Beyond three or four cameras, buffer the line with a logic gate or a trigger splitter.
  4. Match the edge. Set each camera's trigger activation to rising edge for a positive pulse into a logic input. Opto-isolated inputs trigger on current flow, so polarity follows the camera's I/O drawing, not habit.
  5. Scope it at the camera connector. Confirm 3.3 V peak, 100 µs width, one pulse every 33.33 ms over ten seconds of screen time — ground-loop noise hides from a single-shot screenshot.

If both cameras hang off one frame grabber, its simultaneous two-camera trigger output replaces the external generator.

Set frame rate and exposure inside the pulse window

Put the depth camera in external sync mode and set the generator to its nominal frame rate — 30 Hz for a 30 fps camera. Put the 2D camera in hardware-trigger mode so its exposure starts on the same edge. The budget is then arithmetic: exposure plus readout must fit inside the 33.33 ms frame window, so keep exposure at or under half the period, 16.7 ms at 30 fps, unless you have measured the camera's readout overlap.

Motion decides exposure long before the window does. At a 150 mm/s conveyor, a 1 ms exposure smears the image by 150 mm/s × 1 ms = 0.15 mm — the number the worked example below budgets.

Keep the depth camera's exposure comfortably inside its frame too: depth cameras cap or drop their frame rate when exposure runs long, the exposure-capped FPS failure. And after any exposure change, expect the new value a frame later than intuition suggests — the two-capture behaviour after a parameter change explains why.

Strobing instead of running continuous light? Fire the light from the generator's second channel inside the 2D exposure, following the same exposure-time-as-shutter pattern that keeps a depth camera and a flash in step.

Worked example: 30 fps depth camera plus 12 MP camera over a conveyor

The rig: a stereo depth camera at 30 fps, a 12 MP global-shutter camera watching the same parts, a conveyor at 150 mm/s, a pixel scale of 0.2 mm per pixel, and an alignment tolerance of 0.2 mm.

T = 1 / 30 = 33.33 ms duty = 0.1 ms / 33.33 ms = 0.3% blur = 150 mm/s × 1 ms = 0.15 mm = 0.75 px skew budget = 0.2 mm ÷ 150 mm/s = 1.33 ms

Settings that follow: generator at 30 Hz, 3.3 V positive pulses 100 µs wide. The 2D exposure at 1 ms gives 0.15 mm of blur, under one pixel. The depth exposure at 6 ms, an example value for indoor structured light, leaves 27.33 ms of the window for readout and transfer. Both cameras start integrating on the same rising edge, and the 2D camera's trigger-to-exposure latency is typically under 0.1 ms.

Every margin holds: blur sits at 0.75 px against a 1 px target, and start-up skew is roughly a tenth of the 1.33 ms budget. Speed the conveyor to 300 mm/s and the recipe adapts rather than breaks: drop the exposure to 0.5 ms (blur back to 0.15 mm), and the skew budget becomes 0.2 mm ÷ 300 mm/s = 0.67 ms, still about seven times the trigger latency. At 600 mm/s the exposure is down to 0.25 ms and the job moves to a strobe or to line scan.

Verify the sync before you trust it

  1. Count frames, not timestamps. Stream both cameras for ten minutes: 30 fps × 600 s = 18,000 pulses, so each camera owes exactly 18,000 frames. One frame missing on either side means a swallowed pulse — go back to the scope, not the software.
  2. Recognize the free-running signature. Two cameras at 30.00 and 29.90 fps drift 0.11 ms per frame: a full 33 ms frame every ten seconds, about 12 s apart after an hour. If your logs show that staircase, the trigger line is not actually in control.
  3. Overlay a moving part. Project the depth frame into the 2D image — the depth-to-RGB extrinsics fix covers the calibration — and confirm a part at 150 mm/s lands within the 0.2 mm budget, one pixel.
  4. Break it on purpose. Stop the generator for a second and restart. Both cameras must resume on the next edge with no error latched; if the depth camera needs a mode change to re-arm, better to learn that at the bench than in production.

If calibration quality dropped after wiring the trigger, suspect a doubled edge before anything exotic — the trigger wiring that degrades calibration walks that failure down.

Common mistakes

  • A wide pulse. 10 ms at 30 fps is 30% duty against the documented 0.3%; the quiet gap shrinks and marginal wiring starts double-triggering.
  • Software-trigger fan-out. Broadcasting a capture command over USB or GigE reaches cameras milliseconds apart. That is clock skew, not sync; the hardware line is the whole point.
  • No common ground. A pulse referenced to a floating generator ground double-triggers or never triggers; star every I/O ground back to the generator.
  • 5 V into a 3.3 V input. The divider in step 1 costs two resistors; an overstressed input costs a camera.
  • A rolling-shutter camera in the strobed path. It exposes line by line, so a short flash bands the image; use a global-shutter sensor wherever a pulse or strobe defines the exposure.
  • Reading the frame before the new exposure applies. After a depth-camera setting change the old value still governs the next frame, as the two-capture behaviour above explains.
  • Trusting host arrival timestamps. Buffering reorders frames; compare frame IDs captured under the same pulse count.

When one pulse is not enough

  • The light needs 50 µs inside a 1 ms exposure: use the generator's second channel with a programmed delay, referenced to the same edge the 2D camera sees.
  • The whole rig turns out to be one depth-camera family: drop the generator and use the master/slave bus — one fewer box and nothing to rewire when a camera moves.
  • The web never stops: for continuous moving-web inspection the pulse-per-frame model gives way to encoder-driven line scan, and the area-scan camera in line-scan mode is the pattern to copy.
  • The 2D frame should land a fixed offset after the depth frame: a second channel with that delay does it, and the same verification steps apply.

Before the first run

  • Pulse: 100 µs, positive, one per frame at the depth camera's nominal rate (33.33 ms period at 30 fps) — the documented input contract, and wider pulses trade margin for nothing.
  • Level: 3.3 V at the camera connector, divider fitted if the source is 5 V — overstressed inputs fail weeks later, not at first light.
  • Grounds: generator and both camera I/O grounds starred together — ground loops masquerade as double triggers.
  • Modes: depth camera in external sync, 2D camera in hardware trigger, both activation edges matching the pulse — a camera left in free-run silently ignores the line.
  • Exposure: the 2D exposure inside the motion budget, the depth exposure inside the frame window — the worked example's margins only hold if exposure stays put.
  • Scope check at the camera end: width, level, period — the generator's front panel is not the camera's connector.
  • Frame-count run: 18,000 frames from each camera over ten minutes — frame counts are the one timestamp that never lies.
  • Drive circuit: one line of each camera's I/O table read against your wiring — the input type decides drive level and polarity.

The whole integration is two resistors and one disciplined pulse. The rest of the station — trigger cable, splitter, the controller that hosts both streams — comes together in the trigger step of the configurator:

Build the whole station

The configurator matches a camera, lens, light, light controller and cables to each other, step by step, and lists only parts that fit what you already picked.

Start with the trigger sensor

For more timing and integration fixes in mixed rigs, the 3D vision topic collects the guides this one builds on.

Questions

How accurate does the sync generator's frequency need to be?

A quartz-based generator is accurate to tens of parts per million, so a 33.33 ms period drifts by about 1.7 µs — far inside the 100 µs pulse. Accuracy hardly matters anyway: both cameras follow the same pulses, so a slow clock retards both streams together and their alignment is unaffected. What matters is that neither camera free-runs on its own oscillator.

Can the depth camera be the master and the third-party camera the slave?

Within one depth-camera family, yes: the maker's scheme designates one camera master and the others slaves on a short sync bus. Across makers it is not guaranteed — the sync-out level, polarity and timing are specified for its own slaves. If the third camera's trigger input happens to accept that signal exactly, it can work; otherwise run a shared external generator.

Why not use a media timecode sync box for this?

Timecode boxes emit a continuous timecode waveform aimed at audio and video recorders, not a single clean frame-start pulse. A camera trigger input wants one short logic edge per frame at the frame period. A pulse or function generator, a microcontroller timer output or a frame grabber's trigger output produces exactly that; a timecode box does not.

What happens if the pulse is too wide or too narrow?

Too narrow and some opto-isolated inputs may never register the edge — their minimum is often a few microseconds, so stay near the documented 100 µs. Too wide and the pulse eats the frame budget: 10 ms at 30 fps is already 30% duty, leaves less quiet time before the next edge, and raises the odds of a camera reacting twice.

Can the 2D camera run at a different frame rate than the depth camera?

Yes. The pulses define the tempo, and a camera may act on every pulse or a divider of them. A 15 fps 2D camera triggered on every second pulse in a 30 Hz rig still lands each of its frames on a depth frame — it just skips alternate depth frames. Never the reverse: the depth camera needs a pulse at its nominal frame rate.