GrabTrigger#

#include <stdio.h>
#include <stdlib.h>
#include "ItalaApiC/ItalaC.h"

#define ACQUIRE_COUNT 5

ItalaError ErrorManager(ItalaError e) {
  size_t sizeMessage = 255;
  char* message = (char*)malloc(sizeof(char) * sizeMessage);
  ERR_GetLastErrorMessage(message, &sizeMessage);
  printf("\nITALA ERROR (%d):\t%s, %zu char", ERR_GetLastErrorCode(), message, sizeMessage);
  free(message);
  return e;
}

int main(int argc, char** argv) {
  printf("***** Grab trigger example started. *****\n");
  ItalaError error = ItalaErrorSuccess;

  error = SYS_Initialize();
  if (error) return ErrorManager(error);

  size_t devicesInfoSize = 0;
  error = SYS_EnumerateDevices(700);
  if (error) return ErrorManager(error);
  error = SYS_GetDeviceCount(&devicesInfoSize);
  if (error) return ErrorManager(error);
  if (devicesInfoSize == 0) {
    printf("No devices found. Example canceled.\n");
    return ItalaErrorError;
  }
  DeviceInfo deviceInfo;
  error = SYS_GetDeviceByIndex(0, &deviceInfo);
  if (deviceInfo.AccessStatus != AvailableReadWrite) {
    printf("Target device is unaccessible in RW mode. Example canceled.\n");
    return ItalaErrorError;
  }

  H_DEVICE hDevice = NULL;
  error = SYS_CreateDevice(deviceInfo, &hDevice);
  if (error) return ErrorManager(error);
  printf("First device found is initialized.\n\n");
  printf("Configuring trigger mode..\n");

  H_NODEMAP hNodeMap = NULL;
  error = DEV_GetNodeMap(hDevice, &hNodeMap);
  if (error) return ErrorManager(error);

  // Select the "action" that must be performed when the trigger is received.
  H_NODE hNodeTriggerSelector = NULL;
  error = NODEMAP_GetNode(hNodeMap, "TriggerSelector", &hNodeTriggerSelector);
  if (error) return ErrorManager(error);
  bool isWritable = false;
  error = IsNodeWritable(hNodeTriggerSelector, &isWritable);
  if (error) return ErrorManager(error);
  if (!isWritable) {
    printf("Unable to select the trigger type. Aborting.\n");
    return ItalaErrorError;
  }
  error = NODE_FromString(hNodeTriggerSelector, "FrameBurstStart");
  if (error) return ErrorManager(error);

  // Set the source of the trigger. In this case, a software trigger (which is
  // just a command) is used.
  H_NODE hNodeTriggerSource = NULL;
  error = NODEMAP_GetNode(hNodeMap, "TriggerSource", &hNodeTriggerSource);
  if (error) return ErrorManager(error);
  isWritable = false;
  error = IsNodeWritable(hNodeTriggerSource, &isWritable);
  if (error) return ErrorManager(error);
  if (!isWritable) {
    printf("Unable to configure the trigger. Aborting.\n");
    return ItalaErrorError;
  }
  int64_t originalTriggerSource = 0;
  error = NODE_EnumerationGetIntValue(hNodeTriggerSource, &originalTriggerSource);
  if (error) return ErrorManager(error);
  error = NODE_FromString(hNodeTriggerSource, "Software");
  if (error) return ErrorManager(error);

  // Finally, enable the trigger mode.
  H_NODE hNodeTriggerMode = NULL;
  error = NODEMAP_GetNode(hNodeMap, "TriggerMode", &hNodeTriggerMode);
  if (error) return ErrorManager(error);
  isWritable = false;
  error = IsNodeWritable(hNodeTriggerMode, &isWritable);
  if (error) return ErrorManager(error);
  if (!isWritable) {
    printf("Unable to configure the trigger. Aborting.\n");
    return ItalaErrorError;
  }
  int64_t originalTriggerMode = 0;
  error = NODE_EnumerationGetIntValue(hNodeTriggerMode, &originalTriggerMode);
  if (error) return ErrorManager(error);
  error = NODE_FromString(hNodeTriggerMode, "On");
  if (error) return ErrorManager(error);
  error = DEV_StartAcquisition(hDevice);
  if (error) return ErrorManager(error);

  printf("Acquisition started.\n\n");

  H_IMAGE hImage = NULL;
  bool isIncomplete = false;
  H_NODE hNodeTriggerSoftware = NULL;
  for (size_t i = 0; i < ACQUIRE_COUNT; i++) {
    // Send the software trigger to acquire the image.
    error = NODEMAP_GetNode(hNodeMap, "TriggerSoftware", &hNodeTriggerSoftware);
    if (error) return ErrorManager(error);
    isWritable = false;
    error = IsNodeWritable(hNodeTriggerSoftware, &isWritable);
    if (error) return ErrorManager(error);
    if (!isWritable) {
      printf("Unable to send software trigger command. Aborting.\n");
      return ItalaErrorError;
    }
    error = NODE_CommandExecute(hNodeTriggerSoftware);
    printf("\tSoftware trigger sent, image acquired.\n");
    printf("\tPress Enter to grab the acquired image.\n");

    getchar();

    error = DEV_GetNextImage(hDevice, 1000, &hImage);
    if (error) return ErrorManager(error);
    error = IMG_IsIncomplete(hImage, &isIncomplete);
    if (isIncomplete) {
      // Report some info if the image is partially filled.
      printf("\tImage %zu is incomplete.\n", i);
      size_t filled = 0;
      size_t payloadSize = 0;
      uint64_t timestamp = 0;
      error = IMG_GetBytesFilled(hImage, &filled);
      if (error) return ErrorManager(error);
      error = IMG_GetPayloadSize(hImage, &payloadSize);
      if (error) return ErrorManager(error);
      error = IMG_GetTimestamp(hImage, &timestamp);
      if (error) return ErrorManager(error);
      printf("\t\tBytes filled: %zu/%zu", filled, payloadSize);
      printf("\t\tTimestamp: %jd", timestamp);
    } else {
      printf("Image %zu grabbed.\n", i);
    }

    // DO SOMETHING WITH THE IMAGE..

    error = IMG_Dispose(hImage);
    hImage = NULL;
    if (error) ErrorManager(error);
    printf("\n");
  }

  error = DEV_StopAcquisition(hDevice);
  if (error) return ErrorManager(error);

  // Restore the original values
  error = NODE_EnumerationSetIntValue(hNodeTriggerSource, originalTriggerSource);
  if (error) return ErrorManager(error);
  error = NODE_EnumerationSetIntValue(hNodeTriggerMode, originalTriggerMode);
  if (error) return ErrorManager(error);

  error = DEV_Dispose(hDevice);
  hDevice = NULL;
  if (error) return ErrorManager(error);
  printf("Device instance disposed.\n");

  error = SYS_Dispose();
  if (error) return ErrorManager(error);
  printf("System instance disposed.\n");
  return 0;
}