Hi Romain,
I took a closer look this morning, at your code.
I should have said something eralier!
You are trying to write formatted text inside your loop!
This is a major problem in more than one way. First the formatting the data as text requires allocating memory for the strings fom time to time. This will impact the determinism of the loop because the work involved in allocating the memory is rather demanding and of unknown duration. I avoid strings all together in my deterministic loops.
The next issue is the writing to disk. This is another thing that will detroy your determinism. Try shutting down all of the file I/O related code by commenting it out.
Please try that experiment and let me know if your loop keeps up and no errors are generated.
Re: buffers
I generally over allocate buffers. If I have memory available I will use it. I will set my buffer size to be twice as large as I expect. This handles interuptions (This comment mostly applies to non-RT environments where determinism is not expected).
Re: Freq of updates
It looks like you are attempting 20 updates a second. This should be atainable if we can get your loop timing correct. I suggest you use a millisecond timer to measure the actual repetition rate of your loop. Once you have that under control I suspect the rest of the code will fall together nicely.
Re: Architecture
An RT application is generally broken down into two major divisions "Deterministic" and "non-deterministic". In your application, the formatting and file writting are non-deterministic operations. I would suggest you restructure your VI. The general structure would be as follows.
1) Initialize Operations
This could open files, configure DAQ, and create a queue. After this phase was complete, two VI would then execute in parallel threads, one set as "Time Critical" the other set for Normal default.
2) Time critical VI
THis VI will perfom all operations associated with hardware output and input and keeping up with the associated hardware buffer demands. Any data read from the AI operations can then be inseted into the queue created durring the initialization phase. Updates of the values written to the AO can be handled using a LV2 style global (functional global, global,...). THis TC VI should sleep most of the time waiting for the next opertunity to read from the buffer etc.
3)Non-TC Loop
The non-TC loop would read from the queue that created by the inititalization phase and is being updated by the TC loop. The queue elements can then be formatted as text and written to file (Note: formatting data as text is demanding of CPU resources. If the application demands are xpected to increase, try writting data as binary and re-formatting the data as a post processing phase.) This non-TC loop would aslo read from the user interface output settings that can be written to the LV2 global used by the TC loop to update the AO.
4) I recomended a LV2 global because it can be set as "sub-routine". This gives you the option of using the "skip if busy" option when you make calls to the LV2. Search on "Skip if busy" to see how to use this feature.
I realize that this may be quite a bit of work to restructure as I have outlined but the results should be worth it if you want to keep your AO ans AI happy.
General comments
If you have the opertunity to upgrade to LV 7.1, you will find some of the enhancements very useful in diagnosising what is happening in your application. There is a function that allows you to capture a snap shot of the of the execution history of your application. If you upgraded to LV 7.1 an ran the exection trace tool in your aplication, I believe it would indicate that you application is hanging on the memory mangaer or the file I/O.
Please post the most recent version of your code so I can stat on the same page.
Keep me posted if you continue to have trouble.
Trying to help,
Ben