12-03-2019 04:40 AM - edited 12-03-2019 04:42 AM
Hello,
To start - I am new to working with LABVIEW and it's VIs - this could be a very obvious problem! I will attach my VI below (uploading issues)
The Task and Problem:
I have an encoder wired up to the DIs of a USB-6218 BNC, along with an external trigger signal also wired into a DI. This external trigger is coming from an output signal from a camera, sent at the point of image capture, and sampling at just under 1kHz for about a minute per test.
I am interested in the position of the encoder at each frame of the camera, and I am recording information this way to maintain parity with other measurements. The issue is that I seem to be sampling more data points of the encoder position than there are frames from the camera.
The VI set up:
I have both sets of quadrature signals from the same encoder (A,B,Z and invA,invB,invZ) inputting into counters, then DAQmx Reads within a while loop and using the trigger signal as a sample clock. I have (through fudging and trial and error) set it up to record both encoder position signals and the timestamp into an array per iteration of the loop and then, at the end of the test (Manual STOP) send this array to write to a .csv file. The VI functions as I would like bar the extra data.
I can post-process the data to remove the extra entries but the project really needs two data sets of the same length. The USB-6218 does not have a minimum sample rate. How do I set this VI to record data from each and only each sample clock pulse?
Thanks
12-03-2019 11:04 AM
I for one am not on LV 2019 yet. Please use "File-->Save for Previous Version..." and repost. I'd recommend saving back to LV 2016 or earlier.
One initial concern is that your encoder signal names sound like they may be differential outputs while your DAQ device wants single-ended digital with a common ground.
Another concern is your description about timestamping. It sounds like you're reading one sample per iteration and attaching a PC system timestamp to that sample. That isn't going to be very accurate at all.
Overall, this app sounds like it should generally be pretty straightforward. Using the external signal as a sample clock should cause 1 encoder sample to be taken for each clock cycle. Just be sure your DAQ app is started before the camera starts generating these timing signals.
I can probably comment more after you post code in an earlier LV version.
-Kevin P
12-04-2019 02:52 AM
Hello Kevin,
Thanks for getting back to me. I've attached a version backsaved to v14.0 which should work.
In addition to the A,B,Z and invA,invB,invZ channels, I have routed the encoder ground to a DGND port on the DAQ to get distinct signals that can be used by both ctr0 and ctr1. I am doing this because... I can?! I have two counters and more information is always useful. They're used as a check for whether the primary channels are reporting edges correctly, averaging any error within the encoder, and to screen for any EMF noise from the motor on which the encoder is attached.
Yes, timestamping. I think this is where I am falling down - your points make a lot of sense and I have seen considerable variation in this timestamp which I am currently attributing to PC jitter. I am after 1 sample from each input counter per clock cycle, read simultaneously and attributed to the same timestamp - and I think I have it set up that way.
What alternatives do I have for timestamping that are more accurate? If I have to sacrifice the use of ctr1 as an encoder input for an accurate timestamping method then that's not the end of the world.
I have the app setup sequence in that order: DAQ running and ready to receive a signal, then camera signal starts. Interestingly I get an error at the end of test if I stop the camera signal before the VI. I'm assuming this is a timeout error? Is it some datapoints working their way through the loop? Its not a big concern as the final few data points will not be significant.
Thanks,
12-04-2019 08:59 AM
I'm not quite sure I understand the physical setup, and the desired question. Here's what I thought you said:
If these assumptions are more-or-less correct, can you do the following (I not that familiar with the exact model of USB DIO device you are using):
Wouldn't that give you the data you need?
Bob Schor
12-04-2019 09:37 AM
Hello Bob,
Thankyou for responding.
Yes you are correct, that is what I am trying to test, and have it set up as you describe - with encoder outputs going to two counters, and those counters both being read with a sample clock from the camera pulse.
The problem I am encountering is that the VI is reading/storing more data points than the camera is acquiring. Even though it is (in theory) being read in sync with a pulse.
It is only about 1% more, distributed amongst the rest of the data. This means I cannot accurately compare the encoder data with the camera.
12-04-2019 10:07 AM
I made a few quick mods, but don't presently have time for a long writeup about a lot of details. The attached code is NOT A FINISHED PRODUCT!
Brief comments:
- the 2 encoder tasks may need to be sync'ed with an "Arm Start" trigger
- each iteration, there's a 200 msec delay then all newly accumulated samples are read
- the sample freq is an average since the previous iteration
- each of the multiple samples read in an iteration is tagged with the same elapsed time value in the file. This is not great, but was all I had time for. It at least tells you *something*.
-Kevin P
12-09-2019 03:12 AM
Kevin,
Thankyou for these modifications. I think I understand most of the changes here, you're very kind. Once I can get my hands back on the hardware I will run this, get my head around the restructuring you've done and iron out the rough edges.
Cheers,
12-09-2019 08:00 AM
The code you attached has Encoders, but no Camera! I also notice that you are creating a Chart inside the Acquisition loop -- since the DAQ loop should run once per Trigger pulse, it needs to be able to "wait" for the Trigger pulse, which means it should not do anything that might slow down the loop (like all the processing that you do). Check out the Producer/Consumer Design Pattern.
In order to understand how Camera and Encoders are synchronized, we really need to see the entire Project. If you compress the Project's folder to get a .zip file, you can attach that single file to a Reply, and then we'll have "all the pieces" ...
Bob Schor.
12-09-2019 09:54 AM
Hello Bob,
Yes, the code I attached is referring to only the Encoders - the camera data is a completely different measurement process which is not going through LABVIEW and is why I am after accurately aligned data for comparison.
Thankyou for the advice, I will trim down much of the ancillary processes within the loop.
Could this be why I am logging more data entries than clock cycles? I would guess that an incomplete loop, one that has not completed all its processes before another data set is inputted, would record fewer loops, rather than more. Would you agree?
As I mentioned earlier, the camera and encoders are synchronised by the sample clock: I am using an output signal from the camera physically wired into a DAQ and assigned as a sample clock. What is still stumping me currently is why the data out of this VI is longer (more entries) than the same dataset from the Camera.
Does the sample clock trigger on both edges or just the rising edge? For if it is trying to sample on both edges and trying to complete too many operations, then this could be the issue.
12-09-2019 11:20 AM - edited 12-09-2019 11:20 AM
I just did a brief review of the thread to try to focus my comments better.
1. FIRST IMPORTANT POINT: you do not need your software loop to *iterate* at 1000 Hz in order to make your counter task(s) acquire *samples* at 1000 Hz.
The code I posted takes advantage of these DAQmx task capabilities by doing the same *sampling* but drastically reducing the *iteration* rate down to ~5 Hz. It still collects all of the data, and the data is still being sampled with hw-precise timing. But because the chart is only being updated 5 times a second, it's gonna be able to keep up.
2. NI's DAQ devices will sample on only *ONE* edge of a clock signal (the "active" edge), not both. It's generally the rising edge by default, but can generally be configured either way.
3. So you should get exactly 1 valid sample for every active edge coming from your camera. In your original code, you would have gotten 1 extra invalid value when your calls to DAQmx Read timed out in the absence of any further active edges. My modified code shouldn't give you any extras.
4. I would investigate your extra samples this way: use MAX or one of the shipping example programs to simply *count* the # of active edges coming in on PFI11 (or wherever else you've wired the signal from the camera). Then try configuring your camera to capture 1000 frames. How many active edges did you count at PFI11? If > 1000, that's why you got extra samples. Either the camera puts out pulses you aren't expecting, or you've got glitchy noisy signals that produce phantom edges for your DAQ device.
-Kevin P