07-03-2017 02:56 AM
I created a quick VI today to try and test both my understanding of the Frequency measurements (several improvements to that already, so that's good) and make sure my hardware wasn't going to die on me (it seems to have an annoying habit of requiring the PSU be reset for some unknown reason that I expect might be related to some protection circuit in the USB-6356).
My VI is below. I'm wondering if anyone can comment on how to best keep measuring 0, when no pulses are incoming. My first thought is to set a relatively low timeout on the DAQmx Read, check the output vs Empty Array, and if empty, trigger some communication indicating to increase the Time shift register in the lower loop by the timeout value.
I'm concerned that this might not be very accurate, and also here the two loops are close to each other (see spoiler) but in real code might be more separated - the more complicated the communication required, the more wires I might end up needing between VIs or classes.
I can't just output a 0, because that will cause problems at the 1/x node. Presumably I could output some known low value at a known frequency to mimic zero, but that's fairly hacky (and precludes using the code to actually measure slow rotation rates).
The channel wire Last Element input is pretty nice though...
07-03-2017 03:20 AM
Usually if you have a 1/x funcion, you make a security check for 0 and handle it in some way.
/Y
07-03-2017 08:27 PM
I think this works for me. It can lead to some flickering when approaching zero, presumably because some intervals of timeout pass without a pulse, and others don't - increasing the timeout would reduce the minimum speed but make the updates appear less smooth.
For some reason, I have to wire the Valid Input? input to the write channel node, otherwise it doesn't send anything... Clearly there's still a lot for me to learn about Channels but they were an interesting tool to try and use here. The timeout is also pretty confusing, but this configuration seems to work.
As the rate increases, I worry that the loops sending only one element at a time will become a limiting factor. Will check that next time I have faster rotation.
07-05-2017 04:42 PM
A few comments in no particular order:
1. I haven't taken the plunge on Channels yet, but it looks odd to me that you've got same timeout value wired to both your producer and consumer loops.
2. Don't like your calculation of time in the consumer loop. The frequency measurements themselves can be used to calculate cumulative time with hardware precision.
3. You probably will need to do multi-sample reads, especially due to the relatively high overhead of single-point USB reads.
4. Eventually, you'll need to make a clear decision about how to handle frequencies so low that it *might* mean the signal source has stopped. There's more than one reasonable approach, but be careful to follow *all* the implications of that decision.
For example, if you decide that anything below a certain threshold will be treated as 0 freq, you have to deal with the impact of that 0 downstream. You need to think carefully how to accumulate time across this discontinuity. Etc.
-Kevin P
07-09-2017 11:53 PM
This is undoubtedly a stupid question, but how do I go about your point 2?
@Kevin_Price wrote:
2. Don't like your calculation of time in the consumer loop. The frequency measurements themselves can be used to calculate cumulative time with hardware precision.
I can't seem to find a way to get both a Frequency and a Time from any of the DAQmx Counter Read outputs.
A Frequency measurement will allow me to get Frequency (in Hz, by default) as a DBL or U32, or any of 1D Pulse Frequency, Time or Ticks. The Time could be cumulatively added to build a time array, but then it seems I have to carry out the same 1/x to get Frequency (plus an addition for High + Low time) and the ticks is more or less the same. Frequency meanwhile gives the Frequency, which I guess is the same as the 1D DBL Array, and Duty Cycle, which as far as I can see doesn't help me.
I can use the Angular Encoder measurement to get Position, but then I need a derivative for speed, and some handling for the 360->0 or -360->0 transition (if I got the right pairs. Would check again if I tried it). As far as I remember, when I've tried the Angular Velocity measurements I've always received an error.
I'm sure you're probably right about point 3 - I'll probably find this easier if I just drop the channels, which are adding confusion to the setup (at least for me), but I thought this was a good place to try them out in a small demo.
07-10-2017 09:24 AM
I'd just read Frequency as a 1D double array. The "Pulse Measurements" are a somewhat newer feature, at least compared to when I cut my teeth on DAQmx, and I don't have enough familiarity to make recommendations.
You're right of course that calculating cumulative time from the Freq array still leaves you stuck with the 1/x problem when Freq=0. Handling this *well* may get complicated, but it's probably a better tradeoff. Calculating cumulative time gives you excellent timestamp resolution when pulses are present, at the expense of some programming difficulties to skip over the time discontinuity when they aren't.
Here's an outline for an approach:
1. when you encounter a timeout in your 1D Freq read, assume you've probably encountered a near-0 pulse rate.
2. do a followup read of "all available samples" b/c those will be contiguous with your previous reads.
3. set a boolean flag to tell you that you need to re-establish t0 from PC system time for the next burst of real pulses
-Kevin P
07-10-2017 09:58 AM
Thanks again for the response.
So reading through, it seems that you think the method with the 1/x to get cumulative time is appropriate? I guess I misunderstood your comment regarding getting a time measurement from hardware.
Like you highlighted, the timeout does indicate a low frequency/low rotation speed, so for a long enough timeout (still below 1s given 3600 pulse/rev) I can assume the rotation rate is almost 0. I'll take a look at the idea of a boolean flag - that might be quite workable as an alternative to adding timeout duration per timeout, as it were.
It's a shame that I can't seem to get a T0 output from the Counter for any given sample. Obviously a Waveform output is impossible given the varied spacing but a start time might be convenient.
Like you said, I'll make sure to get the "All available samples" if timing out for a given number of samples.
07-10-2017 11:16 AM
What is 0 revolutions ?
What time periode do you want to look at? sec, min, ..., time of earth or universe?
Can we measure DC?? Or is it just low AC ? 😄
07-10-2017 11:31 AM
The output is a square wave (approximately) from a push-pull rotary encoder, but not TTL; the input is 12..24V so even at 12V the high level is around 10V. This can be read by a digital input for a counter, but only just... probably a series resistor or similar would be a good idea.
3600 pulses are output per revolution, for a range of rotation rates between 0 and around 2000 rpm, or 0 to 120kHz as a frequency.
Measurement timescales are likely to be on the order of hours, but although I need to be able to measure at a high frequency it doesn't have to be all of the time, if that becomes problematic. At the moment, trying to set up different rates is more complicated so I'm testing at around 500rpm (30kHz) for only a few minutes. In the future, perhaps use of Substitute Actor in the Actor Framework would allow changing the rate whilst having the actor calibrated to make either full speed or averaged measurements. I'm open to better suggestions...
07-10-2017 11:44 AM
Two quick followup thoughts:
1. maybe it'll be convenient to stop and restart the task at the Freq ~= 0 point? Then you could query system time for t0 right when you restart. That might help avoid managing a boolean flag across a producer/consumer boundary.
2. I think your device supports a frequency measurement mode that lets you use a constant-rate sample clock. I've not yet had occasion to dabble with this mode however, so I can't say much on whether it's helpful for your case or any nuances of how it behaves for Freq ~= 0.
-Kevin P