streaming and exporting


Recommended Posts

I want to acquire three signals by streaming: one analog, one digital (and later one counter) and export (log) based on a condition of one of the channels. I am using DAQ Factory Express with U3-HV.

The example StreamChannelsUD you provided worked OK with minor modifications to stream the analog signal at 0.005 rate, but the digital signal would not stream at this rate together with the analog. When timing was set to 0 (as the analog, and the scan rate set in the script for StartStream sequence), the acqusition stopped. Is there a way to fix it?

Another problem is the exporting. I tried to run a sequence while the streaming was running:

if (mychannel[0] > 0.24)

beginexport(myexportset)

endif

once the input was raised to over 0.24V, but with no success. Ultimately, I'd like to put everything into one sequence, something like:

if (mychannel[0] > 0.24)

beginseq(StartStream)

beginexport(myexportset)

endif

if (digin[0] == 0)

beginseq(StopStream)

endexport(myexportset)

endif

Then the digital signal will stop the logging. Is there a best way to do it?

Thanks in advance

Link to comment
Share on other sites

LabJack can address some of this (namely the part about streaming analog and digital). However, you aren't going to be able to use an export set with high speed data. Its runs asynchronously, and won't finish before a new data point comes in. Also, you have to be careful about using channel events with streaming data. The event only gets triggered once for every block of data received from the device, not with every data point.

If the signal is slowly rising above 0.24 and then eventually will slowly fall, you should instead use a separate sequence to monitor the input. There will be a little slop at the ends, but it will work. You'd also want to use a logging set instead of an export set as the logging set won't miss any data if setup correctly. The sequence would look basically like what you have, but in a loop:

while(1)
   if (myChannel[0] > 0.24)
	  beginseq(startStream)
	  beginlogging(mylog)
   endif
   if (digin[0] == 0)
	  beginseq(stopStream)
	  endlogging(mylog)
   endif
   delay(0.1)
endwhile

Note that if myChannel is the channel you are streaming, this won't work because you aren't taking any data from it because you haven't started streaming. You'll need to manually poll it then start the streaming, something more like this:

while(1)
   read(myChannel)   
   if (myChannel[0] > 0.24)
	  break
   endif
   delay(0.1)
endwhile
beginseq(startStream)
beginlogging(mylog)
while(1)
   if (digin[0] == 0)
	  beginseq(stopStream)
	  endlogging(mylog)
	  return
   endif
   delay(0.1)
endwhile

This will loop and read mychannel until it goes over 0.24, then start streaming and continue streaming until the digin goes low.

Link to comment
Share on other sites

Thanks, that looks great. I am worried however that the second loop (with digin) will not allow me to log fast enough, since the the digin is checked every 0.1sec. Can I change the delay to 0.005? I found I need to stream at 0.005s, otherwise I loose the digin signal which happens very fast. I could catch the raising voltage at around 0.02, but after the apex the drop is much faster.

Thanks gain

Link to comment
Share on other sites

"if you need to catch a pulse you are much better off using a counter or timer and simply look for it to change counts. "

Could you please expand on that? Sorry for my ignorance, it is all new to me. What happens here is that the voltage (from a load cell) is streamed at 0.005ms and I need to catch the apex of the change at this rate. I rigged a contact switch giving me a pulse (as the digin = 0) right after the apex within miliseconds. Then I could detect the apex by looking at the logged file to find the pulse. The system vibrates badly after that and the apex will be lost within wild spikes of voltage.

I am measuring the draw forces in an archery bow, by the way. The bowstring is released (pulse!) and the forces (previously rising as the string is pulled) suddendly drop causing vibration of the grip, which translate to the load cell. I do not want the vibrations, only the max. force of bow. Unfortunately the forces generated during the bounce are sometimes several times greater than the max force of the bow. I plan to add a counter, but only to read the distance the string was moved to pull the bow.

Thanks a lot for help

Link to comment
Share on other sites

Cool application!

Anyhow, a counter is designed to count pulses. The one on the LabJack for example, will catch a pulse as short as 1 microsecond (I believe). It does this automatically in hardware, so you don't have to sit there in software and constantly look at the value. All you have to do is read the counter twice, and if you get a different reading, then you know that a pulse occurred in the time between the readings. So, unless your pulse is shorter than the minimum the counter / timer can handle (and the Timers are quite a bit slower than the counter), you'll catch it even though DAQFactory is only querying the device every 1/10th of a second or so.

Link to comment
Share on other sites

Thanks. I still do not quite understand how you suggest to read the counter. Do I create an extra channel, reading the same analog input voltage (from the load cell) set as the counter?

Anyway, I realized the U3 does not allow to stream counters or DigIn, only AI, so streaming a counter, or the second while loop in the code would not work. Or, am I missing something?

Back to the code above. I changed the code to stream and log another AI, together with the load cell. It looked exactly the same, except I used "if (channel[0] > 4)" instead of the "if (digin[0] == 0)", and run it as a sequence, but with no success (no response). With the second while loop removed, the streaming and logging started, but I could not stop logging, even when switched to the safe mode. Would you be kind to have a look at the DAQF file and correct?

Thanks again

Link to comment
Share on other sites

You shouldn't have to stream the counter. I believe that even the U3 supports polling of some channels while streaming others, though you'd have to ask Labjack to confirm. You aren't going to be able to do anything exactly on a data point, because when streaming, DAQFactory only receives data points in blocks, and so can only process them on a block by block basis. You'll need to setup the counter to use it (usually on FIO0). Look at the DAQFactory - LabJack application guide for me info on counters.

Link to comment
Share on other sites

  • 2 weeks later...

Thanks for your help. There is progress, but I still struggle with exporting the streamed file.

It seems, the file actually exported (written to disk) contains streamed data from a previous test, not a current one (that just ended), once the streaming and exporting is stopped. I start the test with a sequence:

beginseq(StartStream)

beginexport(myexport)

and end it with:

beginseq(StopStream)

endexport(myexport)

I tried to clear history of the three channels with a separate button right before running the test, but then there was no export file written at all. I also tried to put the line channel.ClearHistory() for each channel at the beggining of the StartStream sequence or into the other sequences, but again with no success.

How can I do it? How to have only the data of the test that just ended? I realize that the logging rather than exporting is recommended for streams, but I'd avoid it, since I get runtime errors or can not work with logged file until the DAQF is closed.

Thanks again

Link to comment
Share on other sites

OK, now I understand it. Everything works fine when I start streaming, then stop streaming and after that beginexport in a sequence. Once done, another sequence clears history.

It would be more convinient, the exported file contained only the data I need, not the extraneous stuff before and after. Is it possible to stop streaming, read the buffer, then export only on a condition, such as

if ((channelA[0] > x) && (channelB[0] < y))

beginexport(myexport)

endif

??

Thanks again

Link to comment
Share on other sites

Yes, but not in the way you are thinking. Export sets take expressions, so all you need to do is have the expressions in your export set result in only the numbers you want to export. For you, probably the best option is to use the filter() function on every item in the export set:

filter(mychan, chanA > 3)

filter(myotherChan, chanA >3)

use the same condition for all items. Don't use [0] or it'll only evaluate the most recent value.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.