Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

DAQmxReadAnalogF64 Read and Average Samples in VB6

Hi guys, need a little help on this one.  I have a cDAQ-9178 chassis with Analog In modules for reading voltage, current, and temp.  24 channels all together in my task.  Using VB6 for programming.  I would like to read 50 (or more, but for this example lets just say 50) samples per second per channel, and then average those 50 samples to get an average reading per second.  I'm hoping this will eliminate the fluctuations/noise in my readings.  Code as follows:

 

Form_Load()

numSampsPerChannel = 50

 

DAQmxErrChk DAQmxCreateTask("", myAITask)

DAQmxErrChk DAQmxCreateAIVoltageChan(myAITask, "cDAQ1Mod1/ai0:7", "", DAQmx_Val_Cfg_Default, 0, 10, DAQmx_Val_VoltageUnits2_Volts, "")

 

DAQmxErrChk DAQmxCreateAICurrentChan(myAITask, "cDAQ1Mod2/ai0:7", "", DAQmx_Val_Cfg_Default, 0#, 0.02, DAQmx_Val_CurrentUnits2_Amps,_                     DAQmx_Val_CurrentShuntResistorLocation1_Internal, 100, "")

 

DAQmxErrChk DAQmxCreateAIThrmcplChan(myAITask, "cDAQ1Mod3/ai0:3", "", 0, 400, DAQmx_Val_DegF, DAQmx_Val_ThermocoupleType1_J_Type_TC, DAQmx_Val_CJCSource1_BuiltIn, 0#, "")
DAQmxErrChk DAQmxCreateAIThrmcplChan(myAITask, "cDAQ1Mod4/ai0:3", "", 0, 400, DAQmx_Val_DegF, DAQmx_Val_ThermocoupleType1_J_Type_TC, DAQmx_Val_CJCSource1_BuiltIn, 0#, "")

 

DAQmxErrChk DAQmxCfgSampClkTiming(myAITask, "OnboardClock", 1, DAQmx_Val_Rising, DAQmx_Val_AcquisitionType_FiniteSamps, 50)

 

DAQmxErrChk DAQmxGetTaskNumChans(myAITask, numChannels)
arraySizeInSamps = numSampsPerChannel * numChannels
ReDim data(arraySizeInSamps)

End Sub

 

'Now once per second (using timer on main form) I will read the data returned from the buffer

Public Function GetcDAQAnalogData()

Dim i As Long, j As Long
Dim data2$

sampsPerChanRead = 50

DAQmxErrChk DAQmxReadAnalogF64(myAITask, 1, 10#, DAQmx_Val_GroupByScanNumber, data(0), arraySizeInSamps, sampsPerChanRead, ByVal 0&)
For j = 1 To numChannels

   data2$ = Left$(data(i), 7)
   data2$ = Strings.FormatNumber(data(i), 7)
   i = i + 1
Next

End Sub

 

Can anyone tell me how to change the above code in my GetcDAQAnalogData routine that will read the 50 samples per channel and average them together for each channel, and then output the result in my data2$ variable?

0 Kudos
Message 1 of 7
(4,224 Views)

Nothing at all???  I just need a loop that will read 50 samples from each of my 24 channels, average those samples all together, and ouput the result for each channel.  Any help would be greatly appreciated.  I welcome any input whatsoever...Thanks

0 Kudos
Message 2 of 7
(4,204 Views)

Hi Chris,

 

From looking at your code, you're currently performing a Finite Acquisiton, but I would think you would want to be acquiring data continuously for your specific application, so I would change your call when you configure your sample clock to DAQmx_Val_AcquisitionType_ContSamps. Also, the third argument in your DAQmxCfgSampClkTiming function is the sampling rate for your task, which you currently have set to 1 Hz. You should set this to whatever rate you want to acquire samples at per second per channel, so in your case you would want to set it to 50 Hz. I would also increase your buffer size, which is the final argument of this function, to at least 10x the number of samples you want to read from each channel, to avoid buffer overflow issues.

 

Additionally, you seem to be passing a 1 to your DAQmxReadAnalogF64 function as the number of samples to read every time that the loop iterates, but if you want to pull 50 samples upon each iteration, then you should change that argument to 50. From there, you should just need to average the data you pull out of the buffer with each iteration, and place it into a separate array.

 

I would recommend looking at the DAQmx in C reference help (I realize you are programming in VB6, but the VB6 help doesn't seem to have information about the arguments for specific function calls); it's helpful for verifying the correct arguments for function calls.  

 

Best,

Dan N

Applications Engineer 

 

0 Kudos
Message 3 of 7
(4,201 Views)

Thanks for your response Dan.  When I first started I was doing continuous sampling but kept getting buffer errors.  I have now changed everything to your recommendations and it seems to work beautifully.  Still having issues with creating and averaging for that second array you mention though.  Could you possibly give me some additional help for pulling the data from the buffer and creating the average reads for each channel?  If you aren't familiar with VB6 I understand...if anyone else could help with this I would be very grateful...Thanks

0 Kudos
Message 4 of 7
(4,194 Views)

Worked out a solution and thought I would post for anyone interested.  I decided to average 100 samples per channel which seems to filter out the noise very well.  Steady readings to the 3rd and 4th digit.

 

Modified the following on Form_Load:   

numSampsPerChannel = 100

DAQmxErrChk DAQmxCfgSampClkTiming(myAITask, "OnboardClock", 100, DAQmx_Val_Rising, DAQmx_Val_AcquisitionType_ContSamps, 1000)

 

Public Function GetcDAQAnalogDataDB(inRecordset As Recordset)
Dim count As Long, i As Long, j As Long, temp_i As Long
Dim ArrayAverage As Double
Dim sum As Variant

sampsPerChanRead = 100

DAQmxErrChk DAQmxReadAnalogF64(myAITask, 100, 10#, DAQmx_Val_GroupByChannel, data(0), arraySizeInSamps, 100, ByVal 0&)

ArrayAverage = 0
sum = 0
count = 0
i = 0
temp_i = 0
j = 1
       
inRecordset.MoveFirst
i = temp_i
For count = 0 To sampsPerChanRead - 1 'subtract 1 from total number of samples per channel
    sum = sum + data(i)
    i = i + 1
Next count
inRecordset.Edit
ArrayAverage = sum / sampsPerChanRead 'divide by number of samples per channel
ArrayAverage = Strings.FormatNumber(ArrayAverage, 7) '1st channel only
inRecordset.Fields!Egudata = ArrayAverage
inRecordset.Update
inRecordset.MoveNext
count = 0
sum = 0
ArrayAverage = 0
For j = 2 To numChannels - 1  'will cycle thru channel 2 and up
    For count = 0 To sampsPerChanRead - 1
    sum = sum + data(i)
    i = i + 1
Next count
inRecordset.Edit
ArrayAverage = sum / sampsPerChanRead
ArrayAverage = Strings.FormatNumber(ArrayAverage, 7)
inRecordset.Fields!Egudata = ArrayAverage
If j >= 9 And j <= 16 Then 'this will format the decimal current readings from NI 9208 module into whole numbers for 4-20ma transducer channels
   inRecordset.Fields!Egudata = inRecordset.Fields!Egudata * 1000
End If
inRecordset.Update
inRecordset.MoveNext
count = 0
sum = 0
ArrayAverage = 0
Next j
temp_i = temp_i + 1

End Function

0 Kudos
Message 5 of 7
(4,117 Views)

Well of course I spoke too soon.  You had recommended I set the buffer to 10 times the number of samples I want to acquire so I set it at 1000.  After 5 minutes or so I will get a buffer error.  So I doubled it to 2000 and still get the error.  Is there something wrong with the last code I posted?  Like I stated earlier I only need 50 samples per channel once every second.  I guess i'm not reading in the data buffer fast enough.  How can I fix this?  Can I change to FiniteSamps and achieve the same thing?  I never seemed to get buffer errors when using this method.  Also notice the active light on the 9178 stays on while in contiuous sample mode, and with finite sample mode it only comes on about once per second, which makes more sense to me.  Please advise...Thanks

0 Kudos
Message 6 of 7
(4,111 Views)

Ended up changing code from conintuous samples to finite samples.  Program has been running for 2 days with no errors.

 

DAQmxErrChk DAQmxCfgSampClkTiming(myAITask, "OnboardClock", 100, DAQmx_Val_Rising, DAQmx_Val_AcquisitionType_FiniteSamps, 1000)

0 Kudos
Message 7 of 7
(4,096 Views)