1

I am using the National Instruments myDAQ with MATLAB (using the Data Acquisition Toolbox) to generate a sine wave at defined frequencies at one of the output channels. The output channel is (effectively) connected to a resistor which then goes to AGND. I am measuring the voltage across the resistor with one of the input channels (AI0).

Issue- When measuring from the input channel the DAQ stops recording after a certain time and just returns noise. See examples in images. Here is the relevant code-

dq = daq("ni")
dq2 = daq("ni") % same DAQ, but used for the digital channels

% Adding analog channels to dq
chi0 = addinput(dq, 'myDAQ1', 'ai0', 'Voltage');
chi0.Range = [-10, 10];
chi1 = addinput(dq, 'myDAQ1', 'ai1', 'Voltage');
chi1.Range = [-2, 2];
cho0 = addoutput(dq, 'myDAQ1', 'ao0', 'Voltage');
cho0.Range = [-10, 10];

% Adding digital channels to dq2
% Gives a warning that channels are not synchronized, but I don't need that sync
digi = addoutput(dq2, 'myDAQ1', 'port0/line0:3', 'Digital');

% Turn off all four digital outputs
write(dq2, [0, 0, 0, 0]);

% Program variables
f = 100;        % Signal frequency
fs = 200e3;     % Sampling frequency
Vmax = 0.05;
Vbase = 0.0;
numberOfPeriods = 20;
requiredTime = numberOfPeriods / f;
numberOfPoints = fs * requiredTime;

% t is a vector of size (numberOfPoints x 1)
t = linspace(0, requiredTime, numberOfPoints)';
program = Vmax * sin(2 * pi * f * t) + Vbase;

% Turn on one of the digital outputs
write(dq2, [0, 0, 1, 0]);

% This line works the DAQ, runs for requiredTime amount of time
% Returns a (numberOfPoints x 2) matrix with acquired data
[data, timestamps] = readwrite(dq, program, "OutputFormat", "Matrix");

% Processing received data
channel0 = data(:, 1);
channel1 = data(:, 2);
plot(t, program, timestamps, channel0); legend('Program', 'Acquired');

% Cleanup - turn off all digital outputs
write(dq2, [0, 0, 0, 0]);

This is what I see when the code executes (f = 100Hz)- Plot (code result) for f = 100

For higher frequency, it gets worse (f = 250 Hz)- Plot (code result) for f = 250

And this is for even higher frequencies (f = 1000 Hz)- Plot (code result) for f = 1000

I am really unsure what is causing this. My guess is that it has something to do with the non-synchronization of the two "devices" dq and dq2, but cannot say exactly.

Any insight would be appreciated.

shreyas
  • 103
  • 8

2 Answers2

2

Your interpretation is wrong. Obviously, you continue recording values. This is evident because you see noise as opposed to a constant value or an error.

What really stopped, is the sine generation.

As the generation always stops right at zero, it is quite likely the 20 cycles simply have finished outputting at that point in time.

Why don't you see them ?

What might go wrong, is that the 20 cycles finish partially before you start reading. This is quite likely given the terrible latency of the Windows cDAQ drivers.

tobalt
  • 18,646
  • 16
  • 73
  • Ah, I was not aware of the latency. I'm unsure how the drivers would affect the read/write latency. The MATLAB DAQ Toolbox doesn't allow separate read or write operations if you have both in and out channels configured on a device. If there was a fixed delay between read and write operations I might be able to take them out. – shreyas Nov 09 '21 at 18:56
  • @shreyas At least in labview, the driver delay is pretty indeterministic for generic read and write ops. It can be a few ms but also sometimes more than 10 ms. ni offer their Rio brand devices for users that need better time control, so optimizing the daq series in this respect was never a priority I guess. – tobalt Nov 09 '21 at 19:08
0

As @tobalt suggested, it is an interim delay somewhere which causes the read operation in readwrite to start at a (random) later time than the write operation, which causes the write operation to appear to end prematurely.

Here is how I am using it now. The trick is to create two "devices" dqi and dqo separately for the read and write operations. You will get data that is not synchronized between the output channel and input channels, but that is a different bridge to cross.

dqi = daq("ni");
dqo = daq("ni");

% Adding channels
chi0 = addinput(dqi, 'myDAQ1', 'ai0', 'Voltage');
chi0.Range = [-10, 10];
chi1 = addinput(dqi, 'myDAQ1', 'ai1', 'Voltage');
chi1.Range = [-2, 2];
cho0 = addoutput(dqo, 'myDAQ1', 'ao0', 'Voltage');
cho0.Range = [-10, 10];

% Other stuff

% Reading/writing program
start(dqo, "repeatoutput");
write(dqo, program);
[data, ~] = read(dqi, size(program, 1));
stop(dqo);

data is returned as a timetable

shreyas
  • 103
  • 8
  • You also have an unknown delay between starting the write operation and starting the read. Most likely the "fix" you are seeing is from `"repeatoutput"` and not separating the input and output tasks. – Ben Voigt Nov 10 '21 at 16:00
  • @BenVoigt you are correct, except in this case that unknown delay is very small, or at least small compared to what I was getting with `readwrite`. For my application I don't mind it since I am taking it out later in the code (manifests as phase difference), but it might be significant for somebody else. That `repeatoutput` is not doing much I think since what I see after `plot`ting is exactly what I have in my `program` (no repetition) – shreyas Nov 10 '21 at 16:43