Matrox Iris GTR supports I/O command lists. An I/O command list is an internal container for MIL I/O commands. For information on I/O command lists, refer to the Using I/O command lists section of Chapter 41: I/O signals and communicating with external devices.
Besides supporting scheduling I/O commands on an individual basis, Matrox Iris GTR supports automatically registering an I/O command every time a specified latch is triggered, and using that latch's value as a reference. To do so, use MsysIoCommandRegister() with an operation, M_AUTO_REGISTER, and M_LATCHn.
In this example, parts are moving along a conveyor belt, but are fixed in their position on the conveyor belt. The parts are always taking 100 rotary steps forward before reaching a camera, which will always acquire an image of the parts. For simplicity, the conveyor belt can only move forward and the camera is an areascan camera.
An I/O command list is used to schedule the acquisition of the image. The rotary decoder output is used as the counter source of the I/O command list so that each time the rotary decoder counts 100 steps (distance that the part travels) after the sensor detects a part, an image is acquired.
// M_AUX_IO14: Receives rotary encoder bit 0
// M_AUX_IO15: Receives rotary encoder bit 1
// M_AUX_IO8 (input): Object detector
// M_AUX_IO0 (output): trigger to the camera, 100 positions after object detector
#define CAMERA_TRIGGER_OFFSET 100 // in rotary encoder steps
MIL_INT MFTYPE ProcessingFunction(MIL_INT HookType, MIL_ID HookId, void* HookDataPtr);
typedef struct _HOOK_PARAM
{
MIL_ID MilSystem;
MIL_ID CmdListId;
} HOOK_PARAM, *PHOOK_PARAM;
// Setup triggered grab.
MdigControl(MilDigitizer, M_GRAB_TRIGGER_SOURCE, M_AUX_IO0);
MdigControl(MilDigitizer, M_GRAB_TRIGGER_ACTIVATION, M_EDGE_RISING);
MdigControl(MilDigitizer, M_GRAB_TRIGGER_STATE, M_ENABLE);
// Setup the rorary decoder; for simplicty, we assume the conveyor cannot move backwards.
MsysControl(SysId, M_ROTARY_ENCODER_BIT0_SOURCE + M_ROTARY_ENCODER1, M_AUX_IO14);
MsysControl(SysId, M_ROTARY_ENCODER_BIT1_SOURCE + M_ROTARY_ENCODER1, M_AUX_IO15);
MsysControl(SysId, M_ROTARY_ENCODER_OUTPUT_MODE + M_ROTARY_ENCODER1, M_STEP_FORWARD);
MsysControl(SysId, M_ROTARY_ENCODER_STATE + M_ROTARY_ENCODER1, M_ENABLE);
// Link the grab trigger to an I/O command register bit.
MsysControl(SysId, M_IO_SOURCE + M_AUX_IO0, M_IO_COMMAND_LIST1 + M_IO_COMMAND_BIT0);
// Allocate an I/O command list where I/O commands are scheduled based on rotary decoder 1's output signal.
CmdListId = MsysIoAlloc(SysId, M_IO_COMMAND_LIST1, M_IO_COMMAND_LIST, M_ROTARY_ENCODER1, M_NULL);
if (CmdListId!= M_NULL)
{
// Latch the counter upon detection of the object
MsysIoControl(CmdListId, M_REFERENCE_LATCH_TRIGGER_SOURCE+M_LATCH1, M_AUX_IO8);
MsysIoControl(CmdListId, M_REFERENCE_LATCH_ACTIVATION+M_LATCH1, M_EDGE_RISING);
MsysIoControl(CmdListId, M_REFERENCE_LATCH_STATE+M_LATCH1, M_ENABLE);
// Every one hundred decoder steps after latch 1 is triggered, two I/O commands
// are automatically added to the I/O command list to change register bit 0,
// such that M_AUX_IO0 outputs an active high pulse.
// Since M_AUX_IO0 is the grab trigger source, a frame will always be grabbed 100
// decoder steps after latch 1 is triggered.
MsysIoCommandRegister(CmdListId, M_PULSE_HIGH+M_AUTO_REGISTER, M_LATCH1, CAMERA_TRIGGER_OFFSET, 1, M_IO_COMMAND_BIT0, M_NULL);
// Start the grabbing and processing.
// The processing function is called each time a frame is grabbed.
MdigProcess(MilDigitizer, MilGrabBufferList, MilGrabBufferListSize,
M_START, M_DEFAULT, ProcessingFunction, &HookParam);
// Print a message and wait for a key press before stopping the processing.
MosPrintf(MIL_TEXT("Press <Enter> to stop. \n\n"));
MosGetch();
HookParam.MilSystem = SysId;
HookParam.CmdListId = CmdListId;
// Stop the grabbing and processing.
MdigProcess(MilDigitizer, MilGrabBufferList, MilGrabBufferListSize,
M_STOP, M_DEFAULT, ProcessingFunction, &HookParam);
// Release the auto-register, so that, if latch 1 is triggered, it will not cause
// an I/O command to be added.
MsysIoCommandRegister(CmdListId, M_PULSE_HIGH + M_AUTO_REGISTER_CANCEL, M_LATCH1, CAMERA_TRIGGER_OFFSET, 1, M_IO_COMMAND_BIT0, M_NULL);
}
// Free the I/O command list.
MsysIoFree(CmdListId);
// Defines the processing function, called by MdigProcess()
MIL_INT MFTYPE ProcessingFunction(MIL_INT HookType, MIL_ID HookId, void* HookDataPtr)
{
PHOOK_PARAM pHookParam = (PHOOK_PARAM)HookDataPtr;
MIL_ID ModifiedBufferId;
/* Retrieve the MIL_ID of the grabbed buffer. */
MdigGetHookInfo(HookId, M_MODIFIED_BUFFER+M_BUFFER_ID, &ModifiedBufferId);
/* Execute the processing */
// ... PUT YOUR PROCESSING FUNCTION HERE
return 0;
}