Using Multiple Cameras

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.

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

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.

  2. The cameras do not transmit at the same time - see Trigger Source. How you achieve this depends on your trigger source.

Hardware Setup

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.

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

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

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.

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.

Software Trigger: One Camera After Another

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.

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
%% 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.

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.

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.

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

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

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

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

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

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.

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

  • 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 by LUCID Vision Labs, which describes it for their cameras.