| Customize Help

Automatically scheduling an output upon the occurrence of an event



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;
   }