Jump to content

DAQ AI->AO multiplexing


patufet_99

Recommended Posts

Hello,

For an application I would like to do an analog continuous multiplexing.

I acquire data on two PCI-6225 boards synchronized through an RTSI cable. I then output, 4 selectable channels to the analog outputs of the boards.

I have written a vi in LabVIEW 7.1 that works for a while but it is not very reliable. Most of the time after some minutes or some hours it makes XP crash!

When monitoring the PC resources while the vi is running, the CPU usage is at 2-3 % and the memory remains stable at about 500Mb (there are 4Gb on that PC).

I do not understand what is it wrong with that vi!

Any hints are welcome!

PS: I attach here the Vi that does the acquisition and the analog output of the data.

Multi_Device_AI_AO_Daq_and_multiplex.zip

Link to comment

Any hints are welcome!

I'm not seeing anything obvious in the VI that you attached. You should stop the task before clearing it, though that's not causing your problem.

I'd recommend eliminating as much as you can and then adding it back in one piece at a time if you are certain it's your program.

You don't say what the message is when you get a system crash. Memory usage shouldn't cause XP to crash as XP will hard-kill any task that is taking 2 GB or more.

Does your program have the same behavior on a different PC? Could you be running into, say, a bad memory sector?

Tim

Link to comment

I'm not seeing anything obvious in the VI that you attached. You should stop the task before clearing it, though that's not causing your problem.

I'd recommend eliminating as much as you can and then adding it back in one piece at a time if you are certain it's your program.

You don't say what the message is when you get a system crash. Memory usage shouldn't cause XP to crash as XP will hard-kill any task that is taking 2 GB or more.

Does your program have the same behavior on a different PC? Could you be running into, say, a bad memory sector?

Tim

It has been a while but ... Try cranking up the size of your output buffer to make sure there is enough data in it to fill any delays due to the OS going off into la-la-land.

Ben

Link to comment

The system crashes with a generic BSOD:

*** Hardware MalfunctionCall your hardware vendor for supportNMI: Parity Check/Memory Parity Error*** The system has halted ***

I haven't tried it in another PC yet. I wanted to understand before what was causing the problem: when disabling the Analog Output, it runs smoothly.

I don't think is a bad memory sector or something like that because the PC is new!

I continue investigating...

Link to comment

The system crashes with a generic BSOD:

*** Hardware MalfunctionCall your hardware vendor for support[b]NMI: Parity Check/Memory Parity Error[/b]*** The system has halted ***

I haven't tried it in another PC yet. I wanted to understand before what was causing the problem: when disabling the Analog Output, it runs smoothly.

I don't think is a bad memory sector or something like that because the PC is new!

I continue investigating...

Parity errors are gnerally a hardware issue. After seeing that error message I am leaning toward a hardware issue.

You did not reply to my thought. If you are using hardware exteranlly clocked outputs, you have to make sure the data is ther when the clock clicks.

Still betting hardware.

Ben

Link to comment

I haven't tried it in another PC yet. I wanted to understand before what was causing the problem: when disabling the Analog Output, it runs smoothly.

I don't think is a bad memory sector or something like that because the PC is new!

I continue investigating...

Don't discount the memory being bad because the system is new. I've received pleanty of new systems and components that couldn't have been tested before leaving the factory or were damaged in shipping.

Tim

Link to comment

Don't discount the memory being bad because the system is new. I've received pleanty of new systems and components that couldn't have been tested before leaving the factory or were damaged in shipping.

Tim

Thank's for your comment Tim, I have tested the software on two identical PC's with the same result. It would be really a bad luck that both PC's have a memory default!

I have done a system check of hardware components too, and didn't found any faulty component

Regards

Link to comment

Parity errors are gnerally a hardware issue. After seeing that error message I am leaning toward a hardware issue.

You did not reply to my thought. If you are using hardware exteranlly clocked outputs, you have to make sure the data is ther when the clock clicks.

Still betting hardware.

Ben

Thank you for your comment Ben, I use the internal PCI-6225 clock of the first board. The second board clock is synchronized with the first one via the RTSI cable. I have copied a LabVIEW example to do that.

In the read-write daq loop:

- I skip the first writing iteration as there is no data to write: (data is only acquired at the end of the loop: the loop waits for the data to be acquired)

- At the second iteration I write the daq data to the buffer and then after waiting half of the loop time I start the daq ao operation.

- At the third and next iterations I just write the daq data to the buffer.

The buffer is set to twice the acquisition data.

As the writing start is delayed of 1.5 iterations, if I am not wrong, the buffer should always be between about 1/4 and 3/4 full, but never full or empty.

I am missing something here? How does LabVIEW manage the analog output buffer? Does it wait that it is empty before writing to it?

I can just add that the analog output LabVIEW examples work normally with this hardware.

Regards.

Edited by patufet_99
Link to comment

.....

I am missing something here? How does LabVIEW manage the analog output buffer? Does it wait that it is empty before writing to it?

.....

Regards.

I can help answer part of your question - for the analog output buffer, there's a property you can set thru the DAQmx Channel - here's the blurb from the LabVIEW help file. I think the default is Less than Full.

Mark

Analog Output:General Properties:Advanced:Data Transfer and Memory:Data Transfer Request Condition Property<h1>Analog Output:General Properties:Advanced:Data Transfer and Memory:Data Transfer Request Condition Property

Short Name: AO.DataXferReqCond

Property of DAQmx Channel

Specifies under what condition to transfer data from the buffer to the onboard memory of the device.

Onboard Memory Empty (10235) Transfer data to the device only when there is no data in the onboard memory of the device. Onboard Memory Half Full or Less (10239) Transfer data to the device any time the onboard memory is less than half full. Onboard Memory Less than Full (10242) Transfer data to the device any time the onboard memory of the device is not full.</h1>

Link to comment

Property of DAQmx ChannelSpecifies under what condition to transfer data from the buffer to  the onboard memory of the device.

Thank you for your comment Mark,

there was something a bit confusing for me in this description. I thought that the buffer was directly on the onboard memory of the device!

I see now that the buffer is in the PC memory.

I still does not understand very well how does it work. When you are on non regeneration mode, does the buffer work as a FIFO?

For instance I haven't found any place where this is well described!

Regards.

Link to comment

Property of DAQmx ChannelSpecifies under what condition to transfer data from the buffer to  the onboard memory of the device.

Thank you for your comment Mark,

there was something a bit confusing for me in this description. I thought that the buffer was directly on the onboard memory of the device!

I see now that the buffer is in the PC memory.

I still does not understand very well how does it work. When you are on non regeneration mode, does the buffer work as a FIFO?

For instance I haven't found any place where this is well described!

Regards.

Here's the way I understand the buffers - and I don't guarantee this is correct!

The DAQmx driver for AO allocates memory on the host computer's memory - this is the "buffer". If you are in non-regeneration mode, this buffer does act as a FIFO. A typical sequence is 1) LabVIEW program creates a waveform/analog signal and writes that data to the host computer's buffer when the DAQmx Write VI is called. 2) In non-regeneration mode, this data is consumed - the calling program is responsible for making sure there's data in the host computer's buffer as long as the DAQmx write command is requesting it. If the data buffer ever gets empty before the write is complete, DAQmx errors. 3) In regenerative mode, the task will not consume the data in the buffer and instead just re-read from the buffer for the duration of the requested waveform.

The default data transfer mechanism from the host buffer to the on-board memory is DMA. This can be changed to interrupt driven, but there's hardly ever any reason to do so. The DAQmx drive takes care of all the transfer from the host memory to the onboard memory.

Mark

Mark

Link to comment

Here's the way I understand the buffers - and I don't guarantee this is correct!

The DAQmx driver for AO allocates memory on the host computer's memory - this is the "buffer". If you are in non-regeneration mode, this buffer does act as a FIFO. A typical sequence is 1) LabVIEW program creates a waveform/analog signal and writes that data to the host computer's buffer when the DAQmx Write VI is called. 2) In non-regeneration mode, this data is consumed - the calling program is responsible for making sure there's data in the host computer's buffer as long as the DAQmx write command is requesting it. If the data buffer ever gets empty before the write is complete, DAQmx errors. 3) In regenerative mode, the task will not consume the data in the buffer and instead just re-read from the buffer for the duration of the requested waveform.

The default data transfer mechanism from the host buffer to the on-board memory is DMA. This can be changed to interrupt driven, but there's hardly ever any reason to do so. The DAQmx drive takes care of all the transfer from the host memory to the onboard memory.

Mark

Mark

Hello,

thank you for your explanation.

As I initially thought that the "buffer" was "on-board" I had set it's size to twice the data read/written in a loop cycle. My fear was that in the next loop cycle the buffer would be overwritten if it's size was too small.

I think that is the origin of the problem.

By setting the buffer to the size of the read data on a loop cycle, and delaying the write start to about half of the loop cycle time seems to solve the problem.

With a 1 kHz read/write read, a cycle of 1 second and a buffer of 1000 points:

- i=0. Read 1000 pts (the loop waits until all the data is available)

- i=1. Write the previous read 1000 pts, wait about 0.5 seconds. Start AO write. Read 1000 pts (will wait about 0.5 more sec. until the data is available).

- i=2 and next. Write 1000 pts. This operation will wait about 0.5 seconds until the AO buffer is empty. Read 1000 pts. (wait until the data is available).

With this scheme, the "write" should always have data available.

I still does not understand why with the increased buffer size the system crashed after a while instead of returning an error!

Anyway I'm happy that for instance all seems to work as expected!

Regards.

Link to comment

Hello,

thank you for your explanation.

As I initially thought that the "buffer" was "on-board" I had set it's size to twice the data read/written in a loop cycle. My fear was that in the next loop cycle the buffer would be overwritten if it's size was too small.

I think that is the origin of the problem.

By setting the buffer to the size of the read data on a loop cycle, and delaying the write start to about half of the loop cycle time seems to solve the problem.

With a 1 kHz read/write read, a cycle of 1 second and a buffer of 1000 points:

- i=0. Read 1000 pts (the loop waits until all the data is available)

- i=1. Write the previous read 1000 pts, wait about 0.5 seconds. Start AO write. Read 1000 pts (will wait about 0.5 more sec. until the data is available).

- i=2 and next. Write 1000 pts. This operation will wait about 0.5 seconds until the AO buffer is empty. Read 1000 pts. (wait until the data is available).

With this scheme, the "write" should always have data available.

I still does not understand why with the increased buffer size the system crashed after a while instead of returning an error!

Anyway I'm happy that for instance all seems to work as expected!

Regards.

I think Mark answered that question in his final line. answer the question "where does the hardware find the next sample to output when it gets to the end of the buffer?" If the next location in memory is not mapped to the hardware...

crash.

Ben

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.