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/codeis-10004(couldNotCaptureImage), and through the handshakecapture/readystaysfalseuntil aresetsucceeds. -
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:
-
The link carries camera traffic only - see Hardware Setup.
-
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
packetSizeto 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 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 |
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:
-
Set
camera1capture/requesttotrue. -
Wait until
camera1capture/readyisfalse. -
Set
camera2capture/requesttotrue. -
Wait until
camera2capture/readyisfalse. -
Set
camera1capture/requesttofalse. Camera 1 now exposes and transmits. -
Wait until
camera1capture/readyistrueagain. The image of camera 1 has arrived and the link is free. -
Set
camera2capture/requesttofalse. Camera 2 now exposes and transmits. -
Wait until
camera2capture/readyistrueagain.
%% 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 |
|---|---|
|
Packet delay. The gap the camera leaves between two packets of the same image. |
|
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.
| Camera | GevSCPD |
GevSCFTD |
|---|---|---|
camera 1 |
80,000 ns |
0 ns |
camera 2 |
80,000 ns |
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 |
|---|---|---|
|
|
|
|
|
|
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 (
TriggerActivationset toRisingEdge,FallingEdgeorAnyEdge). 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, calculatePfrom 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.