PVCAM  3.9.x
Programmable Virtual Camera Access Method library
Single Image Polling
Warning
Please note the example below describes an obsolete acquisition technique. This mode may not work reliably for large frames and fast frame rates and will not be supported by future PVCAM revisions. Please refer to Single Image Callbacks for a recommended way to acquire single frames.

This sample shows how to acquire a single frame with 'emulated' software trigger (started by a host) and polling for the readout complete status. Using polling is much simpler, since we do not need to register callback function but we strongly recommend using callbacks instead of polling.

The code snippet below initializes PVCAM and opens the first available camera. Please refer to the actual code sample in the SDK installation directory for more details about the common helper functions used in this documentation.

std::vector<CameraContext*> contexts;
if (!InitAndOpenOneCamera(contexts, cSingleCamIndex))
return APP_EXIT_ERROR;
CameraContext* ctx = contexts[cSingleCamIndex];

Prepare the acquisition. The pl_exp_setup_seq function returns the size of the frame buffer required for the entire frame sequence. Since we are only requesting a single frame, the size of one frame will be reported. See Buffer Size and Frame Count Limitations section for possible limitations.

uns32 exposureBytes;
const uns32 exposureTime = 40; // milliseconds
if (PV_OK != pl_exp_setup_seq(ctx->hcam, 1, 1, &ctx->region, exposureMode,
exposureTime, &exposureBytes))
{
PrintErrorMessage(pl_error_code(), "pl_exp_setup_seq() error");
CloseAllCamerasAndUninit(contexts);
return APP_EXIT_ERROR;
}
Note
For detailed information about error handling, please, refer to Getting Error Messages.
This example uses the extended trigger mode configuration and sets up the camera to use internal trigger with first-row expose out mode. However, legacy cameras do not support the extended modes and the list of supported expose out modes may differ as well. It is important to always discover the supported modes using the PARAM_EXPOSURE_MODE and PARAM_EXPOSE_OUT_MODE parameters when working with multiple camera models.

Allocate a buffer of the size reported by the pl_exp_setup_seq function. function.

uns8* frameInMemory = new (std::nothrow) uns8[exposureBytes];
if (!frameInMemory)
{
printf("Unable to allocate buffer for camera %d\n", ctx->hcam);
CloseAllCamerasAndUninit(contexts);
return APP_EXIT_ERROR;
}

Acquire 50 images in a loop:

bool errorOccured = false;
uns32 imageCounter = 0;
while (imageCounter < 50)
{

Start the acquisition. Since the pl_exp_setup_seq was configured to use the internal camera trigger, the acquisition is started immediately. In hardware triggering modes the camera would wait for an external trigger signal.

if (PV_OK != pl_exp_start_seq(ctx->hcam, frameInMemory))
{
PrintErrorMessage(pl_error_code(), "pl_exp_start_seq() error");
errorOccured = true;
break;
}

Keep checking the camera readout status. If readout succeeds, we print out ADU values of the first five pixels. A 'sleep' is used to reduce CPU load as the loop actively checks the status.

int16 status;
uns32 byte_cnt;
while (PV_OK == pl_exp_check_status(ctx->hcam, &status, &byte_cnt)
&& status != READOUT_COMPLETE && status != READOUT_NOT_ACTIVE
&& !ctx->threadAbortFlag)
{
printf("Waiting 20ms for frame #%u exposure and readout\n",
imageCounter + 1);
std::this_thread::sleep_for(std::chrono::milliseconds(20));
}
if (ctx->threadAbortFlag)
{
// This flag is set on ctrl+c, just break the loop, the acquisition
// is aborted after that
printf("Processing aborted on camera %d\n", ctx->hcam);
break;
}
if (status == READOUT_FAILED)
{
printf("Frame #%u readout failed on camera %d\n",
imageCounter + 1, ctx->hcam);
errorOccured = true;
break;
}
printf("Frame #%u readout successfully completed on camera %d\n",
imageCounter + 1, ctx->hcam);
ShowImage(ctx, frameInMemory, exposureBytes);
Warning
Removing the sleep or setting it to a value too low such as 1ms or hundreds of microseconds significantly increases the CPU load and still doesn't guarantee the code won't miss a frame if the frame rate is too high.

Call the pl_exp_finish_seq after completing the sequence.

if (PV_OK != pl_exp_finish_seq(ctx->hcam, frameInMemory, 0))
PrintErrorMessage(pl_error_code(), "pl_exp_finish_seq() error");
imageCounter++;
} // End of while loop

Although the sequence acquisition with single frame goes automatically to idle state, the main while loop can also be interrupted by the user. For this reason we always call pl_exp_abort. For more details, please, refer to the Closing Camera and Uninitializing PVCAM section.

if (PV_OK != pl_exp_abort(ctx->hcam, CCS_HALT))
PrintErrorMessage(pl_error_code(), "pl_exp_abort() error");
delete [] frameInMemory;
CloseAllCamerasAndUninit(contexts);
if (errorOccured)
return APP_EXIT_ERROR;
return 0;