|
From: Marc G. <mar...@it...> - 2019-08-25 16:47:51
|
Hi Dan, you asked exactly the same questions that I am asking myself since a while. I guess all following options have one thing in common: If a continuous input is started, it is the responsibility of the user to regularily request a chunk of already recorded data from the plugin (and optionally store this chunk to a file, visualize it...). Therefore getVal should be regularily called and the returned dataObject always has a changing number of columns, depending on the number of samples that have been collected since the last call of getVal. If I understand the NI documentation properly, the task will stop and indicate an error, if the internal buffer (given by the number of samples in the task configuration) is full and nobody cleared it by calling DAQmxReadAnalogF64 (or something similar). Currently, we don't have a similar device with continuous acquisition. There is only one other supported AD/DA device from measurement computing, but the continuous acquisition is not implemented there, too. Therefore, there is no established infrastructure available in itom for this (not yet). I see the following options: 1. The quick and dirty solution (I don't like it to much): - startDevice / stopDevice are NOOP - acquire will start the continuous task or finite task - a continuous call to getVal will always obtain the currently available chunk of data in the internal buffer. The task will automatically stop if you don't call getVal again or if you restart the task with another paramerization. For finite tasks, getVal blocks until all samples are recorded (or timeout) 2. The solution, which fits best to other IO-devices like cameras - starting a task will be moved to startDevice (for cameras, startDevice will always bring a camera into a state, where images can then be taken, each single acquisition is then triggered by 'acquire', once a device is started, not all parameters can be changed - this highly depends on the camera) - stopping the task will be moved to stopDevice - If the task is continuous, it will be really started by calling startDevice (acquire is Noop then), if the task is finite, acquire has to be called to fire the start trigger - for a finite task, getVal blocks until all samples are recorded (or timeout), for a continuous task one has to regularily call getVal such that the internal NI buffer never gets full (and the task is interrupted then) 3. AD/DA specific solution - startDevice / stopDevice are NOOP - acquire will start a continuous or finite task - there will be a new method in the base class ito::AddInDataIO (e.g. stopAcquisition or simply stop) which will be wrapped by a method with the same name in the python class itom.dataIO which is only implemented in the case of AD/DA converters which can be called to stop a continuous task - the behaviour of getVal is again the same than in option 1 or 2 Me personally, I would prefer option 2, since startDevice and stopDevice are currently unused for the NIDAQmx plugin, but for cameras, which only provide a continuous data stream and cannot be triggered, like webcams, startDevice will start the data stream and acquire will only "extract" the latest image in the stream and provide it to the following getVal command. Introducing a new command will be available to the dataIO interface in python, hence every camera would have this command which is a NOOP then. All in all, my ranking would be option 2, then option 3 and option 1 would only be a workaround. The NIDAQmx interface also has the option to register a callback function if a certain number of samples have been recorded. In one of my latest emails to you, I talked about the official python package nidaqmx-python and the example, where one registers a python method as callback. Inside of this callback, the current available chunk of data is obtained (to a numpy-array) and stored to the hard drive. In theory it would also be possible to register a c-function in the c++ plugin to this callback function and if it is fired emit a Qt signal, defined in the plugin. Since a couple of months it is now possible to connect python methods in itom to such a function. However you still have to call getVal to really read the data and store it. Therefore I would say that it is often possible to estimate the right time interval when data has been obtained to avoid a full NI-internal buffer. Then it is also possible to repeatedly call getVal within a loop and a sleep command or to use the python class itom.timer (or similar ones) to register a callback function in python which should be called e.g. every 250ms. Best regards Marc Am Sa., 24. Aug. 2019 um 17:20 Uhr schrieb dan nessett <dne...@ya...>: > Hi Marc, > > I am starting to think about how to implement continuous analog input. I > think one point you have raised is how to signal the beginning of the input > and the end of it. It would be possible to use acquire() to start the input > and stopDevice() to end it, but that has the feeling of a hack (overloading > existing functions to do something else). Another possibility would be to > add startChannel() and stopChannel() methods to the plugin. Is there a way > to add plugin specific method calls so they have python wrappers? Are there > any other plugins doing this (if so, would you point me to them so I can > take a look at the code)? > > Cheers, > > Dan > |