Digital I/O

Showing results for 
Search instead for 
Did you mean: 

WriteWaveform method is too slow

I'm using the PCIe-6536 to generate digital waveforms on all 32 supported channels at 25 MHz. My code is written in VB.NET and I'm using the DAQmx driver. A snippet of my code follows.


            Dim obj As [Object]
            Dim bufferLocation As Integer = 0
            Dim SCLKsignal_line As DigitalStateCollection = dataWaveform(NIconfig.ADSPI.CLK.Port).Signals.Item(NIconfig.ADSPI.CLK.Channel).States
            Dim REFINsignal_line As DigitalStateCollection = dataWaveform(NIconfig.REFIN.Port).Signals.Item(NIconfig.REFIN.Channel).States
            Dim RESETBsignal_line As DigitalStateCollection = dataWaveform(NIconfig.RESETB.Port).Signals.Item(NIconfig.RESETB.Channel).States
            Dim SYNCBsignal_line As DigitalStateCollection = dataWaveform(NIconfig.SYNCB.Port).Signals.Item(NIconfig.SYNCB.Channel).States

For Each obj In ADRegEdits WriteToRegister(NIconfig, obj, dataWaveform, bufferLocation) bufferLocation = bufferLocation + 52 Next obj For Each obj In ExpSequence WriteToSPI(NIconfig, obj, dataWaveform, bufferLocation) bufferLocation = bufferLocation + 28 Next obj InsertClock(SCLKsignal_line) InsertClock(REFINsignal_line) RaiseLine(RESETBsignal_line) RaiseLine(SYNCBsignal_line) stpWatchInfo.Start() writer.WriteWaveform(False, dataWaveform) stpWatchInfo.Stop() MessageBox.Show("Elapsed Time in milliseconds is: " & stpWatchInfo.ElapsedMilliseconds) digitalWriteTask.Start() digitalWriteTask.WaitUntilDone() digitalWriteTask.Stop()

The first section just corresponds to routines I use to fill the DigitalWaveform object. The next section in between the 'stpWatchInfo.Start()' and 'stpWatchInfo.Stop()' corresponds to transferring this data to the buffer. This is timed and outputted in a message box. For 3,561,400 x 32-bit digital words (32 corresponds to the 32 channels), this process takes around 408 ms, which corresponds to about 33 MBps. I've tried shorter DigitalWaveforms and have calculated very similar transfer speeds, suggesting it's not some issue with a fixed overheard. It doesn't seem to be limited by the PCIe bus (even one lane with the oldest standard should have a theoretical bandwidth of 250 MBps) nor the RAM (PC3-10600 is capable of 10600 MBps).


As a followup question that I'll need to address once I solve this first problem, I would imagine that I can eventually push the buffer transfer speed to much greater than 100 MBps, which is higher than the output rate of the card (32 bits * 25 MHz = 100 MBps). In this case, it seems theoretically feasible to be able to stream data to a buffer and output it without buffer underruns. I was once pointed towards "Pipelined Sample Clock." I took a look at the example, but would still appreciate if someone could give me some high-level overview of what's going on. It seems like data is generated and output in what I will call blocks. After the first block is streamed, the 'BeginWriteWaveform' method is called with 'autoStart' set to true so that it begins outputting that first block immediately. When this method finish, it calls a callback that starts writing data again, but this time with the 'autoStart' in 'BeginWriteWaveform' set to False? Anyway, it's pretty clear I dont' know what's going on...





DAQmx 9.5.1

0 Kudos
Message 1 of 4

It looks like you created your own 'writer' object with a 'WriteWaveform' method that seems to be slow. Is that correct? Can you show the code you used to create this object?


I'm having trouble following your math...Where does the number 3,561,400 come from?


Nathan S.
Applications Engineer
National Instruments
0 Kudos
Message 2 of 4

The code used to create the object is as follows:


            digitalWriteTask = New Task()
            digitalWriteTask.DOChannels.CreateChannel("dev4/port0/line0:7", _
                                                      String.Empty, _
            digitalWriteTask.DOChannels.CreateChannel("dev4/port1/line0:7", _
                                                      String.Empty, _
            digitalWriteTask.DOChannels.CreateChannel("dev4/port2/line0:7", _
                                                      String.Empty, _
            digitalWriteTask.DOChannels.CreateChannel("dev4/port3/line0:7", _
                                                      String.Empty, _
            digitalWriteTask.Timing.ConfigureSampleClock(System.String.Empty, 25000000, _
                                             SampleClockActiveEdge.Rising, _
                                             SampleQuantityMode.FiniteSamples, _
                                             nRegEdits * nClocksPerRegEdit + nClocksPerSPIWrite * nExpSteps + 1)

            ' Create the writer and attach it to the stream 
            digitalWriteTask.Stream.ConfigureOutputBuffer((nRegEdits + nExpSteps) * nClocksPerRegEdit + 1)
            Dim writer As DigitalMultiChannelWriter = New DigitalMultiChannelWriter(digitalWriteTask.Stream)

 Sorry, there is no math with regard to the 3,561,400 digital words. That is just the test array I made. It corresponds to roughly 114 ms of real data (well, give or take a ms since I'm not counting some very short initialization sequence), but takes 408 ms of time to transfer to the buffer.


If it helps, I'm using this to generate digital ramp forms that are destined for a DAC.

0 Kudos
Message 3 of 4

Thanks for posting on the forums! I noticed you created a service request with our support department. We will continue troubleshooting this issue through that request. Thank you.

Nathan S.
Applications Engineer
National Instruments
0 Kudos
Message 4 of 4