Oscilloscope Like Trigger Function On Graph


Recommended Posts

Hi there, 

I'm new to DaqFactory and hope this is a fairly straight foward question.

 I'm sure there must be a way to get a graph in DaqFactory to work like an Oscilliscope and trigger a freeze (or similar on the left hand side of the graph) based on a specified value everytime the leading edge of a reaping signal comes around? 

I had a look around the forum but couldn't find an example of a code snippet that would help me out. 


Thanks in advance!



Link to comment
Share on other sites

Thanks for the reply. 

I suppose that's what I would like to do. But maybe there's a better way? 

I have a Labjack U6 and I followed the manual in section 9 to get the channels onto the graph in stream mode. The code in the manual maps a sequence to button to activate the streaming. I was wondering if something similar can can maybe be used as a automated trigger?

I will have a series of repeating signals at about 20Hz that I'd like to analyze live and in quite a bit of detail so will need sample rates much higher than that. I am basically looking for an oscilloscope type display but on the computer with the capability to add multiple signals onto a single graph. 

Thanks again!



Link to comment
Share on other sites

 I'm not sure if there is a better way.  It just depends on whether this works for you.  I wouldn't stop/start streaming, but would instead just let it stream continuously.  The technique you'd have to use would depend on how long you want a particular trace to remain on the page before it gets updated or goes away. 

If it only needs to display for a short period, say under a minute or two, then you can simply freeze the X axis scaling and adjust it every time the trigger occurs.  To do this, simply set the X Axis Scaling to two global variables, let's say "GraphScaleFrom" and "GraphScaleTo".  Make sure and uncheck "Use time width".  Create these variables, along with a threshold variable in a start up sequence.   Next, go into the Event for the input channel, and add script similar to this:

if ((myChannel[0] > threshold) && (myChannel[1] < threshold))
   graphScaleFrom = systime() - 1
   graphScaleTo = systime() + 1

Note that the way I have it will actually put the threshold point in the center of the graph, with one second on each side.  You can just adjust the math to put the threshold X point wherever you want.

The problem with this technique is that the graph uses the Channel's History to draw and you have new data constantly coming in.  So, eventually, you will run out of history and the graph will start to disappear.  You can, of course, set the history quite large.  So, if you are sampling at 100hz, you could set the history to 360000 and get an hours worth of data.  Then a triggered trace would remain for up to an hour. 

If you need it to last longer than the history (because really you don't want histories bigger than maybe 1 million), then you need to use a different technique.

Link to comment
Share on other sites

Thank you very much for the reply. I was able to implement this function and it works. Sort of.

Unfortunately it is a bit unstable (there are periods of up to 10s when nothing is displayed in the graph) and sometimes the full image isn't propagated. To work out the kinks I have a simple one sensor setup and am triggering off a saw tooth signal at 10Hz between 0-5V. I have had to setup the thresholds for myChannel[0] and myChannel[1] far apart to get it to work about (about 0.5V). I was wondering if this might be the cause of the instability? I can get it running slightly more consistantly if I up the scanrate and then the history. However then the screen draw time can get very high (several seconds) if I do this. It also only seems to work if I set the time (x) axis to linear.


Any further tips? Maybe theres a better way to do this? 


Signal drop.png

Trigger Function.png

Stream Start Function.png

Link to comment
Share on other sites

I'm not sure of everything you did.  I've attached a sample showing it working with a test channel.  The test channel has a conversion just to give it some noise.

Note that your event trigger is wrong. The threshold values should be the same for both parts of the if().

Also, don't use var. notation.  That is very, very old syntax.  Instead declare your variables and initialize them in an auto-start sequence.



Link to comment
Share on other sites

Thank you very much. I got there in the end. Using the method you used. Apologies, I didn't send through all the information last time.

I think there might be a problem with running the Labjack in stream mode using the StartStream sequence I had defined (section 9 of the manual) and trying to actuate the trigger. I have attached 2 files below. One with and one without the stream function. I am using a 5V 10Hz saw tooth profile from a signal generator to test the trigger function. In "normal mode" the trigger function works fine. Using the "stream mode", as defined in the function, I run into the consistency problems I tried to show earlier.  I also tried running only the pressure signal in "stream mode" and the trigger signal in "normal mode" but that also runs inconsistently.

While I can type in a timing value of say 0.001s into the channel input, the frequency doesn't go above 250Hz looking at the data values coming in on the table tab. For my test setup I am expecting to see oscillations at hundreds Hz and above which I will need to fully capture and would like to display using the graph trigger function, so I will need the scan rate to be sufficiently high. 

Is there another way to get the data from the Labjack into Daqfactory using stream mode?





Link to comment
Share on other sites

OK, first, the LabJack takes a minimum of 4ms to respond to a query, so any Timing value < 0.004 will do nothing but eventually cause Timing Lag errors as the hardware is limiting the speed of acquisition.  That is why you get a max acquisition rate of about 250hz.  250 samples * 4 ms each = 1000 ms = 1 second

Now the issue with streaming is that the LabJack sends DAQFactory the data in blocks, and DAQFactory only triggers the channel Event once per block of data.  This is because DAQFactory script is not particularly fast, and would bog down the acquisition if you tried to run it at 10khz.  So, the issue with your trigger is that when you do [0] you are only getting the most recent reading from the block of, say, 50 readings, and so are likely missing the trigger.  Instead you have to aggregate functions to find the peaks, namely max() and then use gettime() on the result of max() to get the time of that max.  You also need to keep track of how long it has been since the last block was received so you only do max() on the data in the most recent block.

To do this, in general terms, you will need another variable, say "blockStart" which will hold the time the last block started.  Initialize this to systime().  Then in the Event for Trg, capture all the data since then by subsetting in time:

private newData = Trg[blockStart, Trg.time[0]]
blockStart = Trg.Time[0] + 0.000001

Now you can process the entire block:

private themax = max(newData)
if (themax > 4)
   graphScaleFrom = getTime(themax) - 0.5
   graphScaleTo = getTIme(theMax)

This will trigger a little differently though, and cause a long peak to trigger on the end of the peak, not the beginning.


Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.