From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

USB-6001 - Synchronized analog and digital reading

Hello,

I have for some time been struggling with a C# application for a USB-6001 device.

The purpose of my application is to:
-    Sample 8 analog inputs at 100 Hz.
-    Read the status 8 digital inputs in a way that analog samples and digital reading are synchronized.

I use following configuration of the device:
            NationalInstruments.DAQmx.Task analogInTaskPendulum = new NationalInstruments.DAQmx.Task();            
            anInputCh_PendulumCylinder = analogInTaskPendulum.AIChannels.CreateVoltageChannel("dev1/ai0", "pendulumAna", AITerminalConfiguration.Rse, -10.0, 10.0, AIVoltageUnits.Volts);
            anReader_PendulumCylinder = new AnalogSingleChannelReader(analogInTaskPendulum.Stream);

            NationalInstruments.DAQmx.Task analogInTaskHeightCylinder = new NationalInstruments.DAQmx.Task();
            anInputCh_HightCylinder = analogInTaskHeightCylinder.AIChannels.CreateVoltageChannel("dev1/ai1", "heightAna", AITerminalConfiguration.Rse, -10.0, 10.0, AIVoltageUnits.Volts);
            anReader_HightCylinder = new AnalogSingleChannelReader(analogInTaskHeightCylinder.Stream);

            NationalInstruments.DAQmx.Task analogInTaskLeftTilt = new NationalInstruments.DAQmx.Task();
            anInputCh_LeftTiltCylinder = analogInTaskLeftTilt.AIChannels.CreateVoltageChannel("dev1/ai2", "leftTiltAna", AITerminalConfiguration.Rse, -10.0, 10.0, AIVoltageUnits.Volts);
            anReader_LeftTiltCylinder = new AnalogSingleChannelReader(analogInTaskLeftTilt.Stream);

            NationalInstruments.DAQmx.Task analogInTaskRightTilt = new NationalInstruments.DAQmx.Task();
            anInputCh_RightTiltCylinder = analogInTaskRightTilt.AIChannels.CreateVoltageChannel("dev1/ai3", "rightTiltAna", AITerminalConfiguration.Rse, -10.0, 10.0, AIVoltageUnits.Volts);
            anReader_RightTiltCylinder = new AnalogSingleChannelReader(analogInTaskRightTilt.Stream);

            NationalInstruments.DAQmx.Task analogInTaskUltra1 = new NationalInstruments.DAQmx.Task();
            anInputCh_Ultra1 = analogInTaskUltra1.AIChannels.CreateVoltageChannel("dev1/ai4", "ultra1Ana", AITerminalConfiguration.Rse, -10.0, 10.0, AIVoltageUnits.Volts);
            anReader_Ultra1 = new AnalogSingleChannelReader(analogInTaskUltra1.Stream);

            NationalInstruments.DAQmx.Task analogInTaskUltra2 = new NationalInstruments.DAQmx.Task();
            anInputCh_Ultra2 = analogInTaskUltra2.AIChannels.CreateVoltageChannel("dev1/ai5", "ultra2Ana", AITerminalConfiguration.Rse, -10.0, 10.0, AIVoltageUnits.Volts);
            anReader_Ultra2 = new AnalogSingleChannelReader(analogInTaskUltra2.Stream);

            NationalInstruments.DAQmx.Task analogInTaskUltra3 = new NationalInstruments.DAQmx.Task();
            anInputCh_Ultra3 = analogInTaskUltra3.AIChannels.CreateVoltageChannel("dev1/ai6", "ultra3Ana", AITerminalConfiguration.Rse, -10.0, 10.0, AIVoltageUnits.Volts);
            anReader_Ultra3 = new AnalogSingleChannelReader(analogInTaskUltra3.Stream);

            NationalInstruments.DAQmx.Task analogInTaskUltra4 = new NationalInstruments.DAQmx.Task();
            anInputCh_Ultra4 = analogInTaskUltra4.AIChannels.CreateVoltageChannel("dev1/ai7", "ultra4Ana", AITerminalConfiguration.Rse, -10.0, 10.0, AIVoltageUnits.Volts);
            anReader_Ultra4 = new AnalogSingleChannelReader(analogInTaskUltra4.Stream);

A thread is setup to read each inputs every 10 msec:                                                       
            analogDataInPendulum = anReader_PendulumCylinder.ReadSingleSample();                
            analogDataInHeightCylinder = anReader_HightCylinder.ReadSingleSample();               
            analogDataInLeftTiltCylinder = anReader_LeftTiltCylinder.ReadSingleSample();                
            analogDataInRightTiltCylinder = anReader_RightTiltCylinder.ReadSingleSample();                
            analogDataInUltra1 = anReader_Ultra1.ReadSingleSample();                
            analogDataInUltra2 = anReader_Ultra2.ReadSingleSample();                
            analogDataInUltra3 = anReader_Ultra3.ReadSingleSample();                
            analogDataInUltra4 = anReader_Ultra4.ReadSingleSample();                                             

            digPortVal = DigInReader.ReadSingleSamplePortByte();

My problem is that each call to "ReadSingleSample" apparently takes more millisconds. Also I have tried to configure the sample behaviour by adding following calls to the configuration:

analogInTaskPendulum.Timing.ConfigureSampleClock("dev1/ai0", 100, SampleClockActiveEdge.Rising, SampleQuantityMode.ContinuousSamples);
analogInTaskHeightCylinder.Timing.ConfigureSampleClock("dev1/ai1", 100, SampleClockActiveEdge.Rising, SampleQuantityMode.ContinuousSamples);
analogInTaskLeftTilt.Timing.ConfigureSampleClock("dev1/ai2", 100, SampleClockActiveEdge.Rising, SampleQuantityMode.ContinuousSamples);
analogInTaskRightTilt.Timing.ConfigureSampleClock("dev1/ai3", 100, SampleClockActiveEdge.Rising, SampleQuantityMode.ContinuousSamples);
analogInTaskUltra1.Timing.ConfigureSampleClock("dev1/ai4", 100, SampleClockActiveEdge.Rising, SampleQuantityMode.ContinuousSamples);
analogInTaskUltra2.Timing.ConfigureSampleClock("dev1/ai5", 100, SampleClockActiveEdge.Rising, SampleQuantityMode.ContinuousSamples);
analogInTaskUltra3.Timing.ConfigureSampleClock("dev1/ai6", 100, SampleClockActiveEdge.Rising, SampleQuantityMode.ContinuousSamples);
analogInTaskUltra4.Timing.ConfigureSampleClock("dev1/ai7", 100, SampleClockActiveEdge.Rising, SampleQuantityMode.ContinuousSamples);

Which gives me an exception regarding the sample clock source:

NationalInstruments.DAQmx.DaqException: 'Requested sample clock source is invalid.
Property: NationalInstruments.DAQmx.Timing.SampleClockSource

I hope that somebody can point me to an example of how to do stuff like this correctly.





0 Kudos
Message 1 of 2
(2,173 Views)

The first and biggest obstacle is the USB bus.  You can expect latency on the order of msecs when you do single on-demand reads across the bus.

 

Consequently, it's pretty important to combine all the analog channels into a single task so you can get all 8 channels of data using a single read.  That'll cut the overhead by a factor of 8x.

 

It's not just important but *necessary* to combine all analog channels into a single task if you want to set up hardware timing in continuous sampling mode.  The AI subsystem will only support 1 active hardware timing source at a time.

 

The DI subsystem won't support hardware timing, you can only use on-demand port reads.

 

Finally, it'll help if you explicitly Start your tasks before doing a Read.  This will reduce your overhead too, not sure exactly how much but probably noticeable for the on-demand Reads.

 

 

-Kevin P

CAUTION! New LabVIEW adopters -- it's too late for me, but you *can* save yourself. The new subscription policy for LabVIEW puts NI's hand in your wallet for the rest of your working life. Are you sure you're *that* dedicated to LabVIEW? (Summary of my reasons in this post, part of a voluminous thread of mostly complaints starting here).
0 Kudos
Message 2 of 2
(2,158 Views)