В производственных процессах и отделах контроля качества часто возникает задача фиксации геометрических параметров деталей. Для исключения ручного ввода измерительные приборы (электронные индикаторы, штангенциркули, микрометры) подключают напрямую к рабочему месту оператора через физический или виртуальный последовательный интерфейс (COM-порт). Разберем практический способ организации прямого обмена данными между измерительным прибором и платформой 1С:Предприятие 8.3.
Для прямого низкоуровневого опроса последовательного порта в среде Windows традиционно используется библиотека MSCommLib (элемент управления MSComm32.ocx). Данный объект регистрируется в операционной системе и позволяет взаимодействовать с COM-портами через стандартный COM-механизм платформы 1С.
Выясним, с какими особенностями можно столкнуться при использовании этой компоненты:
MSComm32.ocx является строго 32-разрядной (x86). Ее вызов в 1С возможен только из 32-разрядного клиента («Тонкий клиент (x86)» или толстый клиент). При запуске в 64-разрядном клиенте или на сервере 1С x86-64 попытка создания объекта завершится ошибкой.COMSafeArray.Рассмотрим типовой сценарий: оператор нажимает кнопку передачи данных на самом приборе, в результате чего прибор отправляет пакет байтов в COM-порт. На стороне 1С выполняется процедура инициализации порта, ожидания пакета и выгрузки принятых данных.
Посмотрим на пример кода подключения и чтения:
Попытка
ComPort = Новый COMОбъект("MSCOMMLib.MSComm.1");
Исключение
Сообщить("Ошибка создания объекта MSComm: " + ОписаниеОшибки(), СтатусСообщения.ОченьВажное);
Возврат;
КонецПопытки;
Попытка
// Указываем номер порта, к которому подключен прибор (например, COM1)
ComPort.CommPort = 1;
// Параметры связи: скорость 9600, без контроля четности, 8 бит данных, 1 стоп-бит
ComPort.Settings = "9600,N,8,1";
// Отключаем программный контроль потока
ComPort.Handshaking = 0;
// Сбрасываем счетчик и очищаем буфер
ComPort.InBufferCount = 0;
ComPort.InBufferSize = 70;
ComPort.InputLen = 0;
// Режим приема: 1 - двоичные данные (возвращает COMSafeArray), 0 - текстовый режим
ComPort.InputMode = 1;
ComPort.NullDiscard = 0;
// Активируем линию готовности к передаче
ComPort.RTSEnable = 1;
// Открываем порт
ComPort.PortOpen = Истина;
// Ожидаем появления данных в буфере
ПодождатьПриемаСимволовСТаймаутом(ComPort, 7, 2);
// Считываем принятые данные
ПринятаяПосылка = ComPort.Input;
// Закрываем порт сразу после получения данных
ComPort.PortOpen = Ложь;
Сообщить("Связь установлена, данные успешно прочитаны.");
Исключение
Сообщить("Не удалось открыть порт или считать данные: " + ОписаниеОшибки(), СтатусСообщения.ОченьВажное);
Если ComPort.PortOpen Тогда
ComPort.PortOpen = Ложь;
КонецЕсли;
КонецПопытки;
Частая проблема при работе с измерительными приборами (особенно китайского производства) заключается в том, что порт успешно открывается, на приборе нажимается кнопка отправки, но свойство ComPort.Input возвращает абсолютно пустой массив или пустую строку. Проанализируем физическую причину такого поведения.
Многие компактные измерительные приборы не имеют собственного полноценного источника питания для микросхемы согласования уровней RS-232. Для передачи сигнала интерфейс использует так называемое паразитное питание от служебных линий COM-порта управляющего компьютера. Сигнал RTS (Ready to Send) выставляет положительное напряжение на соответствующей ножке разъема, которое питает оптопару или передатчик кабеля прибора. Если в коде не включить свойство ComPort.RTSEnable = 1, микросхема преобразователя интерфейса останется обесточенной, и прибор физически не сможет передать данные в порт. В ряде аналогичных кабелей может дополнительно потребоваться включение линии терминала: ComPort.DTREnable = 1.
Разберем последовательность обработки полученного значения:
ПринятаяПосылка = ComPort.Input; данные из внутреннего буфера порта переносятся в переменную ПринятаяПосылка. Повторное обращение к свойству ComPort.Input вернет уже пустой результат, так как буфер очищается при вычитке. Выгрузку необходимо делать именно из полученной переменной: МассивБайт = ПринятаяПосылка.Выгрузить();.Если решение на базе MSCommLib не подходит из-за ограничений разрядности или блокировки графического интерфейса 1С во время ожидания пакета, проанализируем современные альтернативные варианты:
ОбработкаОповещения или ВнешнееСобытие без зависания интерфейса.