Measurement Studio for VB6

cancel
Showing results for 
Search instead for 
Did you mean: 

Why does DAQmx driver take 100% CPU in VB6?

I have an application to run waveforms on several channels, and my application is using 100% CPU while it is outputing the waveforms.  I have done my best to optimize my code to reduce CPU and memory usage, but I haven't been able to fix it.  The loop below is where the CPU jumps up to 100%.   What is happening in this loop is that i am using the DAQmx circular buffer to output my waveforms.  I initially load data into the buffer and then go to this while loop to determine when the next bufferful of data can be written until the entire waveform is complete.   My code spends a lot of time in this while loop, so if there is any chance i can reduce the CPU usage it would be great.  Does anyone see any major flaws that might help me fix this issue?  I read on some knowledge group post somewhere that earlier versions of NIDAQmx used a lot of the CPU. 

Code Info:

Written in VB6.0

NIDAQmx version: 7.5

NI Card: PCI-6711

 

While (LoopCount <= BufferCount)
                        If (taskIsRunning = False) Then Exit Sub
                        status = DAQmxGetWriteSpaceAvail(taskHandle, WriteSpaceAvail)
                        status = DAQmxGetWriteTotalSampPerChanGenerated(taskHandle, SamplesGenerated)
                        If (status < 0) Then Call DAQmxErrChk(status)
                        If (NumChans <> 3) Then
                            If (WriteSpaceAvail >= SizeofHalfBuffer Or ((WriteSpaceAvail = 0) And (SamplesGenerated = 32768))) Then
                                status = DAQmxWriteAnalogF64(taskHandle, (SizeofHalfBuffer / NumChans), 0, 0, DAQmx_Val_GroupByScanNumber, HalfBuffer(0), sampsPerChanWritten, ByVal 0&)                            

                                    If (status < 0) Then Call DAQmxErrChk(status)
                                    LoopCount = LoopCount + 1
                                    lngLastSamplesGenerated = SamplesGenerated
                                    Call GenerateHalfBuffer(RemainingPoints, CLng(LoopCount))
                                    RemainingPoints = RemainingPoints + SizeofHalfBuffer
                            End If
                        Else
                            If (WriteSpaceAvail >= SizeofThreeChannelHalfBuffer Or ((WriteSpaceAvail = 0) And (SamplesGenerated = 32768))) Then
                                DAQmxErrChk DAQmxWriteAnalogF64(taskHandle,(SizeofThreeChannelHalfBuffer/NumChans),0,0,DAQmx_Val_GroupByScanNumber,ThreeChannelHalfBuffer(0),sampsPerChanWritten,ByVal 0&)                                 

                                LoopCount = LoopCount + 1
                                Call GenerateHalfBuffer(RemainingPoints, CLng(LoopCount))
                                RemainingPoints = RemainingPoints + SizeofThreeChannelHalfBuffer
                            End If
                        End If
                        DoEvents

Wend

0 Kudos
Message 1 of 7
(8,662 Views)

Hi,

 

Thank you for posting to the NI forums.  If you’re just doing analog output, I would recommend starting with one of the examples that install with DAQmx.  There is a good analog output example that can be found in the following location…

 

National Instruments\NI-DAQ\Examples\Visual Basic 6.0\Analog Out\Generate Voltage\Cont Gen Volt Wfm-Int Clk

 

You should be able to modify this example to handle multiple outputs, rather than manually viewing the buffer sizes to stop the while loop.

 

If this is not a viable option, then I would recommend adding some form of delay (around 10ms or so) to your current while loop.  This will give the operating system time between iterations to handle other processes and take some of the burden off of your CPU.

 

In addition to this, I would also recommend upgrading your DAQmx driver

 

Post back if you have further questions.  Thanks!

 

Ed W.

Applications Engineer

National Instruments

Message Edited by Ed W on 03-06-2007 01:22 PM

0 Kudos
Message 2 of 7
(8,646 Views)
Thanks for the comment.  I took a look at that example you mentioned, and it is useful but my application's function is a little different.   In that example, like others I have seen from NI, they are meant to play indefinetly until a stop button is clicked.  My application allows users to add waveforms to a list that will be played when "Start" is clicked.  All waveforms have specific timing parameters (set by users) and they are all played one after the other.   So, to end a waveform I have to figure out when the waveform is done playing and then call the stop task routine and start the next one.   I have tried doing that a lot of different ways, but often times i would get an error saying "An error occured since samples weren't written to the card fast enough".  So, the while loop routine i have is the best one I have developed so far.  It looks at the number of samples generated as well as the buffer space available.    I guess what i am saying is that I think (at least to the best of my knowledge) using the example isn't a viable option. 
 
If you feel that i am wrong in that assessment then I am definitely up for learning a better way. 
 
Thanks in advance,
Gerry
0 Kudos
Message 3 of 7
(8,641 Views)

Hi,

 

What was the error number that you received with that error?  Often times, you can fix errors like these by changes the number of samples to read.  Let me know about that, and I can get back to you with some more recommendations.  Thanks!

 

Ed W.

Applications Engineer

National Instruments

0 Kudos
Message 4 of 7
(8,628 Views)
The error had to due either with the regeneration setting (allow or disallow), or the error had to do with not writing samples fast enough.  The suggestions the error dialog gave was to increase the amount of samples written each time or to slow down the rate at which samples were generated. 
 
Sorry for my long delay in answering your question. 
 
- Gerry
0 Kudos
Message 5 of 7
(8,572 Views)

Hi Gerry,

 

Can you reproduce the error to find the error number?  It’d be difficult to offer recommendations for a solution without that information. 

 

However, if the error message recommends increasing the buffer size, that’ll probably fix the problem.  A good rule of thumb is to set the sample count to 10% of the sample rate in Hz.  Make sure to multiply the sample rate parameter by the number of channels in your task to determine a good sample count.

 

I hope this helps.  Post back if you have any more questions. 

 

Ed W.

Applications Engineer

National Instruments

0 Kudos
Message 6 of 7
(8,555 Views)
I had a similar problem using an NI USB 6008 device with MATLAB on Windows XP.

CPU usage was 100%, on long-term testruns, error messages like the following occured:

Error event occurred at 20:13:29 for the object: nidaqmxDev1-AI.
 NIDAQmx error : Measurements: Attempted to read samples that are no longer available. The requested sample was previously available, but has since been overwritten.
 Increasing the buffer size, reading the data more frequently, or specifying a fixed number of samples to  read instead of reading all available samples might correct the problem.
 Property: DAQmx_Read_RelativeTo
 Corresponding Value: DAQmx_Val_CurrReadPos
 Property: DAQmx_Read_Offset
 Corresponding Value:
 Task Name: MWDAT0061
 Status Code: -200279

Long-term stability was achieved in..
.. reading the data much more often from the device (FIFO: only 512byte!!)
.. introducing a pause(0.1) command in the while-loop reading out the data from the device.
.. predefining the length of MATLAB matrices and then overwriting the generated arrays of zeros with something like A(a:a+c,:)=data_acquired_from_device
0 Kudos
Message 7 of 7
(8,349 Views)