Здравствуйте товарищи!
В статье хочу поделиться с вами своим опытом по применению стандартных команд для программируемых инструментов (SCPI). Рассмотрим, как подключиться к установке проверки электрической безопасности GWINSTEK GPT-79803 и автоматизировать измерения и запись результатов.
Предприятие, на котором я работаю, занимается разработкой и производством интересных штук. В том числе специальных соединителей. Соединитель представляет собой кабель с разъемами на концах. К соединителю есть ряд требований и одно из них — сохранять работоспособность в условиях повышенного давления под водой. Соединители были разработаны и изготавливаются. Каждый соединитель в обязательном порядке проходит испытания повышенным давлением в воде. Тут и появляется наш прибор. Он может подать на исследуемые компоненты большую разность потенциалов и измерить сопротивление между ними (например, между чётными и нечётными проводниками в кабеле соединителя). Если в конструкции где-то нарушается герметичность (продавливается вода), то прибор покажет изменение сопротивления и, в зависимости от настроек, тест будет либо пройден либо нет.
Процесс испытания проходит следующим образом:
-
сопротивление замеряется в нормальных условиях;
-
потом постепенно повышается давление и на определенных отметках замеры повторяются;
-
каждый замер документируется путём фотографирования экрана, скачивания фоток и занесения их в протокол испытаний.
На этом моменте мой коллега устал и спросил: «А можно ли как-то сделать, что бы результаты сразу в компьютере появлялись?». «Если на задней панели есть гнездо разъема USB type A, то, наверное, можно» — ответил я.
Подключаем прибор к компьютеру. В менеджере устройств он определяется как «конвертер USB COM CP210X». Настраиваем соединение и подключаемся терминалом. Соединение устанавливается … и всё. Немигающий зеленый курсор, ничего не появляется и ничего не вводится. Самое время заглянуть в документацию. (На самом деле всё вводилось и появлялось, но об этом позже, чтобы сохранить линейность произошедшего)
Ответов в рисунке выше найдено не было, дальнейший поиск шел на сайте производителя. И, что интересно, прибора с наименованием GPT-79803 на официальном сайте Gwinstek я не нашел. Но там были GPT-9803 c документацией и программами. Скорее всего прибор в моей компании был изготовлен по спецзаказу (русские буквы на рамке экрана и 7 в начале номера модели на это указывают, но это не точно).
Программа была загружена и установлена. По меню и главному окну понятно, что все необходимые функции реализованы. Бери и пользуйся.
Но при попытке подключения выводилось окно с перечислением приборов к которым можно подключиться (естественно все индексы приборов были без семёрки).
С одной стороны опять неудача, с другой — программа как-то получила идентификатор моего прибора, сравнила его со своим списком разрешенных в Российской Федерации моделей, не нашла его там и отказала (наверное, санкции). Обмен данными происходит. Значит надо подсмотреть, почему программа обменивается данными, а через терминал не получается.
Для сниффинга USB использовалась программа USBPcap. Это консольное приложение позволяет перехватить обмен по USB и записать его в формате pcap. Этот формат можно открыть программой Wireshark. Процесс происходит следующим образом:
-
запускается USBPcap;
-
USBPcap выдает список подключенных устройств, цифрой выбираем интересующее устройство и вводим название файла для записи;
-
рядом открывается окно программы прибора;
-
в USBPcap начинаем запись, в программе прибора проводим процедуру подключения;
-
останавливаем запись, в Wireshark открываем полученный файл.
На рисунке ниже находим первую команду, которая была отправлена от хоста к устройству
Странно, ведь в руководстве оператора написано *IDN? (по этой команде прибор отвечает своим наименованием). Смотрим дальше.
А вот и интересующий ответ ниже.
Дальше исследования переместились в Юпитер блокнот. Мне удобно проверять элементы кода в нем и смотреть вывод на разных этапах. Для попыток подключения к прибору использовалась библиотека pyvisa, но подключиться так и не удалось (хотя наличие прибора определялось).
На этом этапе возникла идея, что при попытке подключения терминалом просто не выводилось эхо вводимых символов, а при попытке ввода команд *CLS *IDN? в слепую — прибор ответил (потом я включил эхо в настройках Putty и в терминале всё стало выглядеть ожидаемо). Можно смело вернуться в Юпитер блокнот и организовать обмен с прибором, на этот раз через pyserial. Методом проб было выяснено, что в конце команды надо добавлять символ новой линии и перевода каретки.
Команды для работы именно с этим прибором были найдены на официальном сайте (естественно для 9000 серии). Когда диалог налажен, можно спросить у прибора текущий режим и запустить измерение.
Для ускорения внедрения рационального предложения было решено написать небольшое приложение с использованием pyQt (ну не понравится моему коллеге работать с Юпитер блокнотом).
П р и м е ч а н и е — Так-то я не программист, поэтому ниже представленный код можно и нужно критиковать.
Для создания интерфейса решено было использовать Qt Designer. Нужно всего лишь добавить…(с) QListWidget, QComBobox, QPushButton. Размещены элементы на вертикальном макете (Vertical Layout) — при масштабировании окна элементы будут масштабироваться автоматически. Сохраняем интерфейс (я назвал файл design.ui) и конвертируем ui файл в py файл. В составе pyQt для этого есть программа pyuic6. Конверсия происходит вызовом программы pyuic6 design.ui design.py из каталога с программой. Рекомендуется добавить путь к pyuic6 в переменную PATH, у меня путь выглядел примерно так — C:\Users\……\AppData\Roaming\Python\Python312\Scripts.
Во избежание зависания интерфейса программы, функция измерения помещается в поток. Ещё мне захотелось изменять цвет кнопки во время измерения и оказалось, что из потока нельзя менять ui. Вопрос решается через механизм сигналов. Ниже представлен код программы.
import sys # sys нужен для передачи argv в QApplication from PyQt6 import QtWidgets from PyQt6.QtCore import pyqtSignal, QObject, pyqtSlot import serial.tools import serial.tools.list_ports import design # Это наш конвертированный файл дизайна import time import serial from threading import * import datetime as dt class ExampleApp(QtWidgets.QMainWindow, design.Ui_MainWindow): sendChangeColorBusy = pyqtSignal() sendChangeColorReady = pyqtSignal() def __init__(self): # Это здесь нужно для доступа к переменным, методам # и т.д. в файле design.py super().__init__() self.setupUi(self) # Это нужно для инициализации нашего дизайна self.PB_Mesure.clicked.connect(self.thread) # Запуск потока по кнопке # Изменение цвета кнопки self.sendChangeColorBusy.connect( lambda: self.PB_Mesure.setStyleSheet('background-color: red; color: yellow')) self.sendChangeColorReady.connect( lambda: self.PB_Mesure.setStyleSheet('background-color: light gray; color: black')) # Получаем список COM портов ports=serial.tools.list_ports.comports() # Пробум заполнить выпадающий список try: print(ports[0]) for port in ports: self.comboBox.addItems(port) except: self.statusbar.showMessage('Прибор не обнаружен! Проверьте подключение и перезапустите программу.') # Процесс измерения запускается в потоке def thread(self): t1=Thread(target=self.measure,args=(self,)) t1.start() # функция измерения def measure(self,obj): #Имя порта получаем из выпадающего списка port = str(self.comboBox.currentText()) baudrate = 115200 # Скорость порта ser = serial.Serial(port, baudrate=baudrate) # Если удалось открыть порт, шлём команды и читаем ответы if(ser.is_open == True): # Запрос профиля измерения message = b"*CLS\n\r" ser.write(message) message = b"MANU15:EDIT:SHOW ?\n\r" ser.write(message) data = ser.readline() profile=data.decode("utf-8") # Вывод профиля в статус бр self.statusbar.showMessage('Профиль >>> '+profile.strip("\r\n")) # Команда на начало измерения message = b"*CLS\n\r" ser.write(message) message = b"FUNC:TEST ON\n\r" ser.write(message) # Сигнал изменения цвета кнопки obj.sendChangeColorBusy.emit() # Цикл ожидания измерения. Нужно как-то по другому реализовать for i in range (33): self.PB_Mesure.setText('Внимание, идет измерение! '+str(i)+'c') time.sleep(1) # Запрос результата измерения command = b'*CLS\n\r' ser.write(command) command = b'MEAS?\n\r' ser.write(command) data = ser.readline() # Ответ приходит в виде массива байт, конвертируем в строку answer=data.decode("utf-8") # Выводим ответ self.listWidget.addItem(dt.datetime.now().strftime("%H:%M:%S") +' '+answer.strip("\r\n")) # Сигнал на изменение цвета кнопки obj.sendChangeColorReady.emit() ser.close() self.statusbar.showMessage('Готов') self.PB_Mesure.setText('Измерить!') # Запись измерения в файл with open("test.txt", "a") as myfile: myfile.write(dt.datetime.now().strftime("%H:%M:%S") +' '+answer.strip("\r")) else: self.statusbar.showMessage('Порт занят!') def main(): app = QtWidgets.QApplication(sys.argv) # Новый экземпляр QApplication window = ExampleApp() # Создаём объект класса ExampleApp window.show() # Показываем окно app.exec() # и запускаем приложение if __name__ == '__main__': # Если мы запускаем файл напрямую, а не импортируем main() # то запускаем функцию main()
Уже глядя на код в статье появились такие мысли:
-
получать время ожидания из профиля прибора, и как-то по таймеру опрашивать статус измерения;
-
выделить отдельно функцию отправки команд и реализовать обработку ошибок;
-
после подключения к прибору проверять действительно ли это целевой прибор.
Ниже представлены снимки экрана в процессе измерения и ожидания.
В результате проделанной работы получаем дополнительный инструмент для упрощения рутинной работы, опыт и инженерное наслаждение (от того, что заработало).
Дальнейшее развитие может быть следующим. В составе испытательной камеры есть цифровой манометр. Его можно также подключить и запускать автоматически измерение при достижении определенного давления. А дальше — pandas — pydocx — шаблон документа — готовый отчет. Уже прям на измерительный комплекс тянет!
Скрытый текст
Мне нравится читать о том, что делают увлеченные своим делом технари. Например такие: https://t.me/monobogdann, https://t.me/igornegodastartuem, https://t.me/alexgyvershow, https://t.me/dlinyj_news, https://t.me/brainfuckpc, https://t.me/DV_Workrshop.
И я решил создать свой канал. Там про моделирование, электронику и программирование. Возможно, вам будет интересно — https://t.me/modelistconstruktor
ссылка на оригинал статьи https://habr.com/ru/articles/863586/
Добавить комментарий