ni.com is currently undergoing scheduled maintenance.

Some services may be unavailable at this time. Please contact us for help or try again later.

Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

How to feed callback_data parameter to the callback passed as parameter of register_every_n_samples_acquired_into_buffer_event (in nidaqmx-python)

Solved!
Go to solution

Hello,

 

I wish to pass some data to my callback through callback_data, which seems to be custom info that you can pass (I used to do similar things in C 20 years ago). But I did not get how you give it to the API

In the doc: "@def callback(task_handle, every_n_samples_event_type, number_of_samples, callback_data): ... The callback_data parameter contains the value you passed in the callback_data parameter of this function"

 

Well, not a native english speaker but I am quite puzzled by the sentence. I see no "callback_data" parameter in any nidaqmx API.

Within the generated bindings to C, there are some "register_every_n_samples_event" where you could pass a callback and callback_data but this is internal. Is it just that the API is available in C and not in python ? 

 

OK, I have a fallback solution where I put every info as global but well, if I could get a bit cleaner...

0 Kudos
Message 1 of 5
(1,150 Views)

I had a look at C API

nt32 DAQmxRegisterEveryNSamplesEvent (TaskHandle taskHandle, int32 everyNsamplesEventType, uInt32 nSamples, uInt32 options, DAQmxEveryNSamplesEventCallbackPtr callbackFunction, void *callbackData);

 

In python: register_every_n_samples_acquired_into_buffer_event(sample_intervalcallback_method)

 

As parameter, there is the callback... and the Callback_data stuff that you want to be given as parameter of your callback.

I don't see how this is translated in python

0 Kudos
Message 2 of 5
(1,115 Views)

Looking at internal code of ndaqmx-python:

def register_every_n_samples_acquired_into_buffer_event(self, sample_interval, callback_method):

    if callback_method is not None:

        event_handler = self._interpreter.register_every_n_samples_event(self._handle, EveryNSamplesEventType.ACQUIRED_INTO_BUFFER.value, sample_interval, 0, callback_method, None)

 

Cough, cough, .... callback_data gets discarded. I fear I have my answer

0 Kudos
Message 3 of 5
(1,108 Views)
Solution
Accepted by ft_06

I also need to pass some info to the callback, in Python. Eventually, I've used "partial" to do that. Something like:

on_data_consumed = functools.partial(self._on_data_consumed, continuous=continuous)
ao_task.register_every_n_samples_transferred_from_buffer_event(ao_chunk_size, on_data_consumed)
0 Kudos
Message 4 of 5
(1,102 Views)

Right, I had seen something similar in NI code in their acceptance test for multi-threading. pyqtchart uses lambda functions to also "customize" their callbacks, I guess this would also work.

This is kind of "backup" solution but if NI is also doing this, let's consider this is the solution

 

code from NI:

for i in range(len(tasks)):

  def _every_n_samples_callback(
    i: int,
    task_handle: object,
...

) -> int:...

tasks[i].register_every_n_samples_acquired_into_buffer_event(

100, functools.partial(_every_n_samples_callback, i)
)

0 Kudos
Message 5 of 5
(1,091 Views)