LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

reading analog output channel (or effector) synchronously with analog input channels into arrays in parallel loops

You will need to clean up the queue when you are done with it, and it may be useful to flush the queue if you want to reuse it for a new situation, but the basic clean up of a queue is in the template for the Producer Consumer architecture, which it seems like you are doing fine. You'll just need to carefully step through the logic of your application. You may try switching certain points with a control and runing as a highlight execution to try to verify every step.

 

As far as organizing code, it does not have to be a single all out force on the code. Start by creating a project for the VI, and every time you work on a piece of code, try to wrap the relevant logic into a VI. Seeing it as a single block can help visually see what's happening easier, and can reduce complexity of interpreting code.

 

 

- Regards,

Beutlich
0 Kudos
Message 11 of 36
(1,680 Views)

Hi Eric, thanks for the reply.

 

 

So i gather it's not appearent why the consumer loop would be producing zeroed arrays after two iterations of the producer loop?

 

I'm usually running about 50 loops of the producer loop, then the VI will go over to the file saving frame, but when it repeats, it can't start the queue - i will look into a 'cleanup' to remedy this.

 

One question you might have missed: any suggestion as to what would be a good value for the buffer size on the continous acquisition VI?

 

thanks.

0 Kudos
Message 12 of 36
(1,677 Views)

Hi Eric,

 

I removed the queue to try to narrow down what's causing the zeroing of my data. It's now clear that it's not the queue, but something about the DAQmx acquistion and/or output configuration that's zeroing or timining out?

queue-removed.jpg

If i look at the output carefully,

Graph16.png

I can see that the first time the loop runs, in this case at a sampling rate of 10kHz on the DAQmx input, the first 0 to 5009 points of the high force state are zeroed out (they should be 0 to 5030), then when it drops to low force after the time delay, it records ~70 points then it zeroed out again until almost the next output voltage flip. The behaviour with a queue is the same.

 

So what could be the culprit here? an inappropriate buffer size for the continuous acquisition? The DAQmx timing VI should be outside the loop instead?

 

thanks for any help.

0 Kudos
Message 13 of 36
(1,658 Views)

So i gather it's not appearent why the consumer loop would be producing zeroed arrays after two iterations of the producer loop?

 

it is not apparent to me what your code is doing. I can understand the DAQmx features being used, but the processing and calculations you are implementing is application specific and not immediately obvious. You may try removing the processing and putting controls directly into the DAQmx data calls (or wherever is most intuitive for you) so you can feed the AO directly and view the AI directly.

 

One question you might have missed: any suggestion as to what would be a good value for the buffer size on the continous acquisition VI?

 

Most of the time I don’t configure the buffer size, and it does not seem like you need to either in your application. If you set up the DAQmx task, it will automatically manage the buffer for you, and there are no clear demands in your system for changing the behavior of the buffer.

 

So what could be the culprit here? an inappropriate buffer size for the continuous acquisition? The DAQmx timing VI should be outside the loop instead?

 

At least part of the issue is probably because you are calling the DAQmx Timing VI inside the producer loop. There is an implicit state model occurring with DAQmx tasks. While it is possible to manipulate all of the states directly, it is generally adequate to simply understand them as setup/start/stop states. The DAQmx Timing VI sets up the task before starting, and calling the DAQmx Read or Write can implicitly perform a state transitions to move the task up to where it is capable of performing the read/write function. It does not look like you need to reconfigure the timing on every loop, so try just moving it outside the loop, possibly placing a Start Task VI before the loop also. You can reference the examples in the example finder on Analog Generation for examples, many of them have a Start VI before the loop and a DAQmx Read/Write inside the loop.

 

Another random note: I recommend dropping the local variable ‘while loop halt’. I see you added this so that both loops stop together. The usual practice is to have the consumer loop perform error handling, and always process unless the wait for queue element returns an error. When you destroy the queue, it will throw an error, and then you handle the error to exit the loop. The plus with this is that if you have any other errors, you already have a basic error handling case J. In general, be very wary of local variables (you should feel a little bit uncomfortable whenever you see/work with them) because they break data flow and can turn ordinary code into extremely complex code within a couple of revisions. A data flow language like LabVIEW does not need variables to be storage buckets for data like procedural or OOP languages, and often a complicated structure using local variables can be replaced with a few well placed wires when thinking in terms of data flow. Breaking away from the other paradigms of programming can be tough (like relearning to ride a bike), but there are many powerful advantages once you’re familiar with data flow.

- Regards,

Beutlich
0 Kudos
Message 14 of 36
(1,649 Views)

Hi Eric,

 

I've moved the DAQmxTiming VI out of the while loop (we had this inside for buffer adjustment in every loop), and placed a DAQmxStart VI before the loop starts. [Labview for everyone 3rd Ed. shows the same thing you described on p.510]

 

An interesting thing occured with the queue: it now works with every overall iteration. I'm not really sure why that fixed itself.

 

I've been looking carefully at the output. I've been testing my VI at 10kHz sample, with 100 and 500ms consecutive steps, which should produce 1000 and 5000 datapoints per step, respectively, while the total number of measurement steps should be 50. I do in fact see 25 step at low force and 25 steps at high force, with slightly less than 1000 and 5000 points in these steps.

When looking at the long zeroed sections, there is one leading in, and one leading out, then 25 intersperced.

 

From that, i would almost conclude that data is not actually being lost, but the DAQ acquisition is inserting zeroed points.

The lead in and lead out are both approximately 5000 points, while the zeros intersperced go as 4013, 1, 3996, 4014, 10, 4004, 4014, 12, 4014, 10, ... Or in other words, the interspacing zeroes usually correspond to 400ms of data, not counting the small 1ms blips.

It's definitely a systematic pattern.

 

As for the analog out, its output doesn't appear to go to zero during real loop iterations (using an indicator to watch its output).

 

So maybe i'll try to drop the sampling rate of the continuous acquisition to see if the zeros go away, or maybe change the autostart on the analog output voltage? Otherwise, i don't really know what to do to solve this.

 

thanks.

0 Kudos
Message 15 of 36
(1,638 Views)

Hey Eric,

 

I got onto the instrument and tried some more debugging. Visually on our CCD camera, the steps look as they should, but the data output, not quite.

 

The analog input wires also goto zero (outside the loop at least)

FnE_noqueue.png

voltages_noqueue.png

It might not be clear, but all three channels have the zeros recorded in,. This is for 20 steps, and you can see i got 10 low and 10 high steps.

 

With a queue, the results are the same.

FnE_Wqueue.png

voltages_Wqueue.png

The Force and extension from above are related by a force-extension curve:

FEC_example.png

 

Thanks for any insight into these zeros...

0 Kudos
Message 16 of 36
(1,626 Views)

Which part of the process are the zeros appearing from? Are those graphs from the data coming straight off the DAQ Read, or are they from graphs right before being queued (some producer processing), or are they in the consumer loop, or are the in the file (post processing)? There should not be any zeros padded on the DAQmx Read, but you have some vector math/decimation/other processing parts that are probably the culprit.

- Regards,

Beutlich
0 Kudos
Message 17 of 36
(1,606 Views)

Hi Eric,

 

the PSD voltage graphs are directly off the DAQmx analog in, except that they are carried in a bundle.

path.jpg

 

these voltages are represented here without processing:

FnE_noqueue.png

it appears the zeros are inserted by

0 Kudos
Message 18 of 36
(1,604 Views)

the flatten 2D array is just this

flatten.jpg

 

0 Kudos
Message 19 of 36
(1,603 Views)

So the problem is with reshaping the multiple channels into a single array. It may be from a channel reading zeros (because it is not being used) that is getting inserted into the mix. I don't see that flatten in your actual code, but I suspect that you don't want to actually append one signal to the other, and this reshaping is what's causing a mix up. Try working with a 1D array of waveforms, and when you need the actual values, using the Get Waveform Components. I find these easier to work with conceptually than a 2D array for my signals.

- Regards,

Beutlich
0 Kudos
Message 20 of 36
(1,592 Views)