Machine Vision

cancel
Showing results for 
Search instead for 
Did you mean: 

Free up CPU time with IMAQ

I try to free up the CPU time while using IMAQ low level functions to display the images. From the "Help on line", there is an example where we must do something like below after we open the session.

// Define attribute for sleep time
#define IMG_ATTR_SLEEPTIME (_IMG_BASE + 0x03F6)

// The below lines are in my codes

// Open the interface and session
imgInterfaceOpen (intName, &Iid);
imgSessionOpen (Iid, &Sid);
// Set the sleep time to free up the CPU in ms
imgSetAttribute (Sid, IMG_ATTR_SLEEPTIME, 50);

Notes : I got all the above code from the on-line help.
Everything work fine, excepting the CPU time was not free up.

Please let me know what's wrong ? Why does imgSetAttribute function does not work ? What's the solution?

Thanks !!!
0 Kudos
Message 1 of 3
(3,680 Views)
Leon.

The first thing I would try it to read the attribute (using the imgGetAttribute function) to make sure it is being set. If it is being set, but the CPU is still running at 100%, there might be something else causing it. An easy way to test this is to run the actual CVI_HL Ring with Sleep example that I think you extracted the example code from. If that code doesn't reduce your CPU load, then we can exclude your particular code from the equation and focus on your system.

Kyle V
Applications Engineer
National Instruments
www.ni.com/ask
0 Kudos
Message 2 of 3
(3,680 Views)
Hi Kyle V,
Yes, I tried to read the attribute (using the imgGetAttribute function). The value is being set correctly.
I can not use the CVI_HL Ring with Sleep example, because I'm not using the trigger. I am using the low level grab example right now. The only modification is that I edit the sleep time to this example. You can look at the code below and search for "Leon" to see all my modification. (I only made 2 changes). I think the main point is that I set the sleep time after I open the session in "int OnGrab (void)". Remember I get this code from the example code as well.
Thanks for your help.




*****************************************************************************/
/* This sample demonstrates how to continuously acquire pictures */
/* using a low level grab operation */
/*****************************************************************************/

#include
#include
#include
#include "llgrab.h"
#define _NIWIN
#include "niimaq.h"


// error checking macro
#define errChk(fCall) if (error = (fCall), error < 0) {goto Error;} else


// Window proc
BOOL CALLBACK ImaqSmplProc(HWND hWnd, UINT iMessage, UINT wParam, LONG lParam);
// Error display function
void DisplayIMAQError(Int32 error);
// Snap Callback
int OnGrab (void);
int OnStop (void);
DWORD ImaqThread(LPDWORD lpdwParam);


// windows GUI globals
static HINSTANCE hInst;
static HWND ImaqSmplHwnd;
static HWND HStop, HGrab, HQuit, HIntfName, HFrameRate;
static HANDLE HThread;


// Imaq globals
static SESSION_ID Sid = 0;
static BUFLIST_ID Bid = 0;
static INTERFACE_ID Iid = 0;
static Int8 *ImaqBuffer=NULL; // acquisiton buffer
static Int8 *CopyBuffer=NULL; // copied acquisition buffer
static Int32 CanvasWidth = 512; // width of the display area
static Int32 CanvasHeight = 384; // height of the display area
static Int32 CanvasTop = 10; // top of the display area
static Int32 CanvasLeft = 10; // left of the display area
static Int32 AcqWinWidth;
static Int32 AcqWinHeight;
static BOOL StopGrab = FALSE;


// Leon - modification for free up CPU time
// Define attribute for sleep time
#define IMG_ATTR_SLEEPTIME (_IMG_BASE + 0x03F6)
// end of Leon's modification


int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow)
{
CHAR ImaqSmplClassName[] = "Imaq Sample";
WNDCLASS ImaqSmplClass;
MSG msg;
HWND hTemp;

// register the main window
hInst = hInstance;
if (!hPrevInstance)
{
ImaqSmplClass.style = CS_HREDRAW | CS_VREDRAW;
ImaqSmplClass.lpfnWndProc = (WNDPROC) ImaqSmplProc;
ImaqSmplClass.cbClsExtra = 0;
ImaqSmplClass.cbWndExtra = 0;
ImaqSmplClass.hInstance = hInstance;
ImaqSmplClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
ImaqSmplClass.hCursor = LoadCursor (NULL, IDC_ARROW);
ImaqSmplClass.hbrBackground = GetStockObject(LTGRAY_BRUSH);
ImaqSmplClass.lpszMenuName = 0;
ImaqSmplClass.lpszClassName = ImaqSmplClassName;

if (!RegisterClass (&ImaqSmplClass))
return (0);
}

// creates the main window
ImaqSmplHwnd = CreateWindow(ImaqSmplClassName, "LLGrab", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT, 680, 440, NULL, NULL, hInstance, NULL);


// creates the interface name label
if (!(hTemp = CreateWindow("Static","Interface name",ES_LEFT | WS_CHILD | WS_VISIBLE,
540,14,100,20,ImaqSmplHwnd,(HMENU)-1,hInstance,NULL)))
return(FALSE);

// creates the frame rate label
if (!(hTemp = CreateWindow("Static","Frame per second",ES_LEFT | WS_CHILD | WS_VISIBLE,
540,232,140,20,ImaqSmplHwnd,(HMENU)-1,hInstance,NULL)))
return(FALSE);

// creates the interface name edit box
if (!(HIntfName = CreateWindow("Edit","img0",ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER,
540,34,100,20,ImaqSmplHwnd,(HMENU)-1,hInstance,NULL)))
return(FALSE);

// creates the frame rate edit box
if (!(HFrameRate = CreateWindow("Edit","0",ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER,
540,252,100,20,ImaqSmplHwnd,(HMENU)-1,hInstance,NULL)))
return(FALSE);

// creates the Grab button
if (!(HGrab = CreateWindow("Button","Grab",BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_BORDER,
550,72,80,40,ImaqSmplHwnd,(HMENU)PB_GRAB,hInstance,NULL)))
return(FALSE);

// creates the stop button
if (!(HStop = CreateWindow("Button","Stop",BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_BORDER,
550,112,80,40,ImaqSmplHwnd,(HMENU)PB_STOP,hInstance,NULL)))
return(FALSE);

EnableWindow(HStop, FALSE);
EnableWindow(HFrameRate, FALSE);

// creates the quit application button
if (!(HQuit = CreateWindow("Button","Quit",BS_DEFPUSHBUTTON | WS_CHILD | WS_VISIBLE,
550,152,80,40,ImaqSmplHwnd,(HMENU)PB_QUIT,hInstance,NULL)))
return(FALSE);

// Display the main window
ShowWindow(ImaqSmplHwnd, SW_SHOW);
UpdateWindow(ImaqSmplHwnd);


while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}

return (msg.wParam);
}


// Message proc
BOOL CALLBACK ImaqSmplProc(HWND hWnd, UINT iMessage, UINT wParam, LONG lParam)
{
WORD wmId;

switch (iMessage)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
switch (wmId)
{
case PB_QUIT:
PostQuitMessage(0);
break;
case PB_GRAB:
// Grab button has been hitten
OnGrab();
break;
case PB_STOP:
// Grab button has been hitten
OnStop();
break;
}
break;
case WM_DESTROY:
PostQuitMessage(0);

default:
return DefWindowProc(hWnd, iMessage, wParam, lParam);
break;
}
return 0;
}



// Function executed when the snap button is clicked
int OnGrab (void)
{
int error, bufSize, bytesPerPixel;
char intfName[64];
DWORD dwThreadId;


// Get the interface name
GetWindowText(HIntfName, intfName, 64);

// Open an interface and a session
errChk(imgInterfaceOpen (intfName, &Iid));
errChk(imgSessionOpen (Iid, &Sid));

// Leon - modification for free up CPU time
// Set the sleep time to free up the CPU in ms
imgSetAttribute (Sid, IMG_ATTR_SLEEPTIME, 50);
// end of Leon


// Let's check that the Acquisition window is not smaller than the Canvas
errChk(imgGetAttribute (Sid, IMG_ATTR_ROI_WIDTH, &AcqWinWidth));
errChk(imgGetAttribute (Sid, IMG_ATTR_ROI_HEIGHT, &AcqWinHeight));

if(CanvasWidth < AcqWinWidth)
AcqWinWidth = CanvasWidth;
if(CanvasHeight < AcqWinHeight)
AcqWinHeight = CanvasHeight;

// Set the ROI to the size of the Canvas so that it will fit nicely
errChk(imgSetAttribute (Sid, IMG_ATTR_ROI_WIDTH, AcqWinWidth));
errChk(imgSetAttribute (Sid, IMG_ATTR_ROI_HEIGHT, AcqWinHeight));
errChk(imgSetAttribute (Sid, IMG_ATTR_ROWPIXELS, AcqWinWidth));


// create a buffer list with one element
errChk(imgCreateBufList(1, &Bid));

// compute the size of the required buffer
errChk(imgGetAttribute (Sid, IMG_ATTR_BYTESPERPIXEL, &bytesPerPixel));
bufSize = AcqWinWidth * AcqWinHeight * bytesPerPixel;

// alloc our own buffer for storing copy
CopyBuffer = (Int8 *) malloc(bufSize * sizeof (Int8));

// create a buffer and configure the buffer list
errChk(imgCreateBuffer(Sid, FALSE, bufSize, &ImaqBuffer));

/* the following configuration assigns the following to buffer list
element 0:

1) buffer pointer that will contain image
2) size of the buffer for buffer element 0
3) command to loop when this element is reached

*/
errChk(imgSetBufferElement(Bid, 0, IMG_BUFF_ADDRESS, (uInt32)ImaqBuffer));
errChk(imgSetBufferElement(Bid, 0, IMG_BUFF_SIZE, bufSize));
errChk(imgSetBufferElement(Bid, 0, IMG_BUFF_COMMAND, IMG_CMD_LOOP));

// lock down the buffers contained in the buffer list
errChk(imgMemLock(Bid));

// configure the session to use this buffer list
errChk(imgSessionConfigure(Sid, Bid));

// start the acquisition, asynchronous
errChk(imgSessionAcquire(Sid, TRUE, NULL));

StopGrab = FALSE;

// Start the acquisition thread
HThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) ImaqThread, (LPDWORD*)&StopGrab, 0, &dwThreadId);
if (HThread == NULL)
return 0;

EnableWindow(HStop, TRUE);
EnableWindow(HGrab, FALSE);
EnableWindow(HQuit, FALSE);
Error :
if(error<0)
DisplayIMAQError(error);

return 0;
}



DWORD ImaqThread(LPDWORD lpdwParam)
{
static int nbFrame = 0, error;
static int t1, t2, currBufNum;
char buffer[32];


// the thread stop when StopGrab goes to TRUE
while(*((BOOL*)lpdwParam) == FALSE)
{
t2 = GetTickCount();

// Wait at least for the first valid frame
errChk(imgGetAttribute (Sid, IMG_ATTR_LAST_VALID_BUFFER, &currBufNum));

// if no buffer available, wait
if(currBufNum == 0xFFFFFFFF)
errChk(imgSessionWaitSignal (Sid, IMG_FRAME_DONE, IMG_TRIG_POLAR_ACTIVEH, 5000));

// Get the frame after tne next Vertical Blank
errChk(imgSessionCopyBuffer(Sid, 0, CopyBuffer, TRUE));

// Display it using imgPlot
// Note that if you are using a 1424 and a camera with a bitdepth greater
// that 8 bits, you need to set the flag parameter of imgPlot to match
// the bit depth of the camera. See the "snap imgPlot" sample.
errChk(imgPlot ((GUIHNDL)ImaqSmplHwnd, CopyBuffer, 0, 0, AcqWinWidth, AcqWinHeight,
CanvasLeft, CanvasTop, FALSE));

// Calculate the number of frame per seconds every 10 frames
nbFrame++;
if (nbFrame>10)
{
sprintf(buffer, "%.2f", 1000.0 * (double)nbFrame / (double)(t2-t1));
SetWindowText (HFrameRate, buffer);
t1 = t2;
nbFrame=0;
}

Error:
if(error<0)
{
OnStop();
DisplayIMAQError(error);
}
}

return 0;
}


int OnStop(void)
{
int error, bufNum;
DWORD dwResult;


// Stop the thread
StopGrab = TRUE;

// Wait for the thread to end and kill it otherwise
dwResult = WaitForSingleObject(HThread, 2000);
if (dwResult == WAIT_TIMEOUT)
TerminateThread(HThread, 0);

// stop the acquisition
errChk(imgSessionAbort(Sid, &bufNum));

Error:
if(error<0)
{
DisplayIMAQError(error);
}

// unlock the buffers in the buffer list
if (Bid != 0)
imgMemUnlock(Bid);

// dispose of the buffer
if (ImaqBuffer != NULL)
imgDisposeBuffer(ImaqBuffer);

// close this buffer list
if (Bid != 0)
imgDisposeBufList(Bid, FALSE);

// free our copy buffer
if (CopyBuffer != NULL)
free(CopyBuffer);

// Close the interface and the session
if(Sid != 0)
imgClose (Sid, TRUE);
if(Iid != 0)
imgClose (Iid, TRUE);

EnableWindow(HStop, FALSE);
EnableWindow(HGrab, TRUE);
EnableWindow(HQuit, TRUE);

CloseHandle (HThread);

return 0;
}



// in case of error this function will display a dialog box
// with the error message
void DisplayIMAQError(Int32 error)
{
static Int8 ErrorMessage[256];

memset(ErrorMessage, 0x00, sizeof(ErrorMessage));

// converts error code to a message
imgShowError(error, ErrorMessage);

MessageBox(ImaqSmplHwnd, ErrorMessage, "Imaq Sample", MB_OK);
}
0 Kudos
Message 3 of 3
(3,679 Views)