Euresys Coaxlink Manual

PROGRAMMER'S GUIDE
Coaxlink
Coaxlink Driver Version 7.1
© EURESYS s.a. 2017 - Document version 7.1.637 built on 2017-04-14

EURESYS s.a. shall retain all property rights, title and interest of the documentation of the hardware and the soware,
and of the trademarks of EURESYS s.a. All the names of companies and products mentioned in the documentation may
be the trademarks of their respective owners. The licensing, use, leasing, loaning, translation, reproduction, copying or
modification of the hardware or the soware, brands or documentation of EURESYS s.a. contained in this book, is not
allowed without prior notice. EURESYS s.a. may modify the product specification or change the information given in this
documentation at any time, at its discretion, and without prior notice. EURESYS s.a. shall not be liable for any loss of or
damage to revenues, profits, goodwill, data, information systems or other special, incidental, indirect, consequential or
punitive damages of any kind arising in connection with the use of the hardware or the soware of EURESYS s.a. or resulting
of omissions or errors in this documentation.

ContentsCoaxlink Programmer's Guide
Contents
Introduction............................................................................................................................................................................ 5
GenApi.........................................................................................................................................................................................6
Register description.....................................................................................................................................................................6
GenApi implementation.............................................................................................................................................................. 6
Features........................................................................................................................................................................................6
GenTL...........................................................................................................................................................................................7
System module............................................................................................................................................................................ 7
Interface module......................................................................................................................................................................... 8
Device module............................................................................................................................................................................. 8
Data stream module....................................................................................................................................................................8
Buffer module.............................................................................................................................................................................. 8
GenTL API..................................................................................................................................................................................... 8
Euresys::EGenTL................................................................................................................................................................ 10
A first example........................................................................................................................................................................... 10
Relevant files..............................................................................................................................................................................11
Euresys::EGrabber.......................................................................................................................................................... 12
A first example........................................................................................................................................................................... 12
Acquiring images....................................................................................................................................................................... 13
Configuring the grabber............................................................................................................................................................15
Events......................................................................................................................................................................................... 16
Background............................................................................................................................................................................ 16
Counters................................................................................................................................................................................. 17
Notifications...........................................................................................................................................................................17
Callback functions................................................................................................................................................................. 18
Event identification............................................................................................................................................................... 19
Examples................................................................................................................................................................................ 20
EGrabber flavors....................................................................................................................................................................... 20
Events and callbacks examples................................................................................................................................................21
On demand callbacks............................................................................................................................................................21
Single thread and multi thread callbacks........................................................................................................................... 22
New buffer callbacks.............................................................................................................................................................23
Relevant files..............................................................................................................................................................................24
iii

Coaxlink Programmer's GuideContents
Euresys GenApi scripts................................................................................................................................................. 25
doc/basics.js............................................................................................................................................................................. 25
doc/builtins.js........................................................................................................................................................................... 30
doc/grabbers.js.......................................................................................................................................................................... 31
doc/module1.js.......................................................................................................................................................................... 33
EGrabber for MultiCam users...................................................................................................................................34
.NET assembly.................................................................................................................................................................... 40
A first example........................................................................................................................................................................... 40
Differences between C++ and .NET EGrabber......................................................................................................................... 41
Single thread callbacks............................................................................................................................................................. 42
Definitions............................................................................................................................................................................. 44
iv

IntroductionCoaxlink Programmer's Guide
Introduction
The Application Programming Interface (API) for Coaxlink cards is based on GenICam.
The goal of GenICam is to provide a standardized, uniform programming interface for using cameras and frame
grabbers based on different physical interfaces (CoaXPress, GigE Vision, etc.) or from different vendors.
GenICam is a set of EMVA standards (GenApi and GenTL), as well as related conventions for naming things (the
SFNC for standard features, the PFNC for pixel formats).
• GenApi is about description. At the core of GenApi is the concept of register description. Register descriptions are
provided in the form of XML files. They map low-level hardware registers to high-level features.
GenApi allows applications to detect, configure and use the features of cameras and frame grabbers in a uniform
and consistent way.
• GenTL is about data transport. The TL suffix stands for Transport Layer.
The GenTL standard defines a set of C functions and data types for enumerating, configuring, and grabbing images
from cameras and frame grabbers. This API is defined by a C header file.
Frame grabber vendors provide libraries that implement this API (i.e., libraries that export the functions declared in
the standard header file). These libraries are referred to as GenTL producers, or Common Transport Interfaces
(CTI) and use the cti file extension. The GenTL producer for Coaxlink cards is coaxlink.cti.
This document is meant to be read from beginning to end. Each chapter and section builds upon the preceding ones.
If you skip parts of the text, some of the explanations and examples may seem cryptic. If that happens, you should go
back and read the parts that you've skipped over.
5

Coaxlink Programmer's GuideGenApi
GenApi
GenApi addresses the problem of configuring cameras. The way this is achieved is generic, and applies to different
kinds of devices, including frame grabbers. In this chapter, everything we say about cameras also applies to frame
grabbers.
GenApi requires two things to work: a register description, and a GenApi implementation.
Register description
A register description is an XML file that can be thought of as a computer-readable datasheet of the camera. It defines
camera settings (such as PixelFormat and TriggerSource), and instructions on how to configure them (e.g., to
set ExposureMode to Timed, write value 0x12 to register 0xE0140). It can also contain camera documentation.
GenApi implementation
A GenApi implementation is a soware module that can read and interpret register description files.
The EMVA provides a reference implementation, but it is fairly difficult to use, and logging is very poor. Instead, we
recommend using the Euresys implementation bundled with the Coaxlink soware package. This implementation also
allows writing powerful configuration scripts.
Features
What the user gets from GenApi is a bunch of named features, organized in categories.
Set/get features
Set/get features are simple settings (called parameters in MultiCam), and can be of different types:
• integer (e.g., Width)
• float (e.g., AcquisitionFrameRate)
• enumeration (e.g., PixelFormat)
• boolean (e.g., LUTEnable)
• string (e.g., DeviceVendorName)
The value of features can be retrieved/modified using get/set functions. Some features are read-only and some are
write-only, but most allow read/write access.
Commands
There is also another kind of features: commands (e.g., AcquisitionStart). Commands are special: they don't
have any associated value; they have side effects. Command features are meant to be executed. When a command is
executed, some action happens in the camera (e.g., a soware trigger is generated). Obviously, get/set functions don't
make sense for commands and can't be used.
6

GenTLCoaxlink Programmer's Guide
GenTL
GenTL defines 5 types of objects, organized in a parent/child relationship:
1. the system module
2. the interface module
3. the device module
4. the data stream module
5. the buffer module
Each module:
• corresponds to a particular element of the system;
• defines relevant pieces of information (info commands) that can be queried (using get info functions);
• allows exercising that module's functionality (using specific functions).
Additionally, all modules except the buffer module behave as ports that allow read/write operations. These port
functions are used by GenApi to load that module's description file, and to use its GenApi features.
System Module coaxlink.c
Interface Module PC1633 – Coaxlink Quad G3 (2-camera) – KQG00014
Device Module Device0
Buffer Module Buffers
Stream Module Stream0
PC1630 – Coaxlink Mono (1-camera) – KMO97322
Remote
Device X Device1
Buffers
Stream0
Remote
Device Y Device0
Buffers
Stream0
Remote
Device Z
Figure 1: GenTL Module Hierarchy
System module
The system module (also referred to as TLSystem), represents the GenTL producer (the coaxlink.cti library). This
module is at the top of the parent/child tree.
The system module provides basic information about the GenTL producer: things like the complete path to
coaxlink.cti and the vendor name (Euresys).
7

Coaxlink Programmer's GuideGenTL
The real point of the system module is to list the interfaces (or frame grabbers) present in the system. The most
important functions of the system module are TLGetNumInterfaces (to retrieve the number of frame grabbers in
the system) and TLOpenInterface (to get access to one of the frame grabbers).
Interface module
The GenTL standard calls frame grabbers interfaces. The system module has one child interface for each frame
grabber: if there are 2 Coaxlink cards in the computer, the system module will have two child interfaces.
Each interface represents a frame grabber. Global frame grabber features such as digital I/O lines belong in the interface
module. This means that the GenApi features controlling the I/O lines are attached to the interface.
Each interface also acts as parent to one or several devices. The most important functions of the interface module are
IFGetNumDevices (to retrieve the number of cameras that can be connected to the interface) and IFOpenDevice
(to get access to one of the devices).
Device module
The GenTL standard uses the terms device and remote device for two related but different concepts. A remote device
is a real camera, physically connected to a frame grabber. This is different from the device module we describe here.
The device module is the module that contains the frame grabber settings relating to the camera. This includes things
like triggers and strobes.
The device module also acts as parent to one data stream, and can be viewed as the sibling of the remote device.
The most important functions of the device module are DevOpenDataStream (to get access to the data stream) and
DevGetPort (to get access to the remote device).
Data stream module
The data stream module handles buffers. During acquisition runs, images are sent from the camera to the frame
grabber, which transfers them to memory buffers allocated on the host computer. The data stream module is where
image acquisition occurs. It is where most of the functionality resides.
Buffer handling is very flexible. Any number of buffers can be used. Buffers are either in the input queue, in the output
queue, or temporarily unqueued. The application decides when empty buffers are queued (to the input FIFO), and
when filled buffers are popped (from the output FIFO).
Buffer module
The buffer module simply represents a memory buffer given to a parent data stream. Useful metadata is associated to
buffers. This includes the image width, height, pixel format, timestamp... These are retrieved through info commands
(see BUFFER_INFO_CMD_LIST in the standard GenTL header file).
The buffer module is the only module that doesn't have read/write port functions; it doesn't have GenApi features.
GenTL API
GenTL makes it possible to detect, control and use all camera and frame grabber features, but its usage is tedious:
8

GenTLCoaxlink Programmer's Guide
•cti files must be dynamically loaded, and the functions they export must be accessed through pointers.
• Functions return an error code that must be checked by the application.
• Most functions read from/write to untyped buffers: the application must determine the required buffer size, allocate
a temporary buffer, convert data to/from this buffer, and finally release the buffer memory.
Instead of using the GenTL API directly, we recommend using either:
• the Euresys::EGenTL library which deals with these complications so that the user doesn't have to;
• or the Euresys::EGrabber library which provides a high-level, easy-to-use interface.
9

Coaxlink Programmer's GuideEuresys::EGenTL
Euresys::EGenTL
Euresys::EGenTL is a library of C++ classes that provide the same functionality as standard GenICam GenTL, but
with a more user-friendly interface. For example, it uses std::string instead of raw char pointers, and error codes
are transformed into exceptions. Euresys::EGenTL also takes care of locating the GenTL producer and loading the
functions it exports.
This library is implemented entirely in C++ header files. As a result, you can simply include the relevant header file:
#include <EGenTL.h>
Instead of the raw, low-level C functions that GenTL defines, we get a Euresys::EGenTL object that represents the
GenTL producer:
• Each GenTL function is available as a member method of Euresys::EGenTL. GenTL function names start with
an upper-case prefix. In Euresys::EGenTL, method names start with the same prefix, but written in lower-case.
For example, the GCReadPort function is exposed as the gcReadPort method, and the TLOpenInterface
function as the tlOpenInterface method.
• All GenTL functions return a GC_ERROR code indicating success or failure. When a function returns a code other
than GC_ERR_SUCCESS, an exception is thrown. This removes the burden of manually checking error codes aer
each function call.
• Since GenTL functions return a GC_ERROR, output values are returned through pointers passed as arguments.
Euresys::EGenTL methods offer a more natural interface; they return the output value directly:
GC_API TLGetNumInterfaces(TL_HANDLE hTL, uint32_t *piNumIfaces);
uint32_t tlGetNumInterfaces(TL_HANDLE tlh);
(Note that GC_API is defined as GC_IMPORT_EXPORT GC_ERROR GC_CALLTYPE. It is simply a GC_ERROR
decorated with calling convention and DLL import/export attributes.)
• For GenTL functions that deal with text, the corresponding Euresys::EGenTL methods convert from char *
to std::string and vice-versa:
GC_API TLGetInterfaceID(TL_HANDLE hTL, uint32_t iIndex,
char *sID, size_t *piSize);
std::string tlGetInterfaceID(TL_HANDLE tlh, uint32_t index);
• Some GenTL functions retrieve information about the camera or frame grabber. These functions fill a void *
buffer with a value, and indicate in an INFO_DATATYPE the actual type of the value. Euresys::EGenTL uses C
++ templates to make these functions easy to use:
GC_API GCGetInfo(TL_INFO_CMD iInfoCmd, INFO_DATATYPE *piType,
void *pBuffer, size_t *piSize);
template<typename T> T gcGetInfo(TL_INFO_CMD cmd);
A first example
This program uses Euresys::EGenTL to iterate over the Coaxlink cards present in the system, and display their id:
#include <iostream>
#include <EGrabber.h> // 1
10

Euresys::EGenTLCoaxlink Programmer's Guide
static const uint32_t CARD_IX = 0;
static const uint32_t DEVICE_IX = 0;
void showInfo() {
Euresys::EGenTL gentl; // 2
Euresys::EGrabber<> grabber(gentl, CARD_IX, DEVICE_IX); // 3
std::string card = grabber.getString<Euresys::InterfaceModule>("InterfaceID"); // 4
std::string dev = grabber.getString<Euresys::DeviceModule>("DeviceID"); // 5
int64_t width = grabber.getInteger<Euresys::RemoteModule>("Width"); // 6
int64_t height = grabber.getInteger<Euresys::RemoteModule>("Height"); // 6
std::cout << "Interface: " << card << std::endl;
std::cout << "Device: " << dev << std::endl;
std::cout << "Resolution: " << width << "x" << height << std::endl;
}
int main() {
try { // 7
showInfo();
} catch (const std::exception &e) { // 7
std::cout << "error: " << e.what() << std::endl;
}
}
1. Include EGenTL.h, which contains the definition of the Euresys::EGenTL class.
2. Create a Euresys::EGenTL object. This involves the following operations:
• locate and dynamically load the Coaxlink GenTL producer (coaxlink.cti);
• retrieve pointers to the functions exported by coaxlink.cti, and make them available via
Euresys::EGenTL methods;
• initialize coaxlink.cti (this is done by calling the GenTL initialization function GCInitLib).
3. Open the GenTL producer. This returns a handle of type GenTL::TL_HANDLE. The GenTL namespace is defined
in the standard GenTL header file, which has been automatically included by EGenTL.h in step 1.
4. Find out how many cards are present in the system.
5. Retrieve the id of the n-th card.
6. Euresys::EGenTL uses exceptions to report errors, so we wrap our code inside a try ... catch block.
Example of program output:
[0] PC1633 - Coaxlink Quad G3 (1-camera, line-scan) - KQG00014
[1] PC1632 - Coaxlink Quad (1-camera) - KQU00031
Relevant files
include/EGenTL.h
Main header. Includes all the other headers. Defines Euresys::EGenTL
include/GenTL_v1_5.h
Standard GenTL header. Defines standard types, functions and constants.
include/GenTL_v1_5_EuresysCustom.h
Defines Coaxlink-specific constants
11

Coaxlink Programmer's Guide Euresys::EGrabber
Euresys::EGrabber
Euresys::EGrabber is a library of C++ classes that provide a high-level interface. It is built on top of the
Euresys::EGenTL library, and is recommended for most users.
A .NET assembly, built on top of the Euresys::EGrabber C++ classes, is also provided. In this document, we focus
mainly on the C++ API. Minor differences between the C++ and .NET interfaces are listed in a dedicated chapter.
To use the classes described here, you need to include the main Euresys::EGrabber file:
#include <EGrabber.h>
Euresys::EGrabber is a header-only library (it isn't provided as a lib or dll file). It comprises several classes,
the most important of which is also named Euresys::EGrabber:
namespace Euresys {
class EGrabber;
}
In this text, we'll refer to this class as a grabber. A grabber encapsulates a set of related GenTL modules:
• An interface: the module that represents global (shared) frame grabber settings and features. This includes digital
I/O control, PCIe and firmware status...
• A device (or local device, as opposed to remote device): the module that contains the frame grabber settings and
features relating to the camera. This consists mainly of camera and illumination control features: strobes, triggers...
• A data stream: the module that handles image buffers.
• A remote device: the CoaXPress camera.
• A number of buffers.
Go back to the chapter about GenTL modules if these concepts are not clear.
A first example
This example creates a grabber and displays basic information about the interface, device, and remote device modules
it contains:
#include <iostream>
#include <EGrabber.h> // 1
static const uint32_t CARD_IX = 0;
static const uint32_t DEVICE_IX = 0;
void showInfo() {
Euresys::EGenTL gentl; // 2
Euresys::EGrabber<> grabber(gentl, CARD_IX, DEVICE_IX); // 3
std::string card = grabber.getString<Euresys::InterfaceModule>("InterfaceID"); // 4
std::string dev = grabber.getString<Euresys::DeviceModule>("DeviceID"); // 5
int64_t width = grabber.getInteger<Euresys::RemoteModule>("Width"); // 6
int64_t height = grabber.getInteger<Euresys::RemoteModule>("Height"); // 6
std::cout << "Interface: " << card << std::endl;
std::cout << "Device: " << dev << std::endl;
std::cout << "Resolution: " << width << "x" << height << std::endl;
}
int main() {
try { // 7
12

Euresys::EGrabber Coaxlink Programmer's Guide
showInfo();
} catch (const std::exception &e) { // 7
std::cout << "error: " << e.what() << std::endl;
}
}
1. Include EGrabber.h, which defines the Euresys::EGrabber class, and includes the other header files we
need (such as EGenTL.h and the standard GenTL header file).
2. Create a Euresys::EGenTL object. This involves the following operations:
• locate and dynamically load the Coaxlink GenTL producer (coaxlink.cti);
• retrieve pointers to the functions exported by coaxlink.cti, and make them available via
Euresys::EGenTL methods;
• initialize coaxlink.cti (this is done by calling the GenTL initialization function GCInitLib).
3. Create a Euresys::EGrabber object. The constructor needs the gentl object created in step 2. It also takes
as optional arguments the indices of the interface and device to use.
The purpose of the angle brackets (<>) that come aer EGrabber will become clear later. For now, they can be
safely ignored.
4. Use GenApi on page 6 to find out the ID of the Coaxlink card. Euresys::InterfaceModule indicates that we
want an answer from the interface module.
5. Similarly, find out the ID of the device. This time, we use Euresys::DeviceModule to target the device module.
6. Finally, read the camera resolution. Euresys::RemoteModule indicates that the value must be retrieved from
the camera.
7. Euresys::EGrabber uses exceptions to report errors, so we wrap our code inside a try ... catch block.
Example of program output:
Interface: PC1633 - Coaxlink Quad G3 (2-camera) - KQG00014
Device: Device0
Resolution: 4096x4096
Acquiring images
This program uses Euresys::EGrabber to acquire images from a camera connected to a Coaxlink card:
#include <iostream>
#include <EGrabber.h>
void grab() {
Euresys::EGenTL gentl;
Euresys::EGrabber<> grabber(gentl); // 1
grabber.reallocBuffers(3); // 2
grabber.start(10); // 3
for (size_t i = 0; i < 10; ++i) {
Euresys::ScopedBuffer buf(grabber); // 4
void *ptr = buf.getInfo<void *>(GenTL::BUFFER_INFO_BASE); // 5
uint64_t ts = buf.getInfo<uint64_t>(GenTL::BUFFER_INFO_TIMESTAMP); // 6
std::cout << "buffer address: " << ptr << ", timestamp: "
<< ts << " us" << std::endl;
} // 7
}
int main() {
try {
grab();
} catch (const std::exception &e) {
std::cout << "error: " << e.what() << std::endl;
}
13

Coaxlink Programmer's Guide Euresys::EGrabber
}
1. Create a Euresys::EGrabber object. The second and third arguments of the constructor are omitted here. The
grabber will use the first device of the first interface present in the system.
2. Allocate 3 buffers. The grabber automatically determines the required buffer size.
3. Start the grabber. Here, we ask the grabber to fill 10 buffers. If we don't want the grabber to stop aer a specific
number of buffers, we can do grabber.start(GenTL::GENTL_INFINITE), or simply grabber.start().
Starting the grabber involves the following operations:
• the AcquisitionStart command is executed on the camera;
• the DSStartAcquisition function is called to start the data stream.
In this example, we assume that the camera and frame grabber are properly configured. For a real application,
it would be safer to run a configuration script before starting acquisitions (and before allocating buffers for that
matter). This will be shown in another example.
4. Wait for a buffer filled by the grabber. The result is a Euresys::ScopedBuffer. The term scoped is used to
indicate that the lifetime of the buffer is the current scope (i.e., the current block).
5. Retrieve the buffer address. This is done by calling the getInfo method of the buffer. This method takes as
argument a BUFFER_INFO_CMD. In this case, we request the BUFFER_INFO_BASE, which is defined in the
standard GenTL header file:
enum BUFFER_INFO_CMD_LIST
{
BUFFER_INFO_BASE = 0, /* PTR Base address of the buffer memory. */
BUFFER_INFO_SIZE = 1, /* SIZET Size of the buffer in bytes. */
BUFFER_INFO_USER_PTR = 2, /* PTR Private data pointer of the GenTL Consumer. */
BUFFER_INFO_TIMESTAMP = 3, /* UINT64 Timestamp the buffer was acquired. */
// ...
// other BUFFER_INFO definitions omitted
// ...
BUFFER_INFO_CUSTOM_ID = 1000 /* Starting value for GenTL Producer custom IDs. */
};
typedef int32_t BUFFER_INFO_CMD;
Notice that getInfo is a template method, and when we call it we must specify the type of value we expect.
BUFFER_INFO_BASE returns a pointer; this is why we use getInfo<void *>.
6. Do the same to retrieve the timestamp of the buffer. This time, we use the uint64_t version of getInfo to match
the type of BUFFER_INFO_TIMESTAMP.
Note that, for Coaxlink, timestamps are always 64-bit and expressed as the number of microseconds that have
elapsed since the computer was started.
7. We reach the end of the for block. The local variable buf gets out of scope and is destroyed: the ScopedBuffer
destructor is called. This causes the GenTL buffer contained in buf to be re-queued (given back) to the data stream
of the grabber.
Example of program output:
buffer address: 0x7f3c32c54010, timestamp: 11247531003686 us
buffer address: 0x7f3c2c4bf010, timestamp: 11247531058080 us
buffer address: 0x7f3c2c37e010, timestamp: 11247531085003 us
buffer address: 0x7f3c32c54010, timestamp: 11247531111944 us
buffer address: 0x7f3c2c4bf010, timestamp: 11247531137956 us
buffer address: 0x7f3c2c37e010, timestamp: 11247531163306 us
buffer address: 0x7f3c32c54010, timestamp: 11247531188600 us
buffer address: 0x7f3c2c4bf010, timestamp: 11247531213807 us
buffer address: 0x7f3c2c37e010, timestamp: 11247531239158 us
buffer address: 0x7f3c32c54010, timestamp: 11247531265053 us
We can see that the three buffers that were allocated (let's call them A at 0x7f3c32c54010, B at 0x7f3c2c4bf010,
and C at 0x7f3c2c37e010) are used in a round-robin fashion: A → B → C → A → B → C → ... This is the result of:
• the FIFO nature of input and output buffer queues:
14

Euresys::EGrabber Coaxlink Programmer's Guide
• the Coaxlink driver pops a buffer from the front of the input queue, and gives it to the Coaxlink card for DMA
transfer;
• when the transfer is complete, the buffer is pushed to the back of the output queue;
• the use of ScopedBuffer:
• the ScopedBuffer constructor pops a buffer from the front of the output queue (i.e., it takes the oldest buffer);
• the ScopedBuffer destructor pushes that buffer to the back of the input queue (hence, this buffer will be used
for a new transfer aer all buffers already in the input queue).
Configuring the grabber
Configuration is a very important aspect of any image acquisition program.
• The camera and the frame grabber both have to be configured according to the application requirements.
• The camera configuration must be compatible with the frame grabber configuration, and vice versa.
Configuration basically boils down to a series of set/get operations performed on the grabber modules: the remote
device (i.e., the camera), the interface, the device, or the data stream modules.
This program configures the grabber for the so-called RG control mode (asynchronous reset camera control, frame
grabber-controlled exposure).
#include <iostream>
#include <EGrabber.h>
const double FPS = 150;
void configure() {
Euresys::EGenTL gentl;
Euresys::EGrabber<> grabber(gentl);
// camera configuration
grabber.setString<Euresys::RemoteModule>("TriggerMode", "On"); // 1
grabber.setString<Euresys::RemoteModule>("TriggerSource", "CXPin"); // 2
grabber.setString<Euresys::RemoteModule>("ExposureMode", "TriggerWidth"); // 3
// frame grabber configuration
grabber.setString<Euresys::DeviceModule>("CameraControlMethod", "RG"); // 4
grabber.setString<Euresys::DeviceModule>("CycleTriggerSource", "Immediate"); // 5
grabber.setFloat<Euresys::DeviceModule>("CycleTargetPeriod", 1e6 / FPS); // 6
}
int main() {
try {
configure();
} catch (const std::exception &e) {
std::cout << "error: " << e.what() << std::endl;
}
}
1. Enable triggers on the camera.
2. Tell the camera to look for triggers on the CoaXPress link.
3. Configure the camera to use the TriggerWidth exposure mode.
4. Set the frame grabber's camera control method to RG. In this mode, camera cycles are initiated by the frame
grabber, and the exposure duration is also controlled by the frame grabber.
5. Tell the frame grabber to initiate camera cycles itself (at a rate defined by CycleTargetPeriod), without waiting
for hardware or soware triggers.
6. Configure the frame rate.
But there is a better way to configure the grabber. Using a script file, the program becomes:
#include <iostream>
15

Coaxlink Programmer's Guide Euresys::EGrabber
#include <EGrabber.h>
void configure() {
Euresys::EGenTL gentl;
Euresys::EGrabber<> grabber(gentl);
grabber.runScript("config.js");
}
int main() {
try {
configure();
} catch (const std::exception &e) {
std::cout << "error: " << e.what() << std::endl;
}
}
and the configuration script is:
var grabber = grabbers[0];
var FPS = 150;
// camera configuration
grabber.RemotePort.set("TriggerMode", "On");
grabber.RemotePort.set("TriggerSource", "CXPin");
grabber.RemotePort.set("ExposureMode", "TriggerWidth");
// frame grabber configuration
grabber.DevicePort.set("CameraControlMethod", "RG");
grabber.DevicePort.set("CycleTriggerSource", "Immediate");
grabber.DevicePort.set("CycleTargetPeriod", 1e6 / FPS);
Using a script file has several advantages:
• The configuration can be changed without recompiling the application. This allows shorter development cycles,
and makes it possible to update the configuration in the lab or in the field.
• The configuration script can be loaded by the GenICam Browser and the command-line gentl tool. This makes is
possible to validate the configuration outside of the user application.
• The configuration script can easily be shared by several applications written in different programming languages:
C++, C#, VB.NET...
• The full power of Euresys GenApi scripts is available.
Events
Background
Coaxlink cards generate different kinds of events:
•New buffer events: events indicating that a buffer has been filled by a data stream.
•Data stream events: events related to a data stream and its frame store.
•Camera and illumination controller events: events related to the real-time control (performed by a device) of a
camera and its illumination devices.
•I/O toolbox events: events (coming from the interface) related to digital I/O lines and other I/O tools.
•CoaXPress interface events: events (also coming from the interface) related to the CoaXPress interface.
Newbuffer events are standard in GenTL. They occur when a buffer is filled by the frame grabber. Information attached
to new buffer events include the handle of the buffer and a timestamp.
The other types of events are restricted to Coaxlink and can be viewed as categories of specific events. For example,
in the CIC category of events, we have:
•CameraTriggerRisingEdge (start of camera trigger)
16

Euresys::EGrabber Coaxlink Programmer's Guide
•CameraTriggerFallingEdge (end of camera trigger)
•StrobeRisingEdge (start of light strobe)
•StrobeFallingEdge (end of light strobe)
•AllowNextCycle (CIC is ready for next camera cycle)
• ...
and in the I/O toolbox category of events, we have:
•LIN1 (line input tool 1)
•LIN2 (line input tool 2)
•MDV1 (multiplier/divider tool 1)
• ...
Counters
Coaxlink firmware counts each occurrence of each event (except new buffer events) and makes this counter available
in a GenApi feature named EventCount. Each event has its own counter, and the value of EventCount depends
on the selected event:
// select the CameraTriggerRisingEdge event
grabber.setString<DeviceModule>("EventSelector", "CameraTriggerRisingEdge");
// read the value of the counter
int64_t counter = grabber.getInteger<DeviceModule>("EventCount");
or, using the selected feature notation:
// read the value of the CameraTriggerRisingEdge counter
int64_t counter = grabber.getInteger<DeviceModule>("EventCount[CameraTriggerRisingEdge]");
Notifications
As we've just seen, when an event occurs, a dedicated counter is incremented. Coaxlink can also notify the application
of this event by having Euresys::EGrabber execute a user-defined callback function. But first, it is required to
enable notifications of one or more events:
grabber.setString<DeviceModule>("EventSelector", "CameraTriggerRisingEdge");
grabber.setInteger<DeviceModule>("EventNotification", true);
grabber.setString<DeviceModule>("EventSelector", "CameraTriggerFallingEdge");
grabber.setInteger<DeviceModule>("EventNotification", true);
...
or:
grabber.setInteger<DeviceModule>("EventNotification[CameraTriggerRisingEdge]", true);
grabber.setInteger<DeviceModule>("EventNotification[CameraTriggerFallingEdge]", true);
...
Using a configuration script, it is easy to enable notifications for all events:
function enableAllEvents(p) { // 1
var events = p.$ee('EventSelector'); // 2
for (var e of events) {
p.set('EventNotification[' + e + ']', true); // 3
17

Coaxlink Programmer's Guide Euresys::EGrabber
}
}
var grabber = grabbers[0];
enableAllEvents(grabber.InterfacePort); // 4
enableAllEvents(grabber.DevicePort); // 5
enableAllEvents(grabber.StreamPort); // 6
1. Define a helper function named enableAllEvents and taking as argument a module (or port) p.
2. Use the $ee function to retrieve the list of values EventSelector can take. This is the list of events generated
by module p. (ee stands for enum entry.)
3. For each event, enable notifications. (The + operator concatenates strings, so if e is 'LIN1', the expression
'EventNotification[' + e + ']' evaluates to 'EventNotification[LIN1]'.)
4. Call the enableAllEvents function defined in step 1 for the interface module. This will enable notifications for
all events in the I/O toolbox and CoaXPress interface categories.
5. Likewise, enable notifications for all events coming from the device module (CIC events).
6. Finally, enable notifications for all data stream events.
Callback functions
When an event occurs, and event notification is enabled for that event, Euresys::EGrabber executes one of
several callback functions.
These callback functions are defined in overridden virtual methods:
class MyGrabber : public Euresys::EGrabber<>
{
public:
...
private:
// callback function for new buffer events
virtual void onNewBufferEvent(const NewBufferData& data) {
...
}
// callback function for data stream events
virtual void onDataStreamEvent(const DataStreamData &data) {
...
}
// callback function for CIC events
virtual void onCicEvent(const CicData &data) {
...
}
// callback function for I/O toolbox events
virtual void onIoToolboxEvent(const IoToolboxData &data) {
...
}
// callback function for CoaXPress interface events
virtual void onCxpInterfaceEvent(const CxpInterfaceData &data) {
...
}
};
As you can see, a different callback function can be defined for each category of events.
In .NET, callback functions are defined by creating delegates rather than overriding virtual methods. An example will
be given in the chapter about the .NET assembly.
18

Euresys::EGrabber Coaxlink Programmer's Guide
Event identification
When an event is notified to the application, the callback function that is executed indicates the category of that
event. The actual event that occurred is identified by a numerical ID, called numid, and defined in include/
GenTL_v1_5_EuresysCustom.h:
enum EVENT_DATA_NUMID_CUSTOM_LIST
{
// EVENT_CUSTOM_IO_TOOLBOX
EVENT_DATA_NUMID_IO_TOOLBOX_LIN1 = ... /* Line Input Tool 1 */
EVENT_DATA_NUMID_IO_TOOLBOX_LIN2 = ... /* Line Input Tool 2 */
EVENT_DATA_NUMID_IO_TOOLBOX_MDV1 = ... /* Multiplier/Divider Tool 1 */
...
// EVENT_CUSTOM_CXP_INTERFACE
...
// EVENT_CUSTOM_CIC
EVENT_DATA_NUMID_CIC_CAMERA_TRIGGER_RISING_EDGE = ... /* Start of camera trigger */
EVENT_DATA_NUMID_CIC_CAMERA_TRIGGER_FALLING_EDGE = ... /* End of camera trigger */
EVENT_DATA_NUMID_CIC_STROBE_RISING_EDGE = ... /* Start of light strobe */
EVENT_DATA_NUMID_CIC_STROBE_FALLING_EDGE = ... /* End of light strobe */
...
// EVENT_CUSTOM_DATASTREAM
EVENT_DATA_NUMID_DATASTREAM_START_OF_CAMERA_READOUT = ... /* Start of camera readout */
EVENT_DATA_NUMID_DATASTREAM_END_OF_CAMERA_READOUT = ... /* End of camera readout */
...
};
For reference, the following tables list, for each module generating events and for each category of events, the
relationships with:
• the name of the callback function
• the data type passed to the callback function
• the common numid prefix
Note: A simple naming scheme is followed: a category of events named some category has a callback
function named on SomeCategory Event which takes as argument a SomeCategory Data structure,
and uses EVENT_DATA_NUMID_ SOME_CATEGORY _as common numid prefix.
Data stream module – New Buffer category
Callback function Data type numid prefix
onNewBufferEvent NewBufferData -
Note: There is only one event in the new buffer event category, so we don't need a numid there.
Data stream module – Data Stream category
Callback function Data type numid prefix
onDataStreamEvent DataStreamData EVENT_DATA_NUMID_DATASTREAM_
Device module – CIC category
Callback function Data type numid prefix
onCicEvent CicData EVENT_DATA_NUMID_CIC_
19

Coaxlink Programmer's Guide Euresys::EGrabber
Interface module – I/O Toolbox category
Callback function Data type numid prefix
onIoToolboxEvent IoToolboxData EVENT_DATA_NUMID_IO_TOOLBOX_
Interface module – CXP Interface category
Callback function Data type numid prefix
onCxpInterfaceEvent CxpInterfaceData EVENT_DATA_NUMID_CXP_INTERFACE_
Examples
We'll soon show a few complete example programs illustrating events and callbacks, but there is one more thing we
need to explain before we can do that: the context in which callback functions are executed. This is the subject of the
next section.
EGrabber flavors
When should the callback functions be called? From which context (i.e., which thread)? Thinking about these questions
leads to the definition of several callback models:
• The application asks the grabber: "Do you have any buffer or event for me? If yes, execute my callback
functionnow." This is a polling, synchronous mode of operation, where callbacks are executed when the application
demands it, in the application thread.
We'll refer to this callback model as on demand.
• The application asks the grabber to create a single, dedicated thread, and to wait for events in this thread. When an
event occurs, the grabber executes the corresponding callback function, also in this single callback thread.
We'll refer to this callback model as single thread.
• The application asks the grabber to create a dedicated thread for each of its callback functions. In each of these
threads, the grabber waits for a particular category of events. When an event occurs, the corresponding callback
function is executed in that thread.
We'll refer to this callback model as multi thread.
These three callback models all make sense, and each one is best suited for some applications.
• The on demand model is the simplest. Although its implementation may use worker threads, from the point of view
of the user it doesn't add any thread. This means that the application doesn't need to worry about things such as
thread synchronization, mutexes, etc.
• If the user wants a dedicated callback thread, the single thread model creates it for him.
When we have only one thread, things are simple. In this model, the grabber is used in (at least) two threads, so we
need to start worrying about synchronization and shared data.
• In the multi thread model, each category of event gets its own thread. The benefit of this is that events of one
type (and the execution of their callback functions) don't delay notifications of events of other types. For example,
a thread doing heavy image processing in onNewBufferEvent will not delay the notification of CIC events by
onCicEvent (e.g., events indicating that the exposure is complete and that the object or camera can be moved).
In this model, the grabber is used in several thread, so the need for synchronization is present as it is in the single
thread model.
20
Table of contents
Popular I/O System manuals by other brands

Zeta Alarm Limited
Zeta Alarm Limited SmartConnect SCM-RM instruction manual

WAGO
WAGO 750-8207 manual

Centralized Network Control
Centralized Network Control CIG1-IOC01-0A-01-00 Hardware user manual

Allen-Bradley
Allen-Bradley 1794-IM8 installation instructions

WAGO
WAGO 765-4203/0100-0000 product manual

FieldPoint
FieldPoint FP-AI-100 operating instructions