---
title: "Using Multiple Cameras"
description: "Several cameras with one LumiScan Cam Driver - switch and port layout, and how a software or hardware trigger keeps two cameras from transmitting at once."
product: "LumiScan Cam Driver"
component: "lumiscan-cam-driver"
version: "2.2.1"
display_version: "2.2.1.12"
latest_version: true
language: "en"
url: "https://docs.hdvisionsystems.com/en/lumiscan-cam-driver/lumiscan-camdriver/using-multiple-cameras.html"
---

# Using Multiple Cameras – LumiScan Cam Driver

From v2.0.0, one installation can operate several cameras. Each camera is a module with its own configuration file and its own address on the Data Layer, and each connected camera needs its own licence. See [Creating New Camera Settings Files](https://docs.hdvisionsystems.com/en/lumiscan-cam-driver/lumiscan-camdriver/creating-new-camera-settings-files.html).

What several cameras add to a single-camera installation is a shared resource: they all send their images over one network link into one port of the device that runs the Cam Driver. That link is what limits them. This page describes how to lay out the network, and how to make sure that two cameras never transmit an image at the same time.

## Why Several Cameras Need Planning {#why-planning-is-needed}

A GigE Vision camera does not spread an image over the time until the next one. It sends the whole image as a burst of UDP packets at the full line rate of the link, and then stays quiet. A 1 Gbit/s link carries one such burst at a time.

If a second camera starts its burst while the first one is still running, the switch and the network port of the host are offered more data than they can forward. The surplus packets are dropped. GigE Vision has no retransmission that can recover a whole burst, so the image arrives incomplete, and the Cam Driver discards it:

- `control/status/code` is `-10004` (`couldNotCaptureImage`), and through the handshake `capture/ready` stays `false` until a `reset` succeeds.
- The log contains a line such as `Error: Image is incomplete with filled size 1076592 / 1259712 = 85 %`.

One camera on its own has the link to itself and rarely shows this. That is why an installation that works with one camera can fail as soon as a second one is added, with no change to the cameras, the cabling or the lighting.

Two measures prevent it, and both are needed:

1. The link carries camera traffic only - see [Hardware Setup](https://docs.hdvisionsystems.com/en/lumiscan-cam-driver/lumiscan-camdriver/using-multiple-cameras.html#hardware-setup).
2. The cameras do not transmit at the same time - see [Trigger Source](https://docs.hdvisionsystems.com/en/lumiscan-cam-driver/lumiscan-camdriver/using-multiple-cameras.html#trigger-source). How you achieve this depends on your trigger source.

## Hardware Setup {#hardware-setup}

### Switch and Cables {#switch-and-cables}

- **Jumbo frames:** The switch, every cable path and the network port of the host must support jumbo frames, and the MTU size must be set to 8000 or 9000 on every device in the path. A large packet carries about six times as much image data per packet as the 1500-byte default, which reduces the per-packet overhead and the number of packets that can be lost. Set the Cam Driver’s `packetSize` to match the MTU size that the path actually supports; a packet larger than the smallest MTU in the path is dropped. See [MTU Size Change](https://docs.hdvisionsystems.com/en/lumiscan-cam-driver/lumiscan-camdriver/initializing-the-camera.html#mtu-size-change).
- **Link speed:** Use 1 Gbit/s or faster on every port. The host port is the bottleneck, because all cameras share it.
- **Cables:** Use "Foil Shielded Twisted Pair" cables. In a cabinet, poor shielding shows up as occasional incomplete images that look exactly like a bandwidth problem.

### Keep PLC Traffic Off the Camera Network {#separate-plc-traffic}

Use a switch that carries camera traffic only: the cameras, and the one port of the host that the Cam Driver receives images on. Connect the PLC, the fieldbus and the rest of the plant network to a different port of the host.

This matters in both directions:

- An image burst fills the link completely for the few milliseconds it lasts. Anything else sharing that link is delayed for that time, which is poison for a real-time or cyclic protocol.
- Conversely, every frame the plant network puts on the camera link is bandwidth that is no longer available to the burst, which makes incomplete images more likely.

## Trigger Source {#trigger-source}

The cameras must not transmit at the same time. How you arrange that depends on what triggers them.

| Trigger source | What to do |
| --- | --- |
| Software trigger (`capture`) | Capture one camera after another, and start the next camera only after the previous image has arrived. See [Software Trigger: One Camera After Another](https://docs.hdvisionsystems.com/en/lumiscan-cam-driver/lumiscan-camdriver/using-multiple-cameras.html#software-trigger). |
| Hardware trigger | All cameras are exposed at the same moment by design, so the cameras themselves must interleave their packets. Calculate and set `GevSCPD` and `GevSCFTD`. See [Hardware Trigger: Share the Bandwidth Between the Cameras](https://docs.hdvisionsystems.com/en/lumiscan-cam-driver/lumiscan-camdriver/using-multiple-cameras.html#hardware-trigger). |

### Software Trigger: One Camera After Another {#software-trigger}

The Cam Driver has no synchronised multi-camera trigger. Every module triggers its own camera when its own request arrives, so it is the client that decides when each camera transmits - and the client must put the captures in sequence.

> [!IMPORTANT]
> Never run the capture handshakes of two cameras so that both cameras transmit at once. A capture must be finished before the next camera is told to capture.

A capture starts when `capture/request` falls back to `false`, and it is finished when `capture/ready` returns to `true`. Two cameras can therefore be armed together and released one after the other:

1. Set `camera1` `capture/request` to `true`.
2. Wait until `camera1` `capture/ready` is `false`.
3. Set `camera2` `capture/request` to `true`.
4. Wait until `camera2` `capture/ready` is `false`.
5. Set `camera1` `capture/request` to `false`. Camera 1 now exposes and transmits.
6. Wait until `camera1` `capture/ready` is `true` again. The image of camera 1 has arrived and the link is free.
7. Set `camera2` `capture/request` to `false`. Camera 2 now exposes and transmits.
8. Wait until `camera2` `capture/ready` is `true` again.

**Two cameras captured one after another**

```mermaid
%% Two cameras captured one after another with the software trigger. Rendered by Mermaid in the browser; edit and preview at https://mermaid.live
sequenceDiagram
  autonumber
  participant C as Client (PLC or program)
  participant M1 as Module camera1
  participant M2 as Module camera2
  M1-->>C: capture/ready = true
  M2-->>C: capture/ready = true
  C->>M1: camera1 capture/request = true
  M1-->>C: camera1 capture/ready = false
  C->>M2: camera2 capture/request = true
  M2-->>C: camera2 capture/ready = false
  C->>M1: camera1 capture/request = false
  Note over M1: camera 1 exposes and transmits<br/>the link carries this image alone
  M1-->>C: camera1 capture/ready = true
  C->>M2: camera2 capture/request = false
  Note over M2: camera 2 exposes and transmits<br/>the link carries this image alone
  M2-->>C: camera2 capture/ready = true
```

With more than two cameras, extend the same pattern: arm all of them, then release and await them one at a time.

> [!NOTE]
> This sequence needs the default `handshakeEdge` setting, `FALLING_EDGE`. With `RISING_EDGE` a capture starts as soon as `capture/request` is `true`, so arming a camera already makes it transmit. Then run one complete capture handshake per camera instead: wait until its `capture/ready` is `true` again before you set the next camera’s `capture/request`. See [When a Functionality Runs](https://docs.hdvisionsystems.com/en/lumiscan-cam-driver/lumiscan-camdriver/general-concept-of-handshake.html#when-a-functionality-runs).

If you use the `execute` method instead of the handshake, the rule is the same and simpler to follow: `<camera name>/control/capture/execute` returns only when the capture has finished, so call it for one camera, wait for it to return, and only then call it for the next. Do not call `capture/execute` for several cameras in parallel. See [Execute a Method](https://docs.hdvisionsystems.com/en/lumiscan-cam-driver/lumiscan-camdriver/execute-a-method.html).

> [!NOTE]
> Captures that follow one another cost more time than captures that overlap. If the cycle time is not sufficient, use a hardware trigger with the bandwidth settings below: the cameras then expose at the same moment and only the transmission is spread out.

### Hardware Trigger: Share the Bandwidth Between the Cameras {#hardware-trigger}

With a hardware trigger, all cameras are exposed at the same moment - that is usually the reason for using one - so the captures cannot be put in sequence. Instead, the transmissions are interleaved: every camera leaves a gap between its own packets that is large enough for the other cameras' packets, and every camera starts at a different moment, so the packets of the cameras alternate on the link instead of colliding.

Two GigE Vision features do this. Both are camera features, not Cam Driver settings:

| Feature | Meaning |
| --- | --- |
| `GevSCPD` | Packet delay. The gap the camera leaves between two packets of the same image. |
| `GevSCFTD` | Frame transmission delay. How long the camera waits, after it is ready to transmit, before it sends the first packet. This is what staggers the cameras against each other. |

#### Step 1: Time for One Packet {#calculate-the-packet-time}

First work out how long one packet occupies the link.

```
bytes per second    = link speed / 8
time per byte       = 1 s / bytes per second
packet on the wire  = packetSize + Ethernet overhead
packet time         = packet on the wire x time per byte
P                   = packet time + buffer      (buffer: 10 % to 30 % of packet time)
```

The buffer absorbs the remaining framing overhead and the switch’s own latency. Values below it leave no margin, values far above it waste bandwidth.

For a 1 Gbit/s link and `packetSize` 9000:

| Quantity | Value |
| --- | --- |
| Link speed | 1 Gbit/s = 125,000,000 bytes/s |
| Time per byte | 8 ns |
| Packet on the wire | about 9014 bytes |
| Packet time | 9014 x 8 ns = 72,112 ns |
| Buffer (about 11 %) | 7,888 ns |
| **P** | **80,000 ns** |

#### Step 2: Values per Camera {#calculate-the-delays}

With `N` cameras, and `n` the number of the camera (1, 2, 3 …):

```
GevSCPD  (every camera) = P x (N - 1)
GevSCFTD (camera n)     = P x (n - 1)
```

Every camera gets the same `GevSCPD`: while one packet of this camera is on the link, there must be room for one packet of each of the other `N - 1` cameras. `GevSCFTD` gives each camera a different head start, so that they do not all put their first packet on the link at the same moment.

**Table 1. Two cameras, P = 80,000 ns**

| Camera | `GevSCPD` | `GevSCFTD` |
| --- | --- | --- |
| camera 1 | 80,000 ns | 0 ns |
| camera 2 | 80,000 ns | 80,000 ns |

**Table 2. Four cameras, P = 80,000 ns**

| Camera | `GevSCPD` | `GevSCFTD` |
| --- | --- | --- |
| camera 1 | 240,000 ns | 0 ns |
| camera 2 | 240,000 ns | 80,000 ns |
| camera 3 | 240,000 ns | 160,000 ns |
| camera 4 | 240,000 ns | 240,000 ns |

#### Step 3: Check the Frame Rate You Are Left With {#calculate-the-frame-rate}

The delays slow every camera down. Check that the result still meets your cycle time, and that the trigger is not sent faster than a camera can deliver.

For an image of 960 x 1280 pixels in `Mono8` (1,228,800 bytes), `packetSize` 9000 and two cameras:

| Quantity | Value |
| --- | --- |
| Image size | 960 x 1280 x 1 byte = 1,228,800 bytes |
| Image data per packet | about 8,992 bytes |
| Packets per image | 1,228,800 / 8,992 = 137 packets |
| Interval between packets | 72,112 ns + 80,000 ns = 152,112 ns |
| Transmission of one image | 137 x 152,112 ns = about 20.8 ms |
| Highest frame rate per camera | about 48 images per second |

Both cameras reach this at the same time, so two images arrive about every 20.8 ms. The same camera alone, with no delays, would transmit one image in about 9.9 ms and reach about 101 images per second: two cameras together cost roughly the same total time as two images one after the other, but without the collisions.

#### Where to Set the Values {#set-the-delays}

The Cam Driver sets `GevSCPSPacketSize` and `GevSCPD` from the camera configuration:

| Setting in the camera configuration file | Node on the Data Layer | Camera feature |
| --- | --- | --- |
| `packetSize` | `<camera name>/transport-layer/packet-size` | `GevSCPSPacketSize` |
| `packetDelay_us` | `<camera name>/transport-layer/inter-packet-delay-us` | `GevSCPD` |

Both nodes are read-only while the camera is connected, so set them in the camera configuration file, or on the Data Layer before you connect the camera.

`GevSCFTD` has no setting of its own. Set it per camera through the camera’s feature nodes under `hdvisionsystems/lumiscan-cam-driver/<camera name>/features`, or in a feature file listed in the module’s `cameras[].featureFiles`, which is applied every time the camera is connected. See [GenICam features](https://docs.hdvisionsystems.com/en/lumiscan-cam-driver/lumiscan-camdriver/initializing-the-camera.html#genicam-features).

> [!IMPORTANT]
> The value of `packetDelay_us` is passed to the camera’s `GevSCPD` unchanged, despite the name of the setting. `GevSCPD` and `GevSCFTD` are counted in the camera’s own unit, which differs between manufacturers: some cameras count in nanoseconds, many count in ticks of the device timestamp counter. Read `GevTimestampTickFrequency` from the camera’s feature nodes and convert: `ticks = nanoseconds x GevTimestampTickFrequency / 1,000,000,000`. At the common 125,000,000 Hz (8 ns per tick), the 80,000 ns above is `10,000`. Refer to the camera manufacturer’s documentation, and verify the value you wrote by reading the feature back.

#### Further Points {#hardware-trigger-notes}

- Use an edge for the trigger (`TriggerActivation` set to `RisingEdge`, `FallingEdge` or `AnyEdge`). A level (`LevelHigh`, `LevelLow`) does not produce the interleaving described here.
- Keep the trigger frequency below the frame rate calculated in step 3. The delays lower it, and a camera that is triggered faster than it can transmit drops images.
- The calculation assumes that all cameras use the same image size, pixel format and `packetSize`. If they differ, calculate `P` from the largest packet and check the result with the slowest camera.
- If images are still incomplete, raise the buffer in step 1 towards 30 %, or reduce the image size through the camera’s ROI.

The method follows the application note [Bandwidth sharing in multi-camera systems](https://support.thinklucid.com/app-note-bandwidth-sharing-in-multi-camera-systems/) by LUCID Vision Labs, which describes it for their cameras.
