Получите данные из двух устройств на различных уровнях

В этом примере показано, как использовать интерфейс сеанса, чтобы получить данные из двух различных устройств DAQ на различных уровнях. Пример использует два Национальных Инструмента модули аналогового входа CompactDAQ (9201 и 9211), которые имеют различные ограничения скорости приобретения. 9 211 модулей используются в измерениях температуры и получают на более медленном уровне (10 Гц), чем 9 201 модуль, который используется, чтобы измерить напряжение (100 Гц). Поскольку все каналы на сеансе должны получить на том же уровне, чтобы получить от двух модулей на различных уровнях, необходимо использовать два сеанса. Чтобы заставить оба сеанса запуститься одновременно, можно использовать оборудование цифровая настройка инициирования.

Настройка оборудования

  • Шасси NI cDAQ 9178 CompactDAQ ('cDAQ1')

  • Модуль NI cDAQ 9211 аналогового входа шасси CompactDAQ с типом измерения термопары ('cDAQ1Mod1')

  • Модуль NI cDAQ 9201 аналогового входа шасси CompactDAQ с типом измерения напряжения ('cDAQ1Mod2')

  • Зонд термопары (тип K)

  • Аналоговый сигнал напряжения сгенерирован инструментом функционального преобразователя

Сконфигурируйте сеансы сбора данных и каналы

Создайте два сеанса, каждого с каналом аналогового входа от 9 211 модулей или 9 201 модуля. Сеансы получают данные на уровнях 10 Гц и 100 Гц, соответственно.

Сконфигурируйте сеансы, чтобы запуститься в фоновом режиме и использовать функцию обратного вызова в событии DataAvailable, чтобы хранить полученные данные и метки времени в свойстве UserData сеанса.

% Specify a common acquisition duration for both devices
daqDuration = 3;

% Create and configure session and channels for cDAQ 9211 module
s1 = daq.createSession('ni');
addAnalogInputChannel(s1, 'cDAQ1Mod1', 'ai0', 'Thermocouple');
s1.Channels(1).ThermocoupleType = 'K';

s1.DurationInSeconds = daqDuration;
daListener1 = addlistener(s1, 'DataAvailable', @DataAvailable_callback);
errListener1 = addlistener(s1, 'ErrorOccurred', ...
    @(~,event) disp(getReport(event.Error)));
s1.UserData.Data = [];
s1.UserData.Time = [];
s1.Rate = 10;

% Create and configure session and channels for cDAQ 9201 module
s2 = daq.createSession('ni');
addAnalogInputChannel(s2, 'cDAQ1Mod2', 'ai0', 'Voltage');
s2.DurationInSeconds = daqDuration;
daListener2 = addlistener(s2, 'DataAvailable', @DataAvailable_callback);
errListener2 = addlistener(s2, 'ErrorOccurred', ...
    @(~,event) disp(getReport(event.Error)));
s2.UserData.Data = [];
s2.UserData.Time = [];
s2.Rate = 100;
Warning: The Rate property was reduced to 14.2857 due to changes in the session
configuration. 

Сконфигурируйте триггерные связи

Чтобы синхронизировать приобретение запускаются, можно использовать аппаратное инициирование и основной/ведомый подход. Один из сеансов (ведущее устройство) запускается вручную и инициировал приобретение, запускаются другого сеанса (ведомое устройство).

Примечание: Если у вас есть модель шасси CompactDAQ (такая как NI 9174), который не имеет терминалов инициирования PFI, можно использовать дополнительный цифровой модуль ввода-вывода (такой как NI 9402), чтобы обеспечить терминалы PFI для триггерных связей.

% Configure this session (master) to export a triggering signal on the PFI0
% terminal of cDAQ1 chassis
addTriggerConnection(s1, 'cDAQ1/PFI0', 'External', 'StartTrigger');

% Configure this session (slave) to start acquisition when an external
% triggering signal is received at PFI0 terminal of cDAQ1 chassis
addTriggerConnection(s2, 'External', 'cDAQ1/PFI0', 'StartTrigger');

Запустите приобретение и ожидайте до завершенные

Ведомый сеанс должен быть запущен сначала и быть готов к внешнему триггеру прежде, чем запустить основной сеанс.

startBackground(s2)
while ~s2.IsWaitingForExternalTrigger
    pause(0.1)
end
startBackground(s1)

wait(s1, daqDuration+1)
wait(s2, daqDuration+1)

Сохраните данные как расписание

Полученные данные и метки времени хранились в свойстве UserData сеанса. Скопируйте данные в переменную базового рабочего пространства и преобразуйте их в расписание.

data1 = array2timetable(s1.UserData.Data, ...
    'RowTimes', seconds(s1.UserData.Time),...
    'VariableNames', {s1.Channels.ID});

data2 = array2timetable(s2.UserData.Data, ...
    'RowTimes', seconds(s2.UserData.Time), ...
    'VariableNames', {s2.Channels.ID});

Отобразите полученные данные на графике

Поскольку полученные данные из этих двух устройств имеют различные шкалы и модули, создают график с двумя осями Y.

figure;

yyaxis left
plot(data1.Time, data1.ai0, '-x')
ylabel('Temperature (deg. C)')
ylim([0 50])
yyaxis right
plot(data2.Time, data2.ai0, '-o')
ylabel('Voltage (V)')
xlabel('Time (s)')

Очистка

Удалите прослушиватели и очистите эти два сеанса, чтобы отключиться от оборудования.

delete(daListener1)
delete(daListener2)
delete(errListener1)
delete(errListener2)
clear s1 s2 daListener1 daListener2 errListener1 errListener2

Локальные функции

Функция DataAvailable_callback используется в качестве разделяемого коллбэка для события DataAvailable сеансов s1 и s2.

function DataAvailable_callback(src, event)
%DATAAVAILABLE_CALLBACK Callback function for session DataAvailable event
% Stores acquired data and timestamps in the session UserData property

src.UserData.Data = [src.UserData.Data; event.Data];
src.UserData.Time = [src.UserData.Time; event.TimeStamps];

end
Для просмотра документации необходимо авторизоваться на сайте