A ring acquisition consists of a buffer list with multiple buffers for storing images. The following figure shows how a buffer list might look for five allocated buffers. As the acquisition begins, images 0 through 4 fill up the buffer list. As more images are acquired, they overwrite the old images in the buffer list with new images. This process continues until the acquisition stops. Refer to the System Memory Versus Online Memory section of this document for more information about how images are examined during acquisition.
All IMAQ acquisitions begin by using IMAQ Init (for LabVIEW) or imgInterfaceOpen and imgSessionOpen (for C) to initialize the IMAQ device. Once the device is initialized, you can configure a ring acquisition. Use the buffer list to allocate the number of images you want in the ring acquisition. The more buffers you allocate, the more time before the list fills with images. When acquisition is faster than image processing, keeping up is impossible, regardless of the number of buffers allocated. As a result, you typically need to allocate only three to five buffers. The buffers serve as a cushion for when the operating system multitasks, which sometimes results in processing taking longer. As long as the average processing time is less than the acquisition rate, the extra buffers help keep the acquisition from catching up to the buffer being processed.
When configuring the buffer list, you can assign a different channel to each buffer for multiple channel devices. You can also specify a skip count for each buffer so it will skip some images before it fills up. The skip count is typically set to 0 for each image and only one channel is used for all buffers.
Because images take up a large amount of memory, IMAQ allows you to manage the memory since you can do this more efficiently than the operating system. The following figure and code snippets for LabVIEW and C illustrate how to set up a standard ring buffer list.
static BUFLIST_ID Bid;
static SESSION_ID Sid;
static INTERFACE_ID Iid;
static Int8* ImaqBuffers[NUM_RING_BUFFERS];
// Create a buffer list with n elements
// Compute the size of the required buffer
imgGetAttribute (Sid, IMG_ATTR_BYTESPERPIXEL, &bytesPerPixel);
bufSize = AcqWinWidth * AcqWinHeight * bytesPerPixel;
/* The following configuration makes theseassignments to the buffer list
- buffer pointer that will contain image
- size of the buffer for buffer element 0
- command to go to next buffer or loop when the last element is reached
for (i = 0; i < NUM_RING_BUFFERS; i++)
imgCreateBuffer(Sid, IMG_HOST_FRAME, bufSize, &ImaqBuffers[i]);
imgSetBufferElement(Bid, i, IMG_BUFF_ADDRESS, (uInt32)ImaqBuffers[i]);
imgSetBufferElement(Bid, i, IMG_BUFF_SIZE, bufSize);
bufCmd = (i == (NUM_RING_BUFFERS - 1)) ? IMG_CMD_LOOP : IMG_CMD_NEXT;
imgSetBufferElement(Bid, i, IMG_BUFF_COMMAND, bufCmd);
// Lock down the buffers contained in the buffer list
// Configure the session to use this buffer list
Both methods allocate the memory inside a For loop and assign properties to each buffer in the list.