Measurement Studio for VB6

cancel
Showing results for 
Search instead for 
Did you mean: 

Realtime usb-6009 sampling and graphing

I am using a USB-6009 to sample 8 analog channels simultaneously in VB6. I ideally need to sample at around 500 Hz or more but also need to output the results to a chart in realtime.

 

I initially followed the NI-DAQ VB6 Analog-in example, using the ‘one sample’ example but soon realised that this only sampled one channel once, where I needed to sample 8 channels once repeatedly and plot the results each time.

 

The solution I am using at the moment is based on the Acq-Int Clk example. After creating my task and assigning to it 8 voltage channels I sample all 8 channels once with DAQmxReadAnalogF64 within a loop (well actually twice as this is the minimum, with 6000hz specified as a sample rate in DAQmxCfgSampClkTiming) that writes to a storage array and plots the result (which is actually a point in a picture box). This works ok but is very slow and the speed is intermittent, averages about 60Hz. Taking out the storage and picture box elements does not speed up this process much.

 

I was wondering if there is a better approach for this kind of problem. Would it be possible to plot values from within a DAQmxReadAnalogF64 call? i.e. if it writes to an array data() could I plot every hundredth value or something in realtime. Or is there another way to accomplish this entirely.

 

Many thanks for you time and thoughts,

 

Nick

 

Nick.hamilton@gmail.com

 

ps, i am happy to show my code to anyone that might be interested.

0 Kudos
Message 1 of 8
(8,261 Views)

Hi Nick,

Thanks for your post about calling DAQmx in VB6.

I'm a bit confused about what you're trying to do - can you confirm that you're looking to sample at 500Hz across 8 analogue input channels?

I've had a look at the example you're using in VB6; how many samples are you taking on each iteration of the loop, and at what sampling frequency?

Also - which version of the DAQmx driver are you using (are you using the latest, DAQmx v8.0)?

Would it be OK in your application for it to sample a batch of readings (say 1 seconds worth of data), then 'dump' that onto your plot and go back for the next seconds worth? This would give your application maximum chance to do a portion of the acquisition uninterrupted, and then plot the results afterwards.

If you can post back with your code attached that would be really helpful!

Best wishes,

 

MarkL

Applications Engineer

National Instruments

Message 2 of 8
(8,248 Views)

Mark, thankyou for your reply, I am using the latest DAQmx, v8.0.

 

Let me try and clear up what I am trying to do. I am using the USB-6009 to give feedback to an operator but also sample the data for post processing. I therefore need to sample 8 AI channels at about 500Hz for about 3 seconds but also use the collected data to update a graph used for feedback in real time.

 

At the moment my approach is to set DAQmxCfgSampClkTiming to sample at 6000Hz (found this to be the fastest) using the on board clock and set to finite sample 2 samples (it would not allow only 1 sample to be taken). Within a loop I then use DAQmxReadAnalogF64 to repeatedly sample the 8 channels. The data written by this function to the array is then used to calculate a position and this is reported to the user by means of the graph (which is actually a circle in a picturebox). The data is also written to a storage array for post processing. At the moment this approach is returning an intermittent 60-90 Hz sample rate, which isn’t really good enough.

 

The last resort for me would be to remove the feedback element and just sample over the 3 seconds, and this does actually work.

 

I have thought about the approach you mentioned in your reply, but haven’t implemented it properly yet. I would need to do it faster than you suggest, probably reporting results every 0.1 seconds, so sampling constantly for 0.1 seconds then reporting the last result to the user.

 

What I was hoping would be possible is to use DAQmxReadAnalogF64 to sample constantly over the 3 seconds but actually read from the array that it writes to in realtime.  So perhaps extract every hundredth sample and report it to the graph, but I feel that while the routine is running, its data array will probably be inaccessible. Is there another way to achieve this?

 

Many thanks for you assistance, I have attached my complete VB project for you to have a look at, but you will need NIDAQmxErrorCheck.bas in the correct folder if you wish to run it.

 

Nick

 

 

0 Kudos
Message 3 of 8
(8,240 Views)
Hi Nick,
 
Thanks for your reply before Xmas! I've been trying to look through all the possible ways to achieve this acquisition in VB6.
 
I've got a piece of code which I'm attaching to this post, which sets up and runs a continuous acquisition in Visual Basic 6. Basically this means that the card is set up to continually acquire data and store it in a buffer. Once the acquisition has been set up, a timer on the form takes a portion of samples repeatedly, and then has some breathing space to do operations on them (so for example, displaying them) while the acquisition continues in the background.
 
I hope that this should allow your system to continually acquire at a reasonable rate whilst the program still manages to display your data in real time.
 
This is actually another example of the behaviour we were talking about in my last post; taking a section of readings and working on them in a batch, but I think this is the most sensible way to go about it.
 
Can you have a look at the code and let me know whether you think it may be suitable for your application?
 
Best wishes,
 
Mark L
Applications Engineer
National Instruments
Message 4 of 8
(8,154 Views)

Mark,

thankyou very much for taking the time to adapt the program, I've had a play around with it but I'm not sure its doing quite what you describe in your post.

From what you wrote I assumed that the task is set to continually sample until stopped and that the readanalog command would extract the revevant data from the array for display. This reading would not actually interupt the continual sampling which would continue filling the data array until told to stop. What I think is happening, as far as I can tell, is that the readanalog command actually does the sampling in the timer loop no matter what the CfgSampClkTiming is set to. I could be wrong but I don't have a way to check it as the samples written to the data() array are not time coded in anyway. Do you think there is a simple way this could be achieved to enable further testing? At the end of the test the entire contents of the data array could then be written out and examined.

If what you wrote is correct, then this would be the ideal way of to achieve the measurements, but I dont see how the data array can be written to and read from at the same time.

Thanks again

Nick

0 Kudos
Message 5 of 8
(8,109 Views)

Hi Nick,

Thanks for your reply!

Yes, the idea with setting up the continuous acquisition under DAQmx is that the process runs in the background, fills a FIFO buffer up with data, which the program then reads out of the buffer in large chunks into your data array when told to by the timer portion of the code. The idea of this is to keep the acquisition going as a background process, while the foreground process is able to deal with your data.

What makes you think that the program is not achieving this on your system? Are you able to achieve consistent higher sampling rates with this code than with your existing code, and still get some kind of real-time display?

I can't think of a simple way to get the data points time-stamped really as they're read into the data array as a set of points! Maybe you could run a counter on how many samples are acquired each time the timer fires (so basically how large the data array is each time timer 1 runs) to verify that the program is acquiring as much data as you expect.

Remember that the maximum data rate the card can produce is 48kS/second, so across 8 channels that only works out at a maximum 6kS/sec per channel.

I hope this helps, please let me know if you have any further questions!

 

Best wishes,

MarkL

Message 6 of 8
(8,098 Views)

Thanks again for your continual help Mark, it really is appreciated.

 

I think I'm beginning to see what is actually going on with the system now, but it makes me think that I can't do what I need to do with it. I know understand that the continual sampling is initialised by the DAQmxCfgSampClkTiming command, so the FIFO buffer is being filled from this point. When DAQmxReadAnalogF64 called it then reads the specified number of samples from this buffer. Where in this buffer does it read from and is this controllable?

 

I think that to do everything I need to do I would have to be able to record the entire buffer continuously in to one array so that I have a completely synchronised set of data, time stamps would not matter as the sample rate and number of samples would be known. But I would also need to sample the buffer at regular intervals and display these results to the user. Would this be possible? Or could the whole buffer be dumped to an array at the end of the sampling to allow intermittent sampling aswell? I guess the rate then would be limited by the size of the buffer on the device.

 

Mant thanks

 

Nick

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

Hey Nick,

Some of the more advanced cards we sell have onboard memory and can therefore use this for their FIFO buffers, as I believe it the USB devices under DAQmx will use the PC memory as its buffer. The buffer is handled at driver level, so I don't think there's much scope to control it as such, there may be options to change its size, I'll have a look into that for you.

Regarding your other points, I would use the timer code to append each successive chunk of samples onto the end of a larger array of data (or even maybe a file) which you analyse at the end of your sampling run of 3 seconds. I would then take the signals to display on your real-time display either from one or an average of a few of the samples in the data buffer during each run of the timer code - this way you're getting a slightly approximated or stepped real time display, but also the full data set buffered for when you finish the entire acquisition. As you say, however, you do have to infer the timestamps, as the readings are returned as batches. The samples should be continuous as they come from the FIFO buffer in memory, you're just reading them in a section at a time.

I hope this helps a bit!

Best wishes,

Mark

0 Kudos
Message 8 of 8
(8,087 Views)