Three synchronized CSI camera modules for Jetson Orin multi-camera hardware trigger synchronization setup
jetsonmulti-cameracsiframe synctriggersynchronizationv4l2

Multi-camera synchronization on Jetson: CSI, frame sync, triggers

Andres Campos ·

Running multiple CSI cameras on Jetson simultaneously is straightforward — the hardware supports it natively. Synchronizing them so frames align within a millisecond requires hardware trigger synchronization. Software timestamp comparison introduces too much jitter for stereo vision or surround-view applications. This post covers the full synchronization setup.

Key Insights

  • Hardware trigger sync is the only reliable method for multi-camera synchronization on Jetson — software sync has too much jitter for stereo or surround-view
  • The sync signal comes from a Jetson GPIO (or external source) to each sensor’s trigger input — not from Jetson to the NVCSI
  • Both sensors must be in external trigger mode, not free-running, or trigger sync does not override the internal frame timer
  • NVCSI captures multiple streams in parallel by hardware — the synchronization problem is at the sensor output, not at capture
  • A consistent frame offset (not jitter) points to trigger edge polarity mismatch, not a timing problem

Why free-running sync fails

The most common multi-camera “synchronization” approach is running both cameras at the same frame rate setting and timestamping frames as they arrive. This fails for any application requiring real synchronization.

Here is why: camera sensors use internal oscillators to time their frame rate. These oscillators have frequency tolerance — typically ±100-300 ppm for a standard crystal. Two cameras at 30 fps nominal might run at 30.002 fps and 29.998 fps. That 4 ms/second drift means the cameras are a full frame apart within 4 seconds of running. For stereo depth estimation, this is completely unacceptable.

Software timestamp comparison is also unreliable. The timestamp is applied when the frame arrives at the V4L2 buffer, which depends on interrupt latency and task scheduling. Jitter of 5–30 ms is typical.

Hardware trigger sync solves both problems by forcing every camera to expose on a common hardware edge. The sensors do not free-run — they wait for the trigger pulse.

Hardware trigger sync setup

The physical connection: a Jetson GPIO drives a sync pulse to the trigger input of each sensor. For CSI cameras, this is usually a direct GPIO connection via the carrier board.

Jetson GPIO (e.g., TEGRA234_AON_GPIO(BB, 2))
  ├── Sensor 0 trigger input (e.g., XVS or TRIGGER pin)
  └── Sensor 1 trigger input

The GPIO is configured as a PWM output at the target frame rate (33.33 ms period for 30 fps), or driven manually for triggered-on-demand capture.

In the sensor driver, switch the sensor from free-running to external trigger mode:

/* Put sensor in external trigger mode */
static int sensor_set_trigger_mode(struct camera_common_data *s_data)
{
    /* Register address and value depend on your sensor */
    /* For IMX477: write to trigger mode register */
    return sensor_write_reg(s_data->client,
                            SENSOR_TRIGGER_MODE_REG,
                            SENSOR_TRIGGER_EXTERNAL);
}

In the DTS, declare the sync GPIO:

imx477@10 {
    /* ... */
    trigger-gpios = <&tegra_aon_gpio TEGRA234_AON_GPIO(BB, 2) GPIO_ACTIVE_HIGH>;
    nvidia,trigger-mode = "external";
};

imx477@11 {
    /* ... same GPIO reference ... */
    trigger-gpios = <&tegra_aon_gpio TEGRA234_AON_GPIO(BB, 2) GPIO_ACTIVE_HIGH>;
    nvidia,trigger-mode = "external";
};

Both sensors reference the same GPIO. When the GPIO fires, both sensors expose simultaneously.

Multi-camera pipeline on Jetson

With synchronized sensors, the Jetson pipeline handles multiple streams in hardware in parallel:

Sensor 0 → NVCSI port 0 → VI → /dev/video0
Sensor 1 → NVCSI port 1 → VI → /dev/video1

The VI captures both streams independently. In a GStreamer pipeline, both streams can run concurrently within a single process (avoid separate processes — see nvvidconv performance collapse with multiple GStreamer processes on Jetson):

gst-launch-1.0 \
  nvarguscamerasrc sensor-id=0 ! \
    'video/x-raw(memory:NVMM),width=1920,height=1080' ! \
    queue ! comp.sink_0 \
  nvarguscamerasrc sensor-id=1 ! \
    'video/x-raw(memory:NVMM),width=1920,height=1080' ! \
    queue ! comp.sink_1 \
  nvmultistreamtiler name=comp rows=1 columns=2 \
    width=3840 height=1080 ! \
  nvvidconv ! nvoverlaysink

The queue elements decouple the two sensor pipelines so a slow frame from one sensor does not stall the other.

Verifying synchronization

After enabling hardware trigger sync, verify that frames from both sensors arrive within the expected window:

# Capture frames with timestamps from both sensors simultaneously
v4l2-ctl --stream-mmap -d /dev/video0 --count=10 -v 2>&1 | grep "ts:" > /tmp/cam0_ts.txt &
v4l2-ctl --stream-mmap -d /dev/video1 --count=10 -v 2>&1 | grep "ts:" > /tmp/cam1_ts.txt &
wait

# Compare timestamps
paste /tmp/cam0_ts.txt /tmp/cam1_ts.txt
# Hardware sync: timestamps should differ by < 1ms per frame
# Software sync / no sync: timestamps drift several ms per frame

For GMSL2 multi-camera synchronization which uses the FSYNC signal over the GMSL2 control channel instead of a direct GPIO, see Synchronizing multiple GMSL2 cameras on Jetson Orin.

The Linux V4L2 timestamp documentation is at kernel.org. NVIDIA’s multi-camera pipeline guidance is in the Jetson Linux Accelerated GStreamer User Guide.

NVIDIA Jetson Expert Support

Stuck on a Jetson bring-up?

We've debugged this failure mode before. BSP, device tree, camera pipelines, OTA — most blockers clear in the first session. No long retainers. No guessing.

Frequently Asked Questions

Can Jetson Orin capture from multiple CSI cameras simultaneously?

Yes. Jetson Orin has 6 NVCSI ports (AGX Orin) or 4 (Orin NX), each capable of independent capture. Multiple cameras can stream simultaneously to separate V4L2 video nodes. The capture itself is parallel in hardware — the bottleneck is usually the downstream pipeline (GStreamer, Argus, inference) not the NVCSI.

What is the best way to synchronize two CSI cameras on Jetson for stereo vision?

Hardware trigger synchronization using the sensor's external trigger input. A Jetson GPIO generates a sync pulse at the desired frame rate. The DTS configures both sensors to use external trigger mode via their trigger input pins. Both sensors capture on the same pulse edge. This gives sub-millisecond synchronization. Software sync (timestamping frames as they arrive) introduces 5–30 ms of jitter from interrupt latency and scheduling.

How do I set up hardware frame sync for multiple CSI cameras on Jetson?

Configure a Jetson GPIO as PWM output at your target frame rate (e.g., 30Hz = 33ms period). Route this GPIO to each sensor's trigger input pin. In the sensor driver, write the register that puts the sensor in external trigger mode. In the DTS, declare the trigger GPIO and trigger mode for each sensor node. The sensor should output one frame per trigger edge, eliminating free-running clock drift.

What is the FRSYNC signal on Jetson and how does it relate to camera sync?

FRSYNC (Frame Sync) is a Jetson signal routed through the NVCSI hardware that can synchronize frame capture across multiple CSI ports. It is exposed via GPIO and can be used as the hardware trigger for connected sensors. On AGX Orin, certain NVCSI port pairs share a FRSYNC signal. Check the Orin TRM for which ports can be synchronized via FRSYNC vs. requiring an external GPIO-based approach.

My two synchronized CSI cameras have a consistent 1-2 frame offset. What is wrong?

A consistent frame offset with hardware trigger sync usually means one sensor is configured for rising-edge trigger and the other for falling-edge, or the trigger GPIO has different propagation delay to each sensor due to PCB routing differences. Check the trigger edge polarity register setting on each sensor — both must be identical. Also check whether the NVCSI captures from both sensors in the same interrupt cycle.

Andrés Campos, Co-Founder & CTO at ProventusNova

Written by

Andrés Campos

Co-Founder & CTO · ProventusNova

8 years deep in embedded systems — from underwater ROVs to edge AI. Andrés leads every technical delivery personally.

Connect on LinkedIn