I am trying to write an application which reads from a 9184 chassis which is able to detect and recover from network errors (e.g. Ethernet disconnected or power outage) and its not clear what function I need to call. At present I call:
(add channels to task here)
I then call DAQmxReadAnalogF64 repeatedly and if it fails I repeat the above function calls. Is this the right thing to do as it doesn't seem very reliable i.e. it doesn't always recover?
Solved! Go to Solution.
I found an example program that shows how to reset a device connection after the device has been unplugged. They used a NI cDAQ-9172 and LabVIEW 2012, but the logic should be similar to what you are trying to do. Have a look for inspiration:
If a network error occurs, I suggest you implement some error handling that saves your current data. Then try to reset the connection, and continue the acquisition.
Are you programming in LabVIEW or are you working in a scripting language?
Hi, and thanks for the reply. Sorry I haven't responded earlier but I didn't get a notification of your posting.
I am using C++ to access the device using the NI DAQmx library.
Using compact DAQ devices over Ethernet in an industrial environment has proved so troublesome and unreliable that we are no longer planning to include them in future plant designs. However, it would be good to get the ones we already have working reliably and any advice you can offer would be much appreciated.
I think you are on the right track. As you are using NI DAQmx API you should be able to apply the same logic in C++ as in LabVIEW.
According to the Example I found in the previous post, when the connection is lost you should catch the error and reset the device using DAQmxResetDevice. This .vi aborts all current tasks and returns the device to its initialized state. See DAQmx Reset Device (VI) for more info.
Then once the device has been reset you should be able to perform the initialization steps you mentioned in the original post.
If it still does not work, do you get any error messages? and if so what do they say? This will help us with the troubleshooting.
Thanks. I originally included code to reset the device using DAQmxResetDevice() but discovered that the device was unavailable for an indeterminate period afterwards (several seconds). If I tried to add channels to a task during this time, and the channels were on this device, then DAQmxCreateAIVoltageChan() would fail. I didn't want to have to call sleep() for some overly long period before I could add channels - so I removed the call to DAQmxResetDevice() from my code. However, if as you say I should reset the device before using it, I wonder if there is a way of knowing when its ready for use again?
From my understanding, the a reset of a device is non-deterministic, i.e. the reset time can vary from time to time. Hence, calling sleep() for some fixed duration is probably not the best option here.
Instead, I suggest that you implement some polling that performs a self-test every 100 ms or so until it succeeds. After a successful self-test, the cDAQ is connected again and you can continue with the acquisition. See this forum post for a longer discussion about resetting the device using polling: Delay After Reset Device?
Also, by reading from the description of DAQmxResetDevice(), it seems as the task that was running before the connection lost is still accessible after a device reset. If so, you should be able to start the old task again after reset without needing to create a new task. I have not tried it myself but I think it is worth a try. Just use DAQmxStartTask() and refer to your old task.
Excellent, thanks! I must admit that I wasn't sure whether calling DAQmxResetDevice() would affect the task so I re-created it as a precaution but if that isn't needed then it should improve recovery performance significantly.
Thanks again for your suggestions.