LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Displaying Finite Sample Acquisition with a USB-4431

Solved!
Go to solution

Tried a bunch of examples, DAQ Assistant code, mega-research time. At the end of the road.This is pretty much my first go at DAQmx programming after years of Traditional DAQ programming followed by a long hiatus.

 

I'm using an IEPE force hammer hit to start sampling from a USB-4431. I'm going to be post-processing fft; I want ten seconds of data at 4096 samples per second (40960 samples).

 

As I'm acquiring data, I want to update a graph to show the buffer contents, adding data to the graph every 125 mS until the end of the 10 second capture.  The trigger, data sampling start, and acquisition is working fine. The problem is getting it to the graph control.

 

The graph gets updated in inconsistent fits and spurts. The entire 10 second shot eventually makes it to the graph, but it takes anywhere from 30 to 120 seconds to display, sometimes in rapid  "chunks" with long pauses. Sometimes the initial trigger data gets displayed right away, and sometimes it takes 15 seconds just to display the first 512 samples!

 

I've obviously got something fundamentally wrong here.  Could someone please have a look at the code below for me. TIA~!

 

void main (void)
{
	X_AxisIndex = 0;
	NumDataPoints = 512; // At a sample rate of 4096 samples/second, trying to update the graph every 125 milliseconds.
	
	CreateDaqTask();
	DAQmxStartTask(taskHandle);		
	RunUserInterface();

}  //  Main


void CreateDaqTask(void)
{
//  *** All this works fine AFAIK  ***
	DAQmxCreateTask("",&taskHandle);
	DAQmxCreateAIForceIEPEChan (taskHandle, "Dev1/ai0", "Hammer", DAQmx_Val_PseudoDiff, -10, 100, DAQmx_Val_Pounds, 50.0, DAQmx_Val_mVoltsPerPound, DAQmx_Val_Internal, 0.0021, NULL);
	DAQmxSetChanAttribute(taskHandle, "Hammer", DAQmx_AI_Coupling, DAQmx_Val_AC);
	DAQmxCfgSampClkTiming (taskHandle, "OnboardClock", 4096, DAQmx_Val_Rising, DAQmx_Val_FiniteSamps, 40960);  // Grab 10 seconds worth of data at 4096 samples per second.
	DAQmxCfgAnlgEdgeStartTrig (taskHandle, "Hammer", DAQmx_Val_RisingSlope, TriggerLevel);
//  *** All this works fine AFAIK  ***

	// Here the idea is to fire a callback every 512 samples/4096 samples per second = 125 mS so I can display the data to a graph control, updating it every 1/8th of a second.
	DAQmxRegisterEveryNSamplesEvent (taskHandle, DAQmx_Val_Acquired_Into_Buffer, NumDataPoints, 0, EveryNCallback, NULL);  

}	// CreateDaqTask	


int32 CVICALLBACK EveryNCallback(TaskHandle taskHandle, int32 everyNsamplesEventType, uInt32 nSamples, void *callbackData)
{   
	// Read the 512 data points and display them.
	DAQmxReadAnalogF64 (taskHandle, NumDataPoints, 15.0, DAQmx_Val_GroupByChannel, Buffer, NumDataPoints, &CurrentBufferIndex, NULL); 
	PlotWaveform (MainPanel, Main_Graph, Buffer, NumDataPoints, VAL_DOUBLE, 1.0, 0.0, X_AxisIndex, 1.0, VAL_THIN_LINE, VAL_NO_POINT, VAL_SOLID, 1, VAL_YELLOW);
	
	X_AxisIndex += NumDataPoints;
	
	return 0;
}	// EveryNCallback

 

0 Kudos
Message 1 of 5
(3,872 Views)

The issue you're seeing may be related to the buffer size on the USB-4431. For analog input, the USB-4431 has a buffer size of 1,023 samples, and this is shared by all channels. 

 

This page (http://digital.ni.com/public.nsf/allkb/9CD627095779BE7986256DC8005D767B) talks about using DAQmx in C and how you can configure the number of samples that you transfer at a given time. I think this will help you update your graph more appropriately.

0 Kudos
Message 2 of 5
(3,848 Views)
Solution
Accepted by topic author scottrod

Thanks WW, I'll give that a try.

 

>> For analog input, the USB-4431 has a buffer size of 1,023 samples, and this is shared by all channels. .

 

Can you tell me where you found this information please? I looked and looked, obviously in the wrong place.

Also, I discovered if I move the mouse around rapidly while it's trying to redraw the graph, it draws much more consistently and rapidly, but still not in real time.

 

UPDATE: I had SetSleepPolicy (VAL_SLEEP_NONE); active.

 

I thought this was to prevent Windows events from interfering with the DAQ events. Seems to have the opposite effect here. I turned it off, works fine now.

0 Kudos
Message 3 of 5
(3,841 Views)

Scott,

 

That information is provided in the specifications sheet for the USB-4431/2. (http://www.ni.com/pdf/manuals/372485e.pdf#page=2)

 

And the sleep policy determines how much your program sleeps, so that could explain the behavior you were seeing. Glad to hear it's working now!

 

-Will

0 Kudos
Message 4 of 5
(3,833 Views)

After thinking about it, I suppose writing data to the display IS a Windows function, and the daq program needs to "sleep" in order to update the graph control.

 

The CVI environment default is VAL_SLEEP_MORE. I expect setting it to NONE would be for high-speed applications where you want to grab data without any possibility of Windows intervention. For my paltry 4.1 k sample rate, that does not apply.

0 Kudos
Message 5 of 5
(3,825 Views)