Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

Polling a USB-6008 for analog input causes momentary lags in Visual Basic 6

I am using an adapted version of the Visual Basic 6.0 example code which comes with the NI-DAQmx installation for the NI-6008 USB DAQ to do continuous analog input data acquisition.  Although everything performs fine, whenever the subroutine which polls the DAQ is called, it causes a momentary lag which causes the program to freeze for just a split second.  It is brief enough that program is operable and fully functional otherwise but long enough that it's annoying to do things in other parts of the program like highlighting text or entering text (the repeated lag causes the controls to behave "sticky").  If I disable the analog data collection subroutine, the lag goes away.

 

Can someone please offer some advice how to program a routine which collects analog input from the DAQ without causing a program-wide lag?  Your time is much appreciated!

 

In my program, I have a timer set to a frequency of 400 ms which calls the analog input collection routine:

 

Private Sub Timer2_Timer()
'DAQ Handler
For Index = 0 To setupvalue("numberofmassflowcontrollers", profile) 'Loops over number of analog input channels connected to mass flow controllers, generally from 0 to 2

a = analogindaq(setupvalue("mfc" + LTrim$(Str$(Index + 1)) + "indevnumber", profile), Val(setupvalue("mfc" + LTrim$(Str$(Index + 1)) + "inchannumber", profile))) 'Collects analog input voltage from function analogindaq and stores it in variable a--the rest is just telling the function analogindaq which analog in channel to poll

If a <> "DAQ Read Error" Then Label15(Index).Caption = Str$(Round(voltage2flow(a, setupvalue("mfc" + LTrim$(Str$(Index + 1)) + "flowslope", profile), setupvalue("mfc" + LTrim$(Str$(Index + 1)) + "flowoffset", profile)))) + " sccm" 'If everything goes right, it displays a scaled value of the voltage read into a label in the program form

If a = "DAQ Read Error" Then Label15(Index).Caption = a 'If something goes wrong then the analogindaq function returns the message DAQ Read Error and the message DAQ Read Error is displayed in the program form

Next Index

...

End Sub 

 

The function analogindaq is an adaptation of the NI-DAQmx example code for Visual Basic 6.0.  I have traced the lag to this routine.

 

Function analogindaq(daqnumber, channel%)

Dim sampsPerChanRead As Long
    Dim numChannels As Long
    Dim fillMode As DAQmxFillMode
    Dim bufferSize As Long
    Dim numSampsPerChannel As Long
    Dim arraySizeInSamps As Long
   
    On Error GoTo ErrorHandler
   
    dev$ = LTrim$(Str$(daqnumber))
    cha$ = LTrim$(Str$(channel%))
    analoginputchannel = "Dev" + dev$ + "/ai" + cha$

    If analoginputscanorder = True Then
        fillMode = DAQmx_Val_GroupByScanNumber
    Else
        fillMode = DAQmx_Val_GroupByChannel
    End If
    bufferSize = 255
    numSampsPerChannel = CLng(analoginputsamplesperchannel) 'The value analoginputsamplesperchannel is set to 100 elsewhere in the program.  If this value is less than 100 the lag time goes down but the voltage read off the DAQ analog input channel isn't accurate enough for the process.

   'Create the DAQmx task.
    DAQmxErrChk DAQmxCreateTask("", taskhandle)
    taskIsRunning = True

    'Add an analog input channel to the task.
    DAQmxErrChk DAQmxCreateAIVoltageChan(taskhandle, analoginputchannel, "", DAQmx_Val_InputTermCfg_RSE, analoginputminvalue, analoginputmaxvalue, _
                    DAQmx_Val_VoltageUnits1_Volts, "")
     
    'Configure task for finite sample acquisition and read in data
    DAQmxErrChk DAQmxCfgSampClkTiming(taskhandle, "OnboardClock", analoginputfrequency, DAQmx_Val_Rising, _
                    DAQmx_Val_AcquisitionType_FiniteSamps, CLng(analoginputsamplesperchannel))
    DAQmxErrChk DAQmxGetTaskNumChans(taskhandle, numChannels)
    arraySizeInSamps = numSampsPerChannel * numChannels
    ReDim data(arraySizeInSamps)
       
    DAQmxErrChk DAQmxReadAnalogF64(taskhandle, numSampsPerChannel, 10#, _
                    fillMode, data(0), arraySizeInSamps, sampsPerChanRead, ByVal 0&)
     'Call the StopTask module to stop the DAQmx task.
       
    StopTask
tryagain:
   
    While i < sampsPerChanRead
          i = i + 1
          average = average + data(i)
        Wend
        average = average / sampsPerChanRead
        'Label1.Caption = Format(average, "#.000000")
        analogindaq = average
   
Exit Function
   
ErrorHandler:
If Err.Number = 11 Then GoTo tryagain
    If taskIsRunning = True Then
        DAQmxStopTask taskhandle
        DAQmxClearTask taskhandle
        taskIsRunning = False
    End If
    analogindaq = "DAQ Read Error"

End Function

0 Kudos
Message 1 of 2
(2,819 Views)

Hi rootabegax,

 

I think the reason you're seeing this type of behavior is because the timer function is possibly running within the UI thread. This would cause the User Interface to not be updated until the function is completed. Since the DAQmxReadAnalogF64 will take longer to execute if you acquire more samples, you should see the lag grow as you request a greater number of samples.

 

If you're trying to perform continuous acquisition (as it appears you are doing with the Timer calling DAQ functions), you will not want to create the task and stop the task on each call to acquire samples. A better implementation (and also solution to your problem of having the UI hang while calling DAQmxRead) would be to use DAQmxRegisterEveryNSamplesEvent to handle the samples being acquired in an event handler. You can refer to the NI-DAQmx: Continuous Analog Acquisition with NI-DAQmx Events in Visual Basic 6.0 example for implementing this design. This should also remove the need for a timer. I hope this helps!

0 Kudos
Message 2 of 2
(2,786 Views)