Глава 2. Получение и визуализация данных эксперимента

Подключение устройства сбора данных NI USB 6351


Рассмотрим пример, связанный с автоматизацией регистрации температуры в каком-либо физическом эксперименте. Для этого нам потребуется термопара, подключённая к аналого-цифровому преобразователю (АЦП). Такое электронное устройство мы можем легко найти в стандартной плате сбора данных. Компания National Instruments специализируется на выпуске соответствующих устройств, которые уже давно стали фактическим стандартом для экспериментальных исследований. Однако для работы с этими устройствами обычно используется система LabView, которую мы и собираемся заменить программой на Python.

Мы использовали устройство DAQ (Data acquisition, система сбораданных) NI USB 6351. Это устройство, как следует из его обозначения, использует USB-интерфейс для взаимодействия с компьютером.

Для сопряжения с внешними устройствами (датчиками, периферийным оборудованием) имеется:

16 аналоговых входов с временным разрешением 10 нс и входным напряжением до ±10 В (АЦП);
2 аналоговых выхода (16-разрядные цифро-аналоговые преобразователи);
24 цифровых ввода-вывода;
четыре 32-битных счётчика-таймера до 25 МГц;
генератор базовых частот.

Из этого изобилия возможностей мы будем использовать только один аналоговый двуполярный вход AI0 (клеммы + и – ), к которым и подключим термопару.

Этап 1:

Первый этап состоит в установке актуальных драйверов поддержки оборудования National Instruments. Возможно, вместе с драйверами вы разрешите инсталлятору установить ряд дополнительных программ, которые обычно весьма полезны на стадии отладки приложений, работающих с DAQ.

Драйверы относятся к свободнораспространяемому программному обеспечению, необходима только регистрация на сайте.

Этап 2:

На втором этапе проверяем подключение и работу устройства с использованием загруженной вместе с драйверами программы NI Device Monitor. Устройство сбора данных в нашей системе установилось с именем Dev1, для работы нам нужен аналоговый вход ai0.

Этап 3:

Устанавливаем пакет nidaqmx из командной строки Windows в режиме администратора:

python -m pip install nidaqmx

Эта библиотека постоянно модифицируется и её функциональные возможности всё время увеличиваются. Поэтому при использовании рассмотренных ниже примеров следует обязательно руководствоваться актуальным описанием для данной библиотеки.

Мы использовали оболочку IDLE Python в режиме программирования (программа сохранялась в файл и запускалась на выполнение).

Итак, напишем простую проверочную программу на Python для тестирования подключения к плате сбора данных:


Работа с DAQ-устройствами происходит в парадигме задач: сначала устройство программируется на определённый вид деятельности, а затем мы начинаем получать данные с этого устройства. В нашем случае в строке 4 мы программируем аналоговый вход 0 на получение значений напряжения (это выглядит, на первый взгляд, тривиально, но в коллекции методов у нас есть возможность запрограммировать конкретный вход на измерение иных физических величин). Выполняем задачу в строке 5, измеряя в 10 раз значение напряжения. Конструкция with … as (так называемый менеджер контекста, где мы пишем всё, что связано с DAQ-задачей) делает более удобной работу с объектом Task библиотеки nidaqmx и корректно формирует завершение задачи.

Результат выполнения программы будет выведен в виде списка:

[0.07741842546889639, 0.07774029508782221,
 0.07774029508782221, 0.07774029508782221,
 0.07774029508782221, 0.07741842546889639,
 0.07774029508782221, 0.07774029508782221,
 0.07806216470670671, 0.07774029508782221] 
Этап 4:

Теперь подключим термопару (в нашем случае это была термопара железо-константан, т.е. типа J) ко входу ai0 и модифицируем программу следующим образом:


Мы изменили вид данных, возвращаемых со входа ai0, разрешив использовать встроенную в библиотеку калибровку температуры для данного типа термопары (строка 10). В зависимости от вида термопары можно выбрать несколько уже готовых калибровок. В строке 12 указывается, что для каждого обращения к плате сбора данных мы будем брать только одно значение. Однако при этом создаётся цикл (со строки 11) для выборки 100 значений с задержкой между измерениями 0.5 с (строка 14).

Хотелось бы, чтобы измеренное значение появлялось на графике в тот момент, когда выполнено очередное измерение. Для этого в строке 4 переводим окно визуализации графика в интерактивный режим. Теперь поле графика появится сразу после первого выполнения метода plt.pause. Для отображения точек был использован метод scatter из библиотеки matplotlib (строка 13), который выводит точку с указанными значениями координат i, temp на поле графика. Точки линиями не соединяются.

Интерактивный режим включается с помощью метода ion() пакета matplotlib, а выключается методом ioff(). При этом в интерактивном режиме метод show() не используется, вместо него можно использовать метод draw(), который отображает график и не задерживает выполнение программы. В нашем варианте функцию обновления графика с успехом выполняет метод pause().

Если мы хотим привязаться не к номеру измерения, как в рассмотренном примере, а к реальным меткам времени, воспользуемся возможностями модуля time (импорт в строке 3):


Вычисление времени, прошедшего с начала измерения, осуществляется в строке 18. В этом варианте программы мы использовали бесконечный цикл для чтения информации с аналогового входа платы сбора данных, однако предусмотрели выход из программы по нажатию комбинации клавиш Ctrl-C. Для этого использовалась стандартная конструкция обработчика ошибок Python try … except.

Использование метода scatter позволяет достаточно удобно реализовать динамическое отображение измеряемых значений. В принципе, ничто не мешает заменить этот метод классическим plot, однако следует учесть, что линии, соединяющие точки, при этом всё равно не будут отображаться.

Программа, которая строит график в реальном времени с возможностью выбора типа соединительной линии и маркера экспериментальных точек, будет несколько сложнее (представлено Anthony Zhang на github). При этом, как и в классическом виртуальном инструменте LabView Chart, получаем бесконечную «ленту самописца», что очень удобно для визуализации данных с неизвестным временем завершения процесса. Попробуйте реализовать этот вариант программы самостоятельно. Вот что у вас должно получиться:


Обратите внимание, что Python и библиотека matplotlib поддерживают отрисовку специальных символов в подписях осей координат и в любых других текстовых метках на поле графика. Если потребуются отобразить, например, греческие буквы, можно использовать следующую конструкцию:

plt.title(r'$\Sigma \alpha^2 \beta \omega_i$')

Символ r (отключение экранировки) перед текстовой строкой обязателен

Символы \(\sum_{k=1}^{\infty} \Delta_j \) можно изобразить на графике с помощью следующей строки:

r'$\sum_{j=0}^\infty \Delta_j$'

Если вы заметили неточность, ошибку или хотите поделиться своими мыслями по поводу статьи - мы рады обратной связи. Давайте вместе сделаем ресурс лучше!

От кого:
Ваш комментарий будет виден всем пользователям