Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

problems unbuffered update AO waveform

Hallo,

 

We have serious problems after upgrading our app to DAQmx.

The problem is that we face dead-locks of DAQmxWriteBinaryI16

and DAXmxStopTask in combination with certain states of the progress

of the external pattern clock.

 

We use externally clocked AO using a PCI-6711 / PCI-6713 board.

We selected this board because it uses the main PC memory which can

be accessed by the CPU during AO operation. As a result the waveform

can be updated by the CPU on the fly with minimal lag.

 

With the DAQ32 library, the WFM_Load(,,,buffer[2048*2048*4],,) was

called to pass the address of the buffer. During AO operation, the contents

of the buffer was modified and the new waveform was visible on the output

with minimal lag (~ the size of the hardware DMA buffer).

 

With DAQmx this update on-the-fly type of operation seems to be impossible.

DAQmxWriteBinaryI16 is now used, but this method synchronizes with the

actual AO progress. In the forum there are several topics found that explain

why this buffering and synchronizing strategy slows down the time in which

the DAQmxWriteBinaryI16 returns. However, I have not found a suggestion

how we can implement the fast DAQ32 non-synchronized behaviour.

 

Note that:

- stopping and restarting the task is not possible because it would break the

  synchronization with the external pixelclock

- we understand that updating the buffer during AO introduces glitches in the

  output, but that is acceptable for our hardware

- the total duration of one wave ranges from 100 ms to 60 seconds. 

  with DAQ32, any changes in the buffer were visible within a fraction of second, which is
  an acceptable respons time. With DAQmx, DAQmxWriteBinaryI16 can take

  up to 30 seconds to return, which is killing for the user experience.

 

Because the DAQmxWriteBinaryI16 method could take a long time to return

we have moved this call to a separate working thread that writes the buffer in

the background:

 

 while(WaitForAction(INFINITE) == EDoWork)
 {
      m_BufferChanged.Reset();
      DAQmxWriteBinaryI16(,,,);
 }

The problem our QA team now discovered that that a sometimes a dead-lock occurs in

the following situation:

- the external pixel-clock is stopped

- the DAQmxWriteBinaryI16 is executing (blocked), clearly waiting for the AO to come to

  an certain state

- the DAQmxStopTask is called but never returns.

 

This problem does not happen frequently, I can imaging that it happens only when the clock is

stopped at a certain phase in the total cycle. 

 

The dead-lock seems to me a side-effect of the synchronization with AO.

Note that we don't want to have the synchronization in the first place.

 

Could you please tell us if there is a (hidden) method that can be called after DAQmxStartTask

to get a user-space pointer to the shared memory that is used to store the buffer ?

Using this pointer we can update the waveform on the fly without synchronization with the AO progress.

 

Alternatively, please teach us how to prevent the dead-lock situation that we encounter.

 

WR,

 

Kees van der Oord

0 Kudos
Message 1 of 3
(2,871 Views)

Dear Kees van der Oord,

 

In DAQmx this is not possible. The best you can do is disable the regeneration, and break your waveform in smaller chunks.

 

Regards,

Bas van Dijke
NI Netherlands

0 Kudos
Message 2 of 3
(2,772 Views)

Bas,

 

Thanks for the suggestion.

 

I had the same idea.

The update is now broken into smaller pieces and performed by a thread in the background.

The response time is better now, but far not as good as it was.

 

The solution requires a lot of administration and thread-synchronisation.

It looks strange to add so much error-prone code to work-around the limitations of the API. 

 

I like the simplicity of the NI software interface, but this seems to be the opposite of simple.

 

WR,

 

Kees

0 Kudos
Message 3 of 3
(2,768 Views)