Impact Acquire SDK .NET
GenICamCallbackOnEvent.cs

The GenICamCallbackOnEvent program is a simple example which illustrates how GenICam™ events can be used to inform an application about a certain event via a callback.

How it works:
  1. Open the device by calling
    pDev.open();
  2. Enable GenICam™ events.
  3. Attach a custom callback to the ExposureEndTimestamp property that gets called whenever a property is modified.
  4. Start the image acquisition in order to cause the callbacks to get triggered.

The full explanation regarding the callback usage can be found at the chapter Callbacks Triggered By GenICam™ Events .

Source code
using mv.impact.acquire.examples.helper;
using System;
using System.Threading;
namespace GenICamCallbackOnEvent
{
public class EventCallback : ComponentCallback
{
public EventCallback(Object pUserData) : base(pUserData) { }
// Please carefully read the documentation of the base class (mv.impact.acquire.ComponentCallback) and the documentation of the
// mv.impact.acquire.ComponentCallback.execute function in particular to avoid unpleasant surprises!
public override void execute(Component c, Object pUserData)
{
try
{
// re-generating the object/data previously attached to the callback object. This could now be used to call a certain member function e.g. to update a class instance about this event!
EventControl ec = (EventControl)pUserData;
// Execute the followings if the component is a property.
if (c.isProp)
{
Property p = new Property(c.hObj);
// Show the property value in console when the property value changes due to the occurrence of the event.
Console.WriteLine("Component " + c.name + " has changed. Its current value: " + p.readS() + "us. FrameID is: " + ec.eventExposureEndFrameID.readS());
}
}
{
Console.WriteLine("An error occurred while retrieving the callback value. Error code: " + e.Message + ").");
}
}
static void Main(string[] args)
{
mv.impact.acquire.LibraryPath.init(); // this will add the folders containing unmanaged libraries to the PATH variable.
Device pDev = DeviceAccess.getDeviceFromUserInput();
if (pDev == null)
{
Console.WriteLine("Unable to continue! Press any key to end the program.");
Console.Read();
Environment.Exit(1);
}
Console.WriteLine("Initialising the device. This might take some time...");
try
{
pDev.open();
}
{
// this e.g. might happen if the same device is already opened in another process...
Console.WriteLine("An error occurred while opening the device " + pDev.serial +
"(error code: " + e.Message + "). Press any key to end the application...");
Console.ReadLine();
Environment.Exit(1);
}
EventControl ec = new EventControl(pDev);
try
{
ec.eventSelector.writeS("ExposureEnd");
ec.eventNotification.writeS("On");
}
{
Console.WriteLine("An error occurred while setting up event control to the device " + pDev.serial.read()
+ "(error code: " + e.Message + ").");
}
#if USE_DISPLAY
ImageDisplayWindow window = new ImageDisplayWindow(String.Format("mvIMPACT_acquire sample, Device {0}", pDev.serial.read()));
#endif // #if USE_DISPLAY
bool terminated = false;
Console.WriteLine("Press [ENTER] to end the application");
EventCallback eventCallback = new EventCallback(ec);
// register a callback to eventExposureEndTimestamp
eventCallback.registerComponent(ec.eventExposureEndTimestamp);
Thread thread = new Thread(delegate ()
{
// create an interface to the device found
// Send all requests to the capture queue. There can be more than 1 queue for some devices, but for this sample
// we will work with the default capture queue. If a device supports more than one capture or result
// queue, this will be stated in the manual. If nothing is mentioned about it, the device supports one
// queue only. This loop will send all requests currently available to the driver. To modify the number of requests
// use the property mv.impact.acquire.SystemSettings.requestCount at runtime (note that some devices will
// only allow to modify this parameter while NOT streaming data!) or the property
// mv.impact.acquire.Device.defaultRequestCount BEFORE opening the device.
TDMR_ERROR result = TDMR_ERROR.DMR_NO_ERROR;
while ((result = (TDMR_ERROR)fi.imageRequestSingle()) == TDMR_ERROR.DMR_NO_ERROR) { };
if (result != TDMR_ERROR.DEV_NO_FREE_REQUEST_AVAILABLE)
{
Console.WriteLine("'FunctionInterface.imageRequestSingle' returned with an unexpected result: {0}({1})", result, ImpactAcquireException.getErrorCodeAsString(result));
}
DeviceAccess.manuallyStartAcquisitionIfNeeded(pDev, fi);
// run thread loop
Request pRequest = null;
// we always have to keep at least 2 images as the display module might want to repaint the image, thus we
// cannot free it unless we have a assigned the display to a new buffer.
Request pPreviousRequest = null;
int timeout_ms = 500;
int requestNr = Device.INVALID_ID;
while (!terminated)
{
// wait for results from the default capture queue
requestNr = fi.imageRequestWaitFor(timeout_ms);
pRequest = fi.isRequestNrValid(requestNr) ? fi.getRequest(requestNr) : null;
if (pRequest != null)
{
if (pRequest.isOK)
{
#if USE_DISPLAY
# if CLR_AT_LEAST_3_DOT_5
// Extension methods are not supported by CLR versions smaller than 3.5 and this next function
// is therefore not available then.
window.imageDisplay.SetImage(pRequest);
# else
// If extension methods are not available, the following function can be used instead. It is
// not as convenient and will only work for some pixel formats. For more complex pixel formats
// use other overloads of this method
window.imageDisplay.SetImage(pRequest.imageData.read(), pRequest.imageWidth.read(), pRequest.imageHeight.read(), pRequest.imageBytesPerPixel.read() * 8, pRequest.imageLinePitch.read());
# endif
window.imageDisplay.Update();
#endif // #if USE_DISPLAY
}
else
{
Console.WriteLine("Error: {0}", pRequest.requestResult.readS());
}
if (pPreviousRequest != null)
{
// this image has been displayed thus the buffer is no longer needed...
pPreviousRequest.unlock();
}
pPreviousRequest = pRequest;
// send a new image request into the capture queue
}
//else
//{
// Please note that slow systems or interface technologies in combination with high resolution sensors
// might need more time to transmit an image than the timeout value which has been passed to imageRequestWaitFor().
// If this is the case simply wait multiple times OR increase the timeout(not recommended as usually not necessary
// and potentially makes the capture thread less responsive) and rebuild this application.
// Once the device is configured for triggered image acquisition and the timeout elapsed before
// the device has been triggered this might happen as well.
// The return code would be -2119(DEV_WAIT_FOR_REQUEST_FAILED) in that case, the documentation will provide
// additional information under TDMR_ERROR in the interface reference.
// If waiting with an infinite timeout(-1) it will be necessary to call 'imageRequestReset' from another thread
// to force 'imageRequestWaitFor' to return when no data is coming from the device/can be captured.
// Console.WriteLine("imageRequestWaitFor failed ({0}, {1}), timeout value too small?", requestNr, ImpactAcquireException.getErrorCodeAsString(requestNr));
//}
}
DeviceAccess.manuallyStopAcquisitionIfNeeded(pDev, fi);
#if USE_DISPLAY
// stop the display from showing freed memory
window.imageDisplay.RemoveImage();
#endif // #if USE_DISPLAY
// In this sample all the next lines are redundant as the device driver will be
// closed now, but in a real world application a thread like this might be started
// several times an then it becomes crucial to clean up correctly.
// free the last potentially locked request
if (pRequest != null)
{
pRequest.unlock();
}
// clear all queues
});
thread.Start();
Console.ReadLine();
terminated = true;
// clean up
eventCallback.unregisterComponent(ec.eventExposureEndTimestamp);
thread.Join();
#if USE_DISPLAY
window.Dispose();
#endif // #if USE_DISPLAY
}
}
}
String name
Returns the name of the component referenced by this object.
Definition ComponentAccess.cs:167
int hObj
Returns a unique identifier for the component referenced by this object.
Definition ComponentAccess.cs:155
A simple helper class to wrap the creation of a callback object.
Definition ComponentCallback.cs:108
A base class to implement access to internal driver components.
Definition Component.cs:133
bool isProp
Checks if this component is of type mv.impact.acquire.Property or a derived type.
Definition Component.cs:708
This class and its functions represent an actual device detected by this interface in the current sys...
Definition Device.cs:91
const int INVALID_ID
A symbolic constant to define an invalid handle.
Definition Device.cs:177
void open()
Opens a device.
Definition Device.cs:208
readonly PropertyS serial
A string property (read-only) containing the serial number of this device.
Definition Device.cs:515
T read()
Reads a value from a property.
Definition EnumPropertyI.cs:342
The function interface to devices supported by this interface.
Definition FunctionInterface.cs:21
int imageRequestSingle()
Sends an image request to the mv.impact.acquire.Device driver.
Definition FunctionInterface.cs:656
Request getRequest(int nr)
Returns a const pointer to the desired mv.impact.acquire.Request.
Definition FunctionInterface.cs:452
int imageRequestWaitFor(int timeout_ms)
Waits for a request object to become ready.
Definition FunctionInterface.cs:1021
int imageRequestReset(int requestCtrlNr)
Deletes all requests currently queued for the specified mv.impact.acquire.ImageRequestControl.
Definition FunctionInterface.cs:575
bool isRequestNrValid(int nr)
Check if nr specifies a valid mv.impact.acquire.Request.
Definition FunctionInterface.cs:1098
Category that contains Event control features.
Definition mvIMPACT_acquire_GenICam.autogen.cs:5321
readonly mv.impact.acquire.PropertyI64 eventExposureEndFrameID
An integer property. Returns the unique Identifier of the Frame (or image) that generated the Exposur...
Definition mvIMPACT_acquire_GenICam.autogen.cs:6459
readonly mv.impact.acquire.PropertyI64 eventNotification
An enumerated integer property. Activate or deactivate the notification to the host application of th...
Definition mvIMPACT_acquire_GenICam.autogen.cs:6114
readonly mv.impact.acquire.PropertyI64 eventExposureEndTimestamp
An integer property. Returns the Timestamp of the Exposure End Event.
Definition mvIMPACT_acquire_GenICam.autogen.cs:6454
readonly mv.impact.acquire.PropertyI64 eventSelector
An enumerated integer property. Selects which Event to signal to the host application.
Definition mvIMPACT_acquire_GenICam.autogen.cs:6100
An base class for exceptions generated by Impact Acquire.
Definition Exceptions.cs:9
static String getErrorCodeAsString(int errorCode)
Returns a string representation of a error.
Definition Exceptions.cs:48
A small helper class to administer various library search path related variables and paths.
Definition LibraryPath.cs:14
static void init()
Calling this method will add the folders containing unmanaged libraries to the systems library search...
Definition LibraryPath.cs:251
IntPtr read()
Reads a value from a property.
Definition PropertyPtr.cs:49
String read()
Reads a value from a property.
Definition PropertyS.cs:144
A base class for properties.
Definition Property.cs:109
String readS()
Reads data from this property as a string.
Definition Property.cs:303
Contains information about a captured buffer.
Definition Request.cs:77
readonly PropertyPtr imageData
A pointer property (read-only) containing the start address of the image data.
Definition Request.cs:1556
readonly PropertyI imageLinePitch
An integer property (read-only) containing the offset (in bytes) to the next line of each channel bel...
Definition Request.cs:1630
readonly EnumPropertyI< TRequestResult > requestResult
An enumerated integer property (read-only) defining the result of this request.
Definition Request.cs:1210
readonly PropertyI imageWidth
An integer property (read-only) containing the width of the image in pixels.
Definition Request.cs:1668
readonly PropertyI imageBytesPerPixel
An integer property (read-only) containing the number of bytes per pixel in this image.
Definition Request.cs:1654
bool isOK
Convenience function to check if a request has been processed successfully.
Definition Request.cs:1172
readonly PropertyI imageHeight
An integer property (read-only) containing the height of the image in pixels.
Definition Request.cs:1679
int unlock()
Unlocks the request for the driver again.
Definition Request.cs:618
TDMR_ERROR
Errors reported by the device manager.
Definition mvDriverBaseEnums.cs:2374
This namespace contains classes and functions belonging to the GenICam specific part of the image acq...
Definition GenTLDriverConfigurator.cs:6
This namespace contains classes and functions belonging to the image acquisition module of this SDK.
Definition Enumerations.cs:2
Definition Enumerations.cs:2
Definition Enumerations.cs:2