Impact Acquire SDK C++
Callbacks Triggered By GenICam™ Events
Note
This use case applies only to devices operating in GenICam™ interface layout. More details at chapter General and Which Interface Is Supported By Which Device?.

In some cases it is interesting to get notified about the occurrence of a certain event (e.g. a trigger signal or the end of an image being exposed) on the camera side as soon as possible. This can be achieved by using the events specified by the GenICam™ standard in combination with callbacks.

Note
More details regarding the usage of callbacks are explained at the example Callback.cpp.

Depending on the firmware version the following events are currently supported:

  • General events:
    • EventExposureEnd
    • EventFrameEnd
  • Digital I/O related events:
    • EventLine4RisingEdge
    • EventLine4FallingEdge
    • EventLine4AnyEdge
    • EventLine5RisingEdge
    • EventLine5FallingEdge
    • EventLine5AnyEdge

The following example will illustrate how the events can be used to get notified about an image which has been exposed by the sensor, so the image has not been read out yet. This means the information about the finished image is available much earlier than the image itself. Depending on the resolution of the used device and the bandwidth of the used interface the saved time might be significant.

Note
This use case assumes that the image acquisition is already working and the used device supports the GenICam™ interface layout (see Preface for details), similar to the ContinuousCapture.cpp sample.
How it works
  1. The device is opened by calling
    pThreadParameter->pDev->open();
  1. An instance of the EventControl class is created.
  2. The desired GenICam™ event of the device is enabled.
  3. A callback is created.
  4. The callback is registered to the property which should execute the callback once its value or features change.
  5. As soon as the image acquisition starts, the callback will be invoked.

Any application that wants to get notified when a certain feature in the Impact Acquire property tree did change needs to derive a class from mvIMPACT::acquire::ComponentCallback and override the mvIMPACT::acquire::ComponentCallback::execute() method:

//=============================================================================
//================= Event Callback implementation =============================
//=============================================================================
//-----------------------------------------------------------------------------
class EventCallback : public ComponentCallback
{
public:
explicit EventCallback( void* pUserData = 0 ) : ComponentCallback( pUserData ) {}
virtual void execute( Component& c, void* pUserData )
{
try
{
EventControl* ec = reinterpret_cast<EventControl*>( pUserData );
// Execute the followings if the component is a property.
if ( c.isProp() )
{
Property p( c );
// Show the property value in console when the property value changes due to the occurrence of the event.
cout << "Component " << c.name() << " has changed. Its current value: " << p.readS() << "us. FrameID is: " << ec->eventExposureEndFrameID.readS() << endl;
}
}
catch ( const ImpactAcquireException& e )
{
cout << "An error occurred while retrieving the callback value. Error code: " << e.getErrorCodeAsString() << ")." << endl;
}
}
};

In order to be able to do something useful each callback can carry a pointer to arbitrary user data that can be used to get access to any part of the application code within the callback context. This example attaches an instance of the class EventControl to get access to the events properties, when creating the callback handler later.

The event control class needs to be instantiated to get access to switch on the devices GenICam™ events. In this case the "ExposureEndEvent" is enabled and will be sent by the device once the exposure of an image has finished.

EventControl ec( pThreadParameter->pDev );
try
{
ec.eventSelector.writeS( "ExposureEnd" );
ec.eventNotification.writeS( "On" );
}
catch ( const ImpactAcquireException& e )
{
cout << "An error occurred while setting up event control to the device " << pThreadParameter->pDev->serial.read()
<< "(error code: " << e.getErrorCodeAsString() << ").";
}

Now the actual callback handler will be created and a property will be registered to it:

EventCallback eventCallback( &ec );
// register a callback to eventExposureEndTimestamp
eventCallback.registerComponent( ec.eventExposureEndTimestamp );

Once the callback is not needed anymore, it should be unregistered:

// clean up
eventCallback.unregisterComponent( ec.eventExposureEndTimestamp );

The code used for this use case can be found at: GenICamCallbackOnEvent.cpp