01-26-2017 06:11 AM
Hello eveyrone,
This post follows this one: Click here
I've had a lot of help and encouragments from the pervious thread that lead me to re-think my code into a more "efficient" one. The one I present here is not the best I can do I am sure, but I need it to work pretty soon (work requirement), and will enhance it through time.
1) I've followed most of your advices and shrinked a little bit the loops (expect the 3rd one, but it will come)
2) Bob Schor is privately helping me a LOT! If by any way, Bob, you are reading this post: I am still in the process of enhancing my code with your help
3) the code itself: I want to aquire my data every 500ms (hence the timer on the dequeue element of the 2nd loop). My aquisition is done in the True case of this loop. What I'd like is to acquire a set of data every 1/2s, bundle it, and send it to the 3rd loop where it will be displayed and averaged every minute.
4) what it does: as you can see i've put indicators for displaying the iterations of my loops, and obviously my code doesn't iterate every 1/2s...
Is there a way where I could get closer to one iteration every 1/2s (or every 1s)? For a reason I ignore, my loops are slower than the set timer...
As I said, I am in the process of cleaning that code, and enhancing it, but I am obviously keen to take any critics about it.
(btw, this piece of code works properly right now: data are aquired, averaged, and saved, etc.).
Thank you for you help,
Flo
01-26-2017 06:48 AM - edited 01-26-2017 07:04 AM
First of all, you should organize your project files better. You could use real or virtual folders to keep subVIs in one, typdef ctrls in another, and you should clearly name your top level VI, like "Main.vi" or "Top-level.vi"...
I can really see that you improve (I saw some of your earlier versions). Keep on learning, and you will get even further with LV programming.
About your timing problem:
EDit: more about timing. Imagine what happens now: your Dequeue function times out, and you acquire data from the DAQmx channels, plus the Serial line. These two steps lets say require "N msec" time. When these steps stop execution, we start the next iteration of the While loop, and THEN we wait an additional 500 msec. It means, the elapsed time between two acquisition steps will be N+500 msec. As an ugly workaround, just change the timeout value of the Dequeue function to zero (immadiately time out), and put a "Wait until Next ms multiple" function with a value of 500 wired to it, into the True case of the Case structure.
Edit2: actually i discovered, there are even TWO serial DAQ subVIs in your True case. I wonder how fast they can execute...
EDit3:
Actually I never used the Dequeue with a zero timeout before, I did not know the behaviour. I think it is better if you specify some lower value than 500 for timeout, but not zero, so your code has the chance to process incoming commands. Set the Dequeu timeout like 200 msec for example.
01-26-2017 07:19 AM
A simple way to get the timing it to have a new loop that simply queues the Sample command with a 500ms. If you try to solve it within the consumer you'll inevitably get issues with execution times and what if, e.g. a command is queued after 400ms? The timeout will reset ...
The main point being you want as few disruptions as possible. Maybe it's even better to simply have a 500ms loop that samples and does nothing else.
/Y
01-27-2017 06:22 AM
Thank you for you for your help. Some good news after some good advice:
- I've tested the true case in a simple while loop (attached to this post)
- I've tried to set the dequeue at 0/100/200ms. I dont realy see any change.
- I've put a wait until next 500ms inside the true case + moved my daq reading function there too
and:
- the number of iteration reaches 120 after 1min of running. that was perfect. so the code /daq/pumps are able to answers a request every 1/2s (for display purpose only)
- here is a picture of the result after 0:59:59m of running (almost a minute). the first loop runs at 1/2s, but the third one doesnt exactly follows the second one. I don't understand why...
Yamaeda, I see that there may be a good idea in running another loop, not sure that I've understood your idea behing it. could you please be more specific? I am almost there, and it feels good 🙂
Cheers,
Flo
01-31-2017 03:50 AM
Up ?
Sorry for that, but I am struggling with that slight offset between my loops. Any idea? or examples?
Flo
01-31-2017 04:11 AM - edited 01-31-2017 04:22 AM
Why do you expect that the iteration numbers are matching at the Data Producer and Consumer loops? That is the whole point behind the Producer/Consumer design, that you decouple the code running in the Consumer from the code running in the Producer 🙂
You produce data in the producer loop, in a frequent and more or the less precise manner, and Enqueue this data at regular times into the Queue, which is a lossless way of data transfer. Then you Dequeue this data in your Consumer loop, and your code has time there to do file logging, data analysis, calculations, etc. So that is the point, the Consumer can be a bit slower, and it will process the data as it can available in the Queue. So it is totally normal, that a Consumer loop is "lagging behind" the Producer loop, lets say, "expected behaviour"! That is why it is important, you produce some kind of time information (Waveform, absolute time stamps, etc.) in the producer, and then it just does not matter when this data gets saved into disk: the time info is preserved since it was created in the Producer loop...
01-31-2017 05:39 AM
okay, Thank you.
I think I will bundle the data in the scond loop then, and average everything in the third one...
That shoul do the job