#include <mil.h>
#if M_MIL_USE_WINDOWS
#include <windows.h>
#endif
#if M_MIL_UNICODE_API
#define MosStrncmp wcsncmp
#else
#define MosStrncmp strncmp
#endif
typedef struct
{
MIL_ID MilDigitizer;
MIL_ID MilImageDisp;
MIL_INT ProcessedImageCount;
MIL_TEXT_PTR* Events;
MIL_INT EventCount;
MIL_DOUBLE TimeStamp;
} HookDataStruct;
void GetCameraEventControls(MIL_ID MilDigitizer, MIL_INT& SupportedEventCount,
MIL_TEXT_PTR** Events, bool& StandardEventEnable);
void HookToEvent(MIL_ID MilDigitizer, MIL_TEXT_PTR Event, void* HookDataPtr,
bool StandardEventEnable, MIL_INT Unhook = 0);
void EventTypeLookUp(MIL_ID MilDigitizer, MIL_ID HookId, HookDataStruct* HookDataPtr);
void DoAcquisition(MIL_ID MilSystem, MIL_ID MilDigitizer, MIL_ID MilImageDisp);
MIL_INT MFTYPE ProcessingFunction(MIL_INT HookType,
MIL_ID HookId,
void* HookDataPtr);
MIL_INT MFTYPE CameraEventHandler(MIL_INT HookType,
MIL_ID HookId,
void* HookDataPtr);
int MosMain(void)
{
MIL_ID MilApplication,
MilSystem,
MilDisplay,
MilDigitizer,
MilImage;
MIL_INT BoardType, EventCount, Done = 0;
MIL_TEXT_PTR* Events;
MIL_INT Selection = 0;
bool StandardEventEnbale = false;
HookDataStruct UserHookData;
MappAllocDefault(M_DEFAULT, &MilApplication, &MilSystem, &MilDisplay, &MilDigitizer, M_NULL);
MbufAllocColor(MilSystem,
MdigInquire(MilDigitizer, M_SIZE_BAND, M_NULL),
MdigInquire(MilDigitizer, M_SIZE_X, M_NULL),
MdigInquire(MilDigitizer, M_SIZE_Y, M_NULL),
MdigInquire(MilDigitizer, M_TYPE, M_NULL),
M_IMAGE+M_DISP+M_GRAB,
&MilImage);
MosPrintf(MIL_TEXT("------------------------------------------------------------\n\n"));
MsysInquire(MilSystem, M_BOARD_TYPE, &BoardType);
if(((BoardType & M_BOARD_TYPE_MASK) == M_GIGE_VISION) || ((BoardType & M_BOARD_TYPE_MASK) == M_USB3_VISION))
MosPrintf(MIL_TEXT("Matrox Driver for GigE/USB3 Vision - Camera event example\n\n"));
else
{
MosPrintf(MIL_TEXT("This example program can only be used with the Matrox Driver for ")
MIL_TEXT("GigE Vision or USB3 Vision.\n"));
MosPrintf(MIL_TEXT("Please ensure that the default system type is set accordingly in ")
MIL_TEXT("MIL Config.\n"));
MosPrintf(MIL_TEXT("-------------------------------------------------------------\n\n"));
MosPrintf(MIL_TEXT("Press <enter> to quit.\n"));
MosGetch();
MappFreeDefault(MilApplication, MilSystem, MilDisplay, MilDigitizer, MilImage);
return 1;
}
MosPrintf(MIL_TEXT("Press <Enter> to start.\n\n"));
MosGetch();
MappControl(M_DEFAULT, M_ERROR, M_PRINT_DISABLE);
GetCameraEventControls(MilDigitizer, EventCount, &Events, StandardEventEnbale);
MappControl(M_DEFAULT, M_ERROR, M_PRINT_ENABLE);
if(EventCount)
{
do
{
MosPrintf(MIL_TEXT("\nPlease select the event you wish to hook a function to: "));
#if M_MIL_USE_WINDOWS
scanf_s("%ld", &Selection);
#else
scanf("%ld", &Selection);
#endif
if((Selection >= 0) && (Selection < EventCount))
Done = 1;
else
MosPrintf(MIL_TEXT("\nInvalid selection"));
}
while(!Done);
UserHookData.MilDigitizer = MilDigitizer;
UserHookData.MilImageDisp = MilImage;
UserHookData.ProcessedImageCount = 0;
UserHookData.Events = Events;
UserHookData.EventCount = EventCount;
UserHookData.TimeStamp = 0.0;
HookToEvent(MilDigitizer, Events[Selection], &UserHookData, StandardEventEnbale);
MosPrintf(MIL_TEXT("\nAwaiting %s events.\n"), Events[Selection]);
MosPrintf(MIL_TEXT("Press <Enter> to continue.\n"));
MosGetch();
MdispSelect(MilDisplay, MilImage);
MosPrintf(MIL_TEXT("\nPress <Enter> to quit.\n"));
DoAcquisition(MilSystem, MilDigitizer, MilImage);
MosGetch();
HookToEvent(MilDigitizer, Events[Selection], &UserHookData, StandardEventEnbale, M_UNHOOK);
}
if(EventCount)
{
for(MIL_INT i = 0; i < EventCount; i++)
delete [] Events[i];
delete[] Events;
}
MappFreeDefault(MilApplication, MilSystem, MilDisplay, MilDigitizer, MilImage);
return 0;
}
void GetCameraEventControls(MIL_ID MilDigitizer, MIL_INT& SupportedEventCount,
MIL_TEXT_PTR** Events, bool& StandardEventEnable)
{
MIL_TEXT_PTR CameraVendor = M_NULL;
MIL_TEXT_PTR CameraModel = M_NULL;
MIL_TEXT_PTR* EventNotification = M_NULL;
MIL_INT EventCnt = 0, Cnt = 0, Len = 0;
bool SupportsOn = false, SupportsOff = false;
StandardEventEnable = false;
MdigInquireFeature(MilDigitizer, M_FEATURE_VALUE+M_STRING_SIZE, MIL_TEXT("DeviceVendorName"), M_DEFAULT, &Len);
if(Len)
{
CameraVendor = new MIL_TEXT_CHAR[Len];
MdigInquireFeature(MilDigitizer, M_FEATURE_VALUE, MIL_TEXT("DeviceVendorName"), M_TYPE_STRING, CameraVendor);
}
Len = 0;
MdigInquireFeature(MilDigitizer, M_FEATURE_VALUE+M_STRING_SIZE, MIL_TEXT("DeviceModelName"), M_DEFAULT, &Len);
if(Len)
{
CameraModel = new MIL_TEXT_CHAR[Len];
MdigInquireFeature(MilDigitizer, M_FEATURE_VALUE, MIL_TEXT("DeviceModelName"), M_TYPE_STRING, CameraModel);
}
MdigInquireFeature(MilDigitizer, M_FEATURE_ENUM_ENTRY_COUNT, MIL_TEXT("EventSelector"), M_DEFAULT, &EventCnt);
if(EventCnt)
{
(*Events) = new MIL_TEXT_PTR [EventCnt];
for(MIL_INT i=0; i<EventCnt; i++)
{
MdigInquireFeature(MilDigitizer, M_FEATURE_ENUM_ENTRY_NAME+M_STRING_SIZE+i, MIL_TEXT("EventSelector"), M_DEFAULT, &Len);
(*Events)[i] = new MIL_TEXT_CHAR[Len];
MdigInquireFeature(MilDigitizer, M_FEATURE_ENUM_ENTRY_NAME+i, MIL_TEXT("EventSelector"), M_DEFAULT, (*Events)[i]);
}
}
MdigInquireFeature(MilDigitizer, M_FEATURE_ENUM_ENTRY_COUNT, MIL_TEXT("EventNotification"), M_DEFAULT, &Cnt);
if(Cnt)
{
EventNotification = new MIL_TEXT_PTR[Cnt];
for(MIL_INT i=0; i<Cnt; i++)
{
MdigInquireFeature(MilDigitizer, M_FEATURE_ENUM_ENTRY_NAME+M_STRING_SIZE+i, MIL_TEXT("EventNotification"), M_DEFAULT, &Len);
EventNotification[i] = new MIL_TEXT_CHAR[Len];
MdigInquireFeature(MilDigitizer, M_FEATURE_ENUM_ENTRY_NAME+i, MIL_TEXT("EventNotification"), M_DEFAULT, EventNotification[i]);
if(MosStrcmp(EventNotification[i], MIL_TEXT("On")) == 0)
SupportsOn = true;
else if(MosStrcmp(EventNotification[i], MIL_TEXT("Off")) == 0)
SupportsOff = true;
}
if(SupportsOn && SupportsOff)
StandardEventEnable = true;
}
MosPrintf(MIL_TEXT("%20s %s %s\n"), MIL_TEXT("Connected to camera:"),
CameraVendor?CameraVendor:MIL_TEXT("N/A"), CameraModel?CameraModel:MIL_TEXT("N/A"));
MosPrintf(MIL_TEXT("%20s "), MIL_TEXT("Supported events:"));
if(EventCnt == 0)
{
MosPrintf(MIL_TEXT("Your camera does not support events.\n\n"));
MosPrintf(MIL_TEXT("Press <Enter> to quit.\n\n"));
MosGetch();
}
else
{
MosPrintf(MIL_TEXT("(0) %s\n"), (*Events)[0]);
for(MIL_INT i = 1; i < EventCnt; i++)
MosPrintf(MIL_TEXT("%20s (%d) %s\n"), MIL_TEXT(""), i, (*Events)[i]);
}
if(Cnt)
{
for(MIL_INT i=0; i<Cnt; i++)
delete [] EventNotification[i];
delete [] EventNotification;
}
if(CameraVendor)
delete [] CameraVendor;
if(CameraModel)
delete [] CameraModel;
SupportedEventCount = EventCnt;
}
void HookToEvent(MIL_ID MilDigitizer, MIL_TEXT_PTR Event, void* HookDataPtr,
bool StandardEventEnable, MIL_INT Unhook )
{
MIL_INT MilHookType = 0;
MIL_INT Error = M_NULL_ERROR;
bool UnknownEventType = false;
if(Unhook)
Unhook = M_UNHOOK;
if(StandardEventEnable)
{
if(MosStrcmp(Event, MIL_TEXT("AcquisitionTrigger")) == 0)
{
MdigHookFunction(MilDigitizer, M_GC_EVENT+M_ACQUISITION_TRIGGER+Unhook, CameraEventHandler, HookDataPtr);
}
else if(MosStrcmp(Event, MIL_TEXT("AcquisitionStart")) == 0)
{
MdigHookFunction(MilDigitizer, M_GC_EVENT+M_ACQUISITION_START+Unhook, CameraEventHandler, HookDataPtr);
}
else if(MosStrcmp(Event, MIL_TEXT("AcquisitionEnd")) == 0)
{
MdigHookFunction(MilDigitizer, M_GC_EVENT+M_ACQUISITION_END+Unhook, CameraEventHandler, HookDataPtr);
}
else if(MosStrcmp(Event, MIL_TEXT("AcquisitionTransferStart")) == 0)
{
MdigHookFunction(MilDigitizer, M_GC_EVENT+M_ACQUISITION_TRANSFER_START+Unhook, CameraEventHandler, HookDataPtr);
}
else if(MosStrcmp(Event, MIL_TEXT("AcquisitionTransferEnd")) == 0)
{
MdigHookFunction(MilDigitizer, M_GC_EVENT+M_ACQUISITION_TRANSFER_END+Unhook, CameraEventHandler, HookDataPtr);
}
else if(MosStrcmp(Event, MIL_TEXT("AcquisitionError")) == 0)
{
MdigHookFunction(MilDigitizer, M_GC_EVENT+M_ACQUISITION_ERROR+Unhook, CameraEventHandler, HookDataPtr);
}
else if(MosStrcmp(Event, MIL_TEXT("FrameTrigger")) == 0)
{
MdigHookFunction(MilDigitizer, M_GC_EVENT+M_FRAME_TRIGGER+Unhook, CameraEventHandler, HookDataPtr);
}
else if(MosStrcmp(Event, MIL_TEXT("FrameStart")) == 0)
{
MdigHookFunction(MilDigitizer, M_GC_EVENT+M_FRAME_START+Unhook, CameraEventHandler, HookDataPtr);
}
else if(MosStrcmp(Event, MIL_TEXT("FrameEnd")) == 0)
{
MdigHookFunction(MilDigitizer, M_GC_EVENT+M_FRAME_END+Unhook, CameraEventHandler, HookDataPtr);
}
else if(MosStrcmp(Event, MIL_TEXT("FrameTransferStart")) == 0)
{
MdigHookFunction(MilDigitizer, M_GC_EVENT+M_FRAME_TRANSFER_START+Unhook, CameraEventHandler, HookDataPtr);
}
else if(MosStrcmp(Event, MIL_TEXT("FrameTransferEnd")) == 0)
{
MdigHookFunction(MilDigitizer, M_GC_EVENT+M_FRAME_TRANSFER_END+Unhook, CameraEventHandler, HookDataPtr);
}
else if(MosStrcmp(Event, MIL_TEXT("ExposureStart")) == 0)
{
MdigHookFunction(MilDigitizer, M_GC_EVENT+M_EXPOSURE_START+Unhook, CameraEventHandler, HookDataPtr);
}
else if(MosStrcmp(Event, MIL_TEXT("ExposureEnd")) == 0)
{
MdigHookFunction(MilDigitizer, M_GC_EVENT+M_EXPOSURE_END+Unhook, CameraEventHandler, HookDataPtr);
}
else if(MosStrncmp(Event, MIL_TEXT("Counter"), MosStrlen(MIL_TEXT("Counter"))) == 0)
{
MIL_TEXT_CHAR String1[256];
MIL_TEXT_CHAR String2[256];
MIL_INT Count = 0;
MdigInquireFeature(MilDigitizer, M_FEATURE_ENUM_ENTRY_COUNT, MIL_TEXT("CounterSelector"), M_DEFAULT, &Count);
for(int i=0; i<Count && MilHookType == 0; i++)
{
MosSprintf(String1, 256, MIL_TEXT("Counter%dStart"), i);
MosSprintf(String2, 256, MIL_TEXT("Counter%dEnd"), i);
if(MosStrcmp(Event, String1) == 0)
MilHookType = M_GC_EVENT+M_COUNTER_START;
else if(MosStrcmp(Event, String2) == 0)
MilHookType = M_GC_EVENT+M_COUNTER_END;
}
if(MilHookType)
MdigHookFunction(MilDigitizer, MilHookType+Unhook, CameraEventHandler, HookDataPtr);
else
UnknownEventType = true;
}
else if(MosStrncmp(Event, MIL_TEXT("Timer"), MosStrlen(MIL_TEXT("Timer"))) == 0)
{
MIL_TEXT_CHAR String1[256];
MIL_TEXT_CHAR String2[256];
MIL_INT Count = 0;
MdigInquireFeature(MilDigitizer, M_FEATURE_ENUM_ENTRY_COUNT, MIL_TEXT("TimerSelector"), M_DEFAULT, &Count);
for(int i=0; i<Count && MilHookType == 0; i++)
{
MosSprintf(String1, 256, MIL_TEXT("Timer%dStart"), i);
MosSprintf(String2, 256, MIL_TEXT("Timer%dEnd"), i);
if(MosStrcmp(Event, String1) == 0)
MilHookType = M_GC_EVENT+M_TIMER_START;
else if(MosStrcmp(Event, String2) == 0)
MilHookType = M_GC_EVENT+M_TIMER_END;
}
if(MilHookType)
MdigHookFunction(MilDigitizer, MilHookType+Unhook, CameraEventHandler, HookDataPtr);
else
UnknownEventType = true;
}
else if(MosStrncmp(Event, MIL_TEXT("Line"), MosStrlen(MIL_TEXT("Line"))) == 0)
{
MIL_TEXT_CHAR String1[256];
MIL_TEXT_CHAR String2[256];
MIL_TEXT_CHAR String3[256];
MIL_INT Count = 0;
MdigInquireFeature(MilDigitizer, M_FEATURE_ENUM_ENTRY_COUNT, MIL_TEXT("LineSelector"), M_DEFAULT, &Count);
for(int i=0; i<Count && MilHookType == 0; i++)
{
MosSprintf(String1, 256, MIL_TEXT("Line%dRisingEdge"), i);
MosSprintf(String2, 256, MIL_TEXT("Line%dFallingEdge"), i);
MosSprintf(String3, 256, MIL_TEXT("Line%dAnyEdge"), i);
if(MosStrcmp(Event, String1) == 0)
MilHookType = M_GC_EVENT+M_LINE_RISING_EDGE;
else if(MosStrcmp(Event, String2) == 0)
MilHookType = M_GC_EVENT+M_LINE_FALLING_EDGE;
else if(MosStrcmp(Event, String3) == 0)
MilHookType = M_GC_EVENT+M_LINE_ANY_EDGE;
}
if(MilHookType)
MdigHookFunction(MilDigitizer, MilHookType+Unhook, CameraEventHandler, HookDataPtr);
else
UnknownEventType = true;
}
else
{
UnknownEventType = true;
}
}
if((StandardEventEnable == false) || UnknownEventType)
{
MappControl(M_DEFAULT, M_ERROR, M_PRINT_DISABLE);
MdigHookFunction(MilDigitizer, M_GC_EVENT+Unhook, CameraEventHandler, HookDataPtr);
MdigControlFeature(MilDigitizer, M_FEATURE_VALUE_AS_STRING, MIL_TEXT("EventSelector"), M_DEFAULT, Event);
if(!Unhook)
{
MdigControlFeature(MilDigitizer, M_FEATURE_VALUE_AS_STRING, MIL_TEXT("EventNotification"), M_DEFAULT, MIL_TEXT("On"));
MappGetError(M_DEFAULT, M_CURRENT+M_THREAD_CURRENT, &Error);
if(Error != M_NULL_ERROR)
{
MosPrintf(MIL_TEXT("\nThe %s feature as implemented by the camera manufacturer lacks\n"), Event);
MosPrintf(MIL_TEXT("standard \"EventNotification\" support. Make sure the event is enabled using\n"));
MosPrintf(MIL_TEXT("the feature browser before continuing.\n\n"));
MosPrintf(MIL_TEXT("Some older camera models might require \"EventNotification\" to be set to\n"));
MosPrintf(MIL_TEXT("\"GigEVisionEvent\" or \"GenICamEvent\" for event notification to occur.\n"));
MdigControl(MilDigitizer, M_GC_FEATURE_BROWSER, M_OPEN+M_ASYNCHRONOUS);
}
}
else
MdigControlFeature(MilDigitizer, M_FEATURE_VALUE_AS_STRING, MIL_TEXT("EventNotification"), M_DEFAULT, MIL_TEXT("Off"));
MappControl(M_DEFAULT, M_ERROR, M_PRINT_ENABLE);
}
}
void EventTypeLookUp(MIL_ID MilDigitizer, MIL_ID HookId, HookDataStruct* HookDataPtr)
{
MIL_TEXT_CHAR String[256];
bool Found = false;
MIL_DOUBLE EventTimeStamp;
MIL_INT EventType;
MIL_INT64 LocalEventType = 0;
MdigGetHookInfo(HookId, M_GC_EVENT_TYPE, &EventType);
MdigGetHookInfo(HookId, M_GC_CAMERA_TIME_STAMP, &EventTimeStamp);
MappControl(M_DEFAULT, M_ERROR, M_PRINT_DISABLE);
for(MIL_INT i=0; i<HookDataPtr->EventCount && !Found; i++)
{
MosSprintf(String, 256, MIL_TEXT("Event%s"), HookDataPtr->Events[i]);
MdigInquireFeature(MilDigitizer, M_FEATURE_VALUE, String, M_TYPE_INT64, &LocalEventType);
if(LocalEventType == EventType)
{
MosPrintf(MIL_TEXT("Received %s event. Interval from last: %.6f sec.\n"),
HookDataPtr->Events[i], EventTimeStamp-HookDataPtr->TimeStamp);
Found = true;
}
}
MappControl(M_DEFAULT, M_ERROR, M_PRINT_ENABLE);
if(Found == false)
MosPrintf(MIL_TEXT("Event #%d received. Interval from last: %.6f sec.\n"),
EventType, EventTimeStamp-HookDataPtr->TimeStamp);
HookDataPtr->TimeStamp = EventTimeStamp;
}
void DoAcquisition(MIL_ID MilSystem, MIL_ID MilDigitizer, MIL_ID MilImageDisp)
{
MIL_INT NbFrames = 10;
MIL_INT MilGrabBufferListSize;
MIL_INT Done = 0;
MIL_INT Ch = 0;
MIL_ID* MilGrabBufferList = NULL;
HookDataStruct UserHookData;
MilGrabBufferList = new MIL_INT[(NbFrames==M_INFINITE) ? 10 : NbFrames];
MappControl(M_DEFAULT, M_ERROR, M_PRINT_DISABLE);
for(MilGrabBufferListSize = 0;
MilGrabBufferListSize<NbFrames; MilGrabBufferListSize++)
{
MbufAlloc2d(MilSystem,
MdigInquire(MilDigitizer, M_SIZE_X, M_NULL),
MdigInquire(MilDigitizer, M_SIZE_Y, M_NULL),
8+M_UNSIGNED,
M_IMAGE+M_GRAB+M_PROC,
&MilGrabBufferList[MilGrabBufferListSize]);
if (MilGrabBufferList[MilGrabBufferListSize])
{
MbufClear(MilGrabBufferList[MilGrabBufferListSize], 0xFF);
}
else
break;
}
MappControl(M_DEFAULT, M_ERROR, M_PRINT_ENABLE);
UserHookData.MilDigitizer = MilDigitizer;
UserHookData.MilImageDisp = MilImageDisp;
UserHookData.ProcessedImageCount = 0;
MdigProcess(MilDigitizer, MilGrabBufferList, MilGrabBufferListSize,
M_START, M_DEFAULT, ProcessingFunction, &UserHookData);
MosGetch();
MdigProcess(MilDigitizer, MilGrabBufferList, MilGrabBufferListSize,
Done ? M_STOP : M_STOP+M_WAIT, M_DEFAULT, ProcessingFunction, &UserHookData);
while(MilGrabBufferListSize > 0)
MbufFree(MilGrabBufferList[--MilGrabBufferListSize]);
delete [] MilGrabBufferList;
}
#define STRING_LENGTH_MAX 20
#define STRING_POS_X 20
#define STRING_POS_Y 20
MIL_INT MFTYPE ProcessingFunction(MIL_INT HookType,
MIL_ID HookId,
void* HookDataPtr)
{
HookDataStruct *UserHookDataPtr = (HookDataStruct *)HookDataPtr;
MIL_ID ModifiedBufferId;
MIL_TEXT_CHAR Text[STRING_LENGTH_MAX]= {MIL_TEXT('\0'),};
MdigGetHookInfo(HookId, M_MODIFIED_BUFFER+M_BUFFER_ID, &ModifiedBufferId);
UserHookDataPtr->ProcessedImageCount++;
MosSprintf(Text, STRING_LENGTH_MAX, MIL_TEXT("%ld"),
UserHookDataPtr->ProcessedImageCount);
MgraText(M_DEFAULT, ModifiedBufferId, STRING_POS_X, STRING_POS_Y, Text);
MbufCopy(ModifiedBufferId, UserHookDataPtr->MilImageDisp);
return 0;
}
MIL_INT MFTYPE CameraEventHandler(MIL_INT HookType,
MIL_ID HookId,
void* HookDataPtr)
{
HookDataStruct *UserHookDataPtr = (HookDataStruct *)HookDataPtr;
EventTypeLookUp(UserHookDataPtr->MilDigitizer, HookId, UserHookDataPtr);
return 0;
}