The VisionCam XM/XM2 provides a user-configurable FPGA, the "Real Time Communication Controller" (RTCC). It contains functional units for controlling trigger signals.
The RTCC can be configured by using the VisionBox Interface Library. The relevant modules are listed below:
Also take a look at the Sensors page for information about available sensors.
The function FG_set_trigger_mode() is used to configure one of the trigger modes:
Example:
The VisionCam XM uses the VIB::Multiplexer output line 0 as hardware trigger for the sensor by default. The Multiplexer line can be changed with the special feature TriggerLine. The sensor will trigger on a rising edge of the signal. There are no restrictions on the pulse length.
Property name | Description | Library |
---|---|---|
TriggerLine | Sets the VIB::Multiplexer line to use as trigger source in hardware triggered mode (default: 0). | ≥ 1.1.1.0 |
In the following example, the digital input 0 is connected to the sensor by using the Multiplexer output 2: VIB::Multiplexer multiplexer;
unsigned int muxOutput = 2;
// Open the multiplexer device
multiplexer.Open();
// Connect the multiplexer output with the first digital input
multiplexer.ConnectOutput(muxOutput, VIB::Multiplexer::MUX_SRC_DIG_IN0);
// Setup the FG camera interface
// Use hardware triggered mode
// Select the multiplexer output for triggering the sensor
FG_set_special_option("TriggerLine", muxOutput);
...
Please note that no error checking is performed in the examples in order to simplify the code. |
The following example shows how to configure the RTCC for using a rotary encoder to generate an adequate trigger signal. This is often useful for line scan applications (Dragster Line Scan sensor or Lince5M181 sensor in Line scan mode). The example uses DividerA withtin the Trigger Unit (VIB::TriggerGenerator) with the encoder signals A and B. The divider value EncoderDivider (1...) determines the ratio between encoder speed and trigger frequency. void SetupTrigger(unsigned int EncoderDivider)
{
VIB::TriggerGenerator triggerUnit;
VIB::Multiplexer multiplexer;
char text[200];
// Open Multiplexer and Trigger Unit
multiplexer.Open();
triggerUnit.Open();
// Connect RS-422 encoder signals A and B to MUX output 0 and 1
// Setup DividerA using both encoder signals to get the highest input frequency:
snprintf(text, sizeof(text), "DividerA=%u,TrigIn0/1_Both", EncoderDivider);
triggerUnit.ConfigureSet(text);
// We use Divider output 'TrigInB' because it has twice the frequency compared to output 'DividerA'
triggerUnit.ConfigureSet("MuxIntern0=TrigInB");
// Connect the trigger signal to output 0 of the Trigger Unit
triggerUnit.ConfigureSet("TrigOut0_Mux=TrigIntern0");
// Connect the trigger signal to MUX output 2
multiplexer.ConnectOutput(2, VIB::Multiplexer::MUX_SRC_TRIGGEN_OUT0);
// Configure the sensor to use MUX output 2, the default is 0
FG_set_special_option("TriggerLine", 2);
// Activate hardware trigger for the sensor
}
Please note that no error checking is performed in the examples in order to simplify the code. |
This example is based on the previous example. An external frame trigger signal is now used to start acquistion for a limited number of trigger events. After a frame trigger happens, only the specified number of trigger events (TriggerCount) will be sent to the sensor. Further events are ignored, until the next frame trigger arrives. Further, the value TriggerDelay can be used to delay the first sensor event after the frame trigger. This value is also based on encoder position, not on time. void SetupTrigger(unsigned int EncoderDivider, unsigned int TriggerCount, unsigned int TriggerDelay)
{
VIB::TriggerGenerator triggerUnit;
VIB::Multiplexer multiplexer;
char text[200];
// Open Multiplexer and Trigger Unit
multiplexer.Open();
triggerUnit.Open();
multiplexer.ConnectOutput(2, VIB::Multiplexer::MUX_SRC_DIG_IN0); // frame trigger at digital input 0
// multiplexer.ConnectOutput(2, VIB::Multiplexer::MUX_SRC_SYNC_2); // alternatively: use encoder zero pulse as frame trigger
// Setup DividerA using both encoder signals to get the highest input frequency:
snprintf(text, sizeof(text), "DividerA=%u,TrigIn0/1_Both", EncoderDivider);
triggerUnit.ConfigureSet(text);
triggerUnit.ConfigureSet("MuxIntern1=DividerA");
// Use CounterB to generate a delay after the frame trigger signal
triggerUnit.ConfigureSet("MuxIntern2=TrigIn2");
// Setup ON / OFF times to create a short output pulse after reaching the delay position:
snprintf(text, sizeof(text), "CounterB=%u,TrigIn0/1_Both CounterB_ON=%u CounterB_OFF=%u",
EncoderDivider * TriggerDelay + 1, EncoderDivider * TriggerDelay, EncoderDivider * TriggerDelay + 1);
triggerUnit.ConfigureSet(text);
triggerUnit.ConfigureSet("CounterB_Reset=Auto"); // Reset counter automatically after reaching the highest value
triggerUnit.ConfigureSet("MuxIntern3=CounterB"); // CounterB output is the start signal for CounterA
// Use CounterA to mask the divider output
// Setup ON / OFF times to create the mask signal:
snprintf(text, sizeof(text), "CounterA=%u,TrigIntern1_Both CounterA_On=1 CounterA_Off=%u", TriggerCount + 1, TriggerCount + 1);
triggerUnit.ConfigureSet(text);
triggerUnit.ConfigureSet("CounterA_Reset=Auto"); // Reset counter automatically after reaching the highest value
// Divider output 'TrigInB' is masked by CounterA
triggerUnit.ConfigureSet("MuxIntern0=TrigInB");
// Connect the trigger signal to output 0 of the Trigger Unit
triggerUnit.ConfigureSet("TrigOut0_Mux=TrigIntern0");
// Connect the trigger signal to MUX output 3
multiplexer.ConnectOutput(3, VIB::Multiplexer::MUX_SRC_TRIGGEN_OUT0);
// Configure the sensor to use MUX output 3, the default is 0
FG_set_special_option("TriggerLine", 3);
// Activate hardware trigger for the sensor
}
Please note that no error checking is performed in the examples in order to simplify the code. |
The exposure signal is available to the Multiplexer by using VIB::Multiplexer::MUX_SRC_SYNC_1_0 as source signal.
In the following example, we use the exposure signal from the sensor to activate the internal LED ring light.
Please note that error checking was removed to keep the code as simple as possible.
Three special features are provided in order to embed additional information into the beginning of each frame or each line for line scan cameras:
Property name | Description | Version requirements | |
---|---|---|---|
Library | FPGA | ||
InsertImageCounter | Enables or disables insertion of a frame / line counter. 0: disable counter (default) 1: enable counter | ≥ 1.2.4.0 | ≥ 1.0.0.48 |
InsertTriggerCounter | Enables or disables insertion of a trigger counter, see Using embedded image, trigger and timestamp counters. 0: disable counter (default) 1: enable counter | ||
InsertTimeStamp | Enables or disables insertion of a time stamp, see Using embedded image, trigger and timestamp counters. 0: disable time stamp (default) 1: enable time stamp |
The image counter can be used for detection of dropped senor lines which are caused by insufficient acquisition buffers.
The trigger counter is used in hardware triggered mode for detection of ignored trigger events when the trigger signal is arriving too fast. This counter doesn't increment in free run mode.
int main()
{
FG_IMAGE imageList[NUM_BUFFERS];
int checkCounters = 0;
unsigned short frameCounter[2];
unsigned short trgCounter[2];
unsigned int timestamp[2];
// install and configure the camera
SetupCamera();
// configure customized hardware trigger
SetupTrigger();
// activate all counters
FG_set_special_option("InsertImageCounter", 1);
FG_set_special_option("InsertTriggerCounter", 1);
FG_set_special_option("InsertTimeStamp", 1);
// allocate image buffers
for (UINT32 i = 0; i < NUM_BUFFERS; i++)
FG_alloc_image(&imageList[i]);
// start acquisition
for (UINT32 i = 0; i < NUM_BUFFERS; i++)
FG_append_image(&imageList[i]);
// enter acquisition loop
while (isRunning)
{
FG_IMAGE currentImage;
unsigned short counterDiff;
UINT32 res = FG_get_image(¤tImage, UINT_MAX);
if (res == FG_ERROR_CODE_NoError)
{
// read the counter values from the beginning of the image:
if (checkCounters)
{
// check the received sensor frames
counterDiff = frameCounter[0] - frameCounter[1];
if (counterDiff != 1)
printf("%d sensor frames dropped\n", counterDiff - 1);
// check the trigger counter
counterDiff = trgCounter[0] - trgCounter[1];
if (counterDiff != 1)
printf("%d trigger events dropped\n", counterDiff - 1);
printf("Frame period: %u us\n", timestamp[0] - timestamp[1]);
}
else
{
// delayed start of counter check
checkCounters = 1;
}
// store values for the next cycle
frameCounter[1] = frameCounter[0];
trgCounter[1] = trgCounter[0];
timestamp[1] = timestamp[0];
FG_append_image(¤tImage);
}
{
FG_append_image(¤tImage);
}
else // Error during waiting
return -1;
}
// abort image acquisition
// free buffers
for (UINT32 i = 0; i < NUM_BUFFERS; i++)
FG_free_image(&imageList[i]);
// Close the camera
return 0;
}
Please note that no error checking is performed in the examples in order to simplify the code. |