From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

Counter/Timer

cancel
Showing results for 
Search instead for 
Did you mean: 

Recovering from task stopping when buffer overrun

Driver: mx 7.3
Software: C++ 6.0
PCI-6220

I have a situation where I have a counter task that is running continuously, although when a test isn't being performed the program periodically monitors the most recent reading for various reasons. When a test is being performed all of the data is transferred to local variables and stored - this is no problem. I am looking for a bug that occurs when the buffer overruns because samples aren't being read for an extended period (no activity). Almost 100% certain that the task is being stopped because of this but cannot seem to recover from it.

At first I tried to check for this using DAQmxIsTaskDone with the intention that I could just re-start it. I'm not sure why this did not work.

Then I read about DAQmxSetReadOverWrite and decided to set this to allow overwriting when I didn't care and then change it to disallow it when I needed that. This did not work either, and also had the affect of forcing my computer to spontaneously re-boot the 4 or 5 times I tested it. I confirmed this by commenting it out and the symptom disappeared.

I feel like there is something I am missing here because all my efforts have not produced any results.

Ed
0 Kudos
Message 1 of 5
(3,555 Views)
Ed,

Hi again on a different thread. I think there are ways to handle your situation, but I don't know the exact syntax for DAQmx dll calls -- I'm a LabVIEW guy. Let me offer up a few thoughts from the LV world.

1. DAQmxSetReadOverWrite - I used a similarly named DAQmx Read Property under LV hoping to let the acquisition buffer keep overwriting itself circularly if I didn't read data out of it for a while. It didn't work for me either, though the failure was only an error code and no data returned not a system crash. I found a workaround for my app and I hope a variation on it can work for you.

2. By default the 'Read' operations want to read the earliest unread data. This is because of DAQmx properties with names like 'RelativeTo' and 'Offset' that have default values of 'earliest unread data' and 0 respectively. You could set them to 'Most Recent Sample' and -100 if you wanted, then when you perform a 100 sample read you'll get just the 100 most recent points. This was all I needed for my app and it worked fine. I could let the buffer overwrite dozens of times between reads, and as long as I set up the read position properties I would get data back without errors.

3. There are additional properties to query such as 'Current Read Position' and 'Total # Samples Acquired". I don't recall the details, but these seemed to behave a little odd I thought. Like, I think 'Current Read Position' would reset to 0 and stay there after the first buffer overwrite. I *think* 'Total # Samples' kept a correct running total though I'm not sure how much that'll help your specific problem.

4. During testing, I expect you need to acquire a continuous stream of data with no interruptions or overlaps, right? Can you do it by simply making your buffer big enough to hold all the test data and then reading it all out using the method in step #2 at the end of the test? If not, there still *should* be a way to accomplish what you need, though I'm not 100% certain that it'll work. Here's the idea I picture:

a. Read, say, 1000 samples setting up RelativeTo='Most Recent Sample', Offset=-1000.
b. Query DAQmx for the 'Current Read Position'. This could be a problem because the way I remember it, this value quit updating after the first buffer overwrite. But maybe that's just in LV, or maybe there's another property to query that'll give you the right info.
c. Now read, say, 1000 samples setting up RelativeTo='First Sample', Offset = Current Read Position (maybe +/- 1).
d. Loop over steps b and c until you've collected your test data. Then you can rever to occasional queries for recent data, not caring if the buffer overwrites in the meantime.

-Kevin P.
CAUTION! New LabVIEW adopters -- it's too late for me, but you *can* save yourself. The new subscription policy for LabVIEW puts NI's hand in your wallet for the rest of your working life. Are you sure you're *that* dedicated to LabVIEW? (Summary of my reasons in this post, part of a voluminous thread of mostly complaints starting here).
0 Kudos
Message 2 of 5
(3,548 Views)
Kevin, thanks for the reply. You have me thinking that the driver doesn't behave as I am expecting it to or certain calls don't work as expected. Specifically, I can use the program "as is" for my normal testing but what I am trying to do for occasional queries is to allow the buffer to overrun regularly but still get the most recent data to evaluate.

My method to insure that my external sample clock is still running is to first check the number of available samples using DAQmxGetReadAvailSampPerChan which works fine until I get the overrun. I have a 60 Hz clock so if I don't see 2 readings within 250 msec my software creates an error for a missing sample clock. As I see it now, the DAQmxGetReadAvailSampPerChan always returns 0 after the overrun and this did not change when setting the overwrite mode to DAQmx_Val_OverwriteUnreadSamps. A side effect was that my computer rebooted, but that was shortly after I realized that it didn't fix the problem anyway.

Getting down to the real nitty-gritty, I need to find out what to expect when the buffer overruns. As I said before when it did stop I tried to check DAQmxIsTaskDone and restart the task but it never returned true. How can I get readings after the overrun or recognize that it stopped due to this and restart it? Seems simple but so far it isn't.

Thanks, Ed
0 Kudos
Message 3 of 5
(3,545 Views)
OK, I have re-read the documentation about this problem. When the buffer overruns the acquisition stops, but should DAQmxIsTaskDone return true??? It indicates that it will return true on a fatal error, but I don't know if the overrun is a fatal error or not. Any suggestions on how I can easily determine when the buffer has overrun so I can re-start the task.

Ed
0 Kudos
Message 4 of 5
(3,541 Views)
Ed,

I'm going just a little bit out on a limb here, but if you are configured for continuous sampling rather than finite, the hw acquisition shouldn't stop on a buffer overwrite. That's why isTaskDone doesn't return True. However, any Read operations using the default settings meaning "Read starting at first sample that hasn't been read yet" will return an error and return no sample data.

However, I have an app running where the buffer definitely overwrites many many times and later I can still retrieve data from it. The key is preparing the Read property settings that mean "Read the most recent data, wherever you may be in the buffer." In LV, they are DAQmx Read Properties named RelativeTo and Offset.

Alternative: can you stop (not clear) the task then start it again? I'm not at my hw now and am not sure this works with buffered acquisitions. It might though. If so, you could just perform a stop - start sequency when you transition into the mode where you need to test and collect all data.

-Kevin P.
CAUTION! New LabVIEW adopters -- it's too late for me, but you *can* save yourself. The new subscription policy for LabVIEW puts NI's hand in your wallet for the rest of your working life. Are you sure you're *that* dedicated to LabVIEW? (Summary of my reasons in this post, part of a voluminous thread of mostly complaints starting here).
0 Kudos
Message 5 of 5
(3,533 Views)