Руководство по интеграции SDK PMSOpticDll V4.4.7 для моторизованных зум-объективов

SDK PMSOptical предоставляет 44 экспортируемые C-функции из одной Windows DLL, охватывающие последовательное и Ethernet-соединение, абсолютное позиционирование, обратное чтение состояния, возможности шифрованной контроллерной карты и полное параллельное семейство API для двухмоторных объективов. Базовый рабочий процесс — четыре вызова: open → home → move → wait. Дескриптор получают через PMSOptical_OpenComm("COM1", 9600) для последовательного порта или PMSOptical_OpenSocket("192.168.1.200", 4196) для TCP.

В этом руководстве описаны семейства функций, рекомендуемая последовательность вызовов и четыре ограничения интеграции, вызывающие большинство проблем у новичков, — включая одно, важное для безопасности оборудования: в SDK нет пригодной для использования программной аварийной остановки.

Ключевые факты вкратце

ПунктЗначение
Экспортируемые функции44 (24 одномоторные, 20 двухмоторных)
ПлатформаWindows x64 / x86 (DLL)
СоединениеПоследовательный порт 9600 бод или TCP на порту 4196
Тип дескриптораPMSHANDLE (void*) — всегда проверяйте на null
Базовая последовательностьOpen → GoHome → MoveTo(pulse) → WaitForOpticalFinished → GetPos → Close
Тайм-аут ожидания по умолчанию100000 ms (100 s)
Нереализованные функции8, включая Stop и Stop2
Привязки языковНативный C++; C# через P/Invoke; другие языки через ctypes/cffi (официальной привязки нет)

Структура пакета

PMSOptical-SDK/
├── Doc/
│   ├── POMEAS electric lens development documents V4.4.7.pdf   (English)
│   ├── encrypted / non-encrypted development documents V4.4.7  (control-card comparison)
│   └── dual-motor control card operation manual V1.5
├── SDK/
│   ├── include/PMSOpticalDll.h            44 exported functions
│   ├── x64/{Release,Debug}/PMSOpticalDll.dll + .lib
│   │   └── OP/*.txt                       per-model pulse tables
│   └── x86/{Release,Debug}/               same, 32-bit
└── demo/
    └── x64/PMSOpticalDemo.exe + .ini      MFC demo application

DLL должна лежать рядом с исполняемым файлом или находиться в системном PATH.

Подключение

СпособФункцияПараметры
ПоследовательныйPMSOptical_OpenComm(char* comname, int nBaud)comname, напр. "COM1"; nBaud = 9600
EthernetPMSOptical_OpenSocket(char* ip, int nPort)ip, напр. "192.168.1.200"; nPort = 4196
Запрос состоянияPMSOptical_IsOpened(PMSHANDLE, bool&)—
ЗакрытиеPMSOptical_Close(PMSHANDLE&)Дескриптор передаётся по ссылке

Для сетевого подключения хост-ПК и контроллерная карта объектива должны находиться в одной подсети — первые три октета должны совпадать, например 192.168.1.xxx. Маска подсети получается автоматически.

#include "PMSOpticalDll.h"

PMSHANDLE h = PMSOptical_OpenComm("COM2", 9600);            // serial
// PMSHANDLE h = PMSOptical_OpenSocket("192.168.1.200", 4196);  // Ethernet
if (!h) { /* connection failed */ }

44 функции по семействам

Семейство 1 — управление соединением (1–4)

№ФункцияНазначение
1PMSOptical_OpenSocket(char* ip, int nPort)Открыть через Ethernet, вернуть дескриптор устройства
2PMSOptical_OpenComm(char* comname, int nBaud)Открыть через последовательный порт, вернуть дескриптор устройства
3PMSOptical_IsOpened(PMSHANDLE, bool& bIsOpened)Сообщить, открыт ли дескриптор
4PMSOptical_Close(PMSHANDLE&)Закрыть дескриптор

Функции 3 и 4 передают результат и дескриптор по ссылке. Это сделано намеренно: в заголовочном файле отмечено, что сигнатуры сформированы так ради совместимости с C# P/Invoke.

Семейство 2 — управление одним мотором (5–15)

№ФункцияНазначениеРеализовано
5GoHome(PMSHANDLE)Возврат в исходное положениеДа
6IsHomed(PMSHANDLE, bool&)Сообщить, завершён ли возврат в исходное положениеНет — помечено как нереализованное
7MoveTo(PMSHANDLE, int nPulse)Переход в абсолютную позицию по импульсамДа
8Stop(PMSHANDLE)Остановка немедленноНет — помечено как нереализованное
9JogStart(PMSHANDLE, int nJogSpeed)Джог (положительная или отрицательная скорость)Нет — помечено как нереализованное
10JogStop(PMSHANDLE)Остановка джогаНет — помечено как нереализованное
11GetPos(PMSHANDLE, int& nCurPulse)Чтение текущей позицииДа
12GetMaxPos(PMSHANDLE, int& nMaxPulse)Чтение максимального импульса (общего хода)Да
13GetStatus(PMSHANDLE, int& nStatus)Чтение состояния движения: 0 движение, 1 остановка, 2 сбой инициализацииДа
14WaitForOpticalFinished(PMSHANDLE, int nTimeOut = 100000)Блокировка до завершения движения зумаДа
15GetVer(PMSHANDLE, char* Ver)Чтение версии прошивкиДа

WaitForOpticalFinished внутренне оборачивает логику опроса состояния — опрашивает запрос статуса и проверяет признак останова — с тайм-аутом по умолчанию 100000 ms. В большинстве приложений следует вызывать её, а не писать собственный цикл опроса.

Семейство 3 — шифрованная контроллерная карта (16–24)

Доступно только когда объектив укомплектован шифрованной контроллерной картой (обозначается словом encrypt в имени файла таблицы импульсов).

№ФункцияНазначение
16EncryptCommStatus(PMSHANDLE, bool& IsConnected)Подключена ли шифрованная плата
17EncryptReadTimes(PMSHANDLE, int& nTimes)Чтение счётчика циклов зума
18EncryptWriteTimes(PMSHANDLE, int nTimes)Запись счётчика циклов зума
19EncryptAddTimes(PMSHANDLE)Увеличение счётчика циклов зума
20EncryptReadFlashMaxPos(PMSHANDLE, int&)Чтение максимального импульса, хранящегося в Flash
21EncryptWriteFlashMaxPos(PMSHANDLE, int)Запись максимального импульса в Flash
22EncryptCheckHomeStatus(PMSHANDLE, bool& bHasStatus, bool& bNowStatus)Состояние возврата в исходное положение и концевого выключателя
23EncryptReadFlashLensInfo(PMSHANDLE, unsigned char buf[64])Чтение информации об объективе (фиксированный блок 64 байта)
24EncryptWriteFlashLensInfo(PMSHANDLE, unsigned char buf[64])Запись информации об объективе (только печатный ASCII)

Для чего на самом деле нужна шифрованная карта: она хранит счётчик циклов зума и 64-байтовый блок идентификации объектива в Flash контроллера. Это поддерживает учёт активов оборудования, статистику использования и распознавание подлинного объектива — непосредственно полезно для системных интеграторов, прокатных парков и сервисных служб.

Семейство 4 — двухмоторные объективы (25–44)

У каждой функции выше есть параллельная версия с суффиксом 2 и конечным параметром unsigned char u8lensnum = 0, выбирающим мотор 1 или мотор 2.

ОдномоторнаяДвухмоторнаяНазначение
GoHomeGoHome2(h, u8lensnum)Возврат выбранного мотора в исходное положение
IsHomedIsHomed2(h, bool&, u8lensnum)Нереализовано
MoveToMoveTo2(h, nPulse, u8lensnum)Переход выбранного мотора в абсолютную позицию
StopStop2(h, u8lensnum)Нереализовано
JogStart / JogStopJogStart2 / JogStop2Нереализовано
GetPosGetPos2(h, int&, u8lensnum)Чтение позиции
GetMaxPosGetMaxPos2(h, int&, u8lensnum)Чтение общего хода
GetStatusGetStatus2(h, int&, u8lensnum)Чтение состояния
WaitForOpticalFinishedWaitForOpticalFinished2(h, nTimeOut, u8lensnum)Ожидание завершения
GetVerGetVer2(h, char*, u8lensnum)Чтение версии прошивки
Encrypt* (9 functions)Encrypt*2(h, …, u8lensnum)Полный набор для шифрованной карты

Двухмоторные объективы сочетают мотор зума с независимым мотором доводки фокуса — например, зум-объектив 12.5X с 12 mm моторизованной доводкой фокуса или двухмоторный 12.5X с осью доводки 3 mm.

// Dual motor: motor 0 = zoom, motor 1 = focus trim
PMSOptical_GoHome2(h, 0);
PMSOptical_MoveTo2(h, 4600, 0);                        // zoom to 1X (see the model pulse table)
PMSOptical_WaitForOpticalFinished2(h, 100000, 0);

Рекомендуемая последовательность вызовов

Open (serial or Ethernet)
   |
GoHome()  ->  WaitForOpticalFinished(timeout)
   |
GetMaxPos()  ->  validate total travel, and confirm the link is alive
   |
+-- MoveTo(pulse)
|     ->  WaitForOpticalFinished(timeout)   (or poll GetStatus until it returns 1)
|     ->  GetPos()  ->  compare with target (closed loop)
+-- repeat for the next magnification
   |
Close()

Блок-схема производителя предписывает три правила для пути опроса:

  1. Ждите не менее 50 ms перед каждым запросом статуса.
  2. Задайте общий тайм-аут — в руководстве рекомендуется 10 секунд или более.
  3. Если общий тайм-аут истекает без действительного ответа, объявите ошибку соединения с объективом и корректно завершите работу.

Четыре ограничения интеграции

1. Связь прерывается, пока движется мотор

Пока контроллерная карта приводит мотор, связь приостанавливается. Запрос статуса может вообще ничего не вернуть. Обрабатывайте это через тайм-аут и повтор или вызывая WaitForOpticalFinished. Не считайте это сбоем и не перезапускайте соединение.

2. Запрос перемещения, равный текущей позиции, ничего не делает

Если запрошенный импульс равен текущему, объектив не двигается и сообщает об успехе. Никогда не используйте «команда отправлена» как проверку живости линии. Используйте вместо этого GetMaxPos или GetPos.

3. Инициализация при включении занимает 25–35 секунд

При включении питания объектив сам возвращается в исходное положение и не принимает команд в это время. Прикладная программа должна ждать не менее 35 секунд, прежде чем открывать соединение и отдавать команды. Игнорирование этого — частая причина сообщений «устройство не отвечает», которые на самом деле не являются сбоями.

4. Программной аварийной остановки нет

Stop и Stop2 оба помечены как нереализованные в заголовочном файле, наряду с IsHomed, JogStart, JogStop и их двухмоторными аналогами — всего восемь функций. Не проектируйте вокруг них функцию безопасности. Определяйте завершение через GetStatus или WaitForOpticalFinished, а аварийную остановку реализуйте аппаратной схемой — отключением питания или внешним сигналом блокировки.

Аппаратные правила, от которых зависит ПО

  1. Подключите и зафиксируйте моторный кабель и кабель RS-232 до подачи питания. Подключение под напряжением может повредить схему привода.
  2. Никогда не подключайте и не отключайте моторный кабель при включённом питании. Это самое разрушительное действие на практике и может необратимо повредить мотор.
  3. Если моторный кабель должен быть длиннее 5 m, закажите заводской удлинительный кабель. Не сращивайте несколько коротких и не делайте свой.
  4. Выберите последовательный порт или Ethernet, но не оба. Контроллерная карта поддерживает любой вариант; режим соединения в ПО должен соответствовать аппаратной разводке.

Шифрованная или стандартная контроллерная карта?

ТребованиеРекомендация
Только управление зумомСтандартная карта
Подсчёт использования, проверка подлинности, прокатная тарификацияШифрованная карта (EncryptReadTimes, EncryptReadFlashLensInfo)
Смешанный паркУчтите, что две карты используют разные таблицы импульсов — смена карты означает смену таблицы

Часто задаваемые вопросы

Поддерживает ли SDK Linux или macOS?

Официальный SDK поставляется только с DLL для Windows (x64 и x86). На других платформах реализуйте последовательный протокол напрямую — это пять простых ASCII-команд без привязки к платформе, поэтому они работают на любом хосте с последовательным портом или TCP-сокетом.

Можно ли вызывать SDK из Python?

Да, через ctypes или cffi, поскольку экспорты имеют C-связывание. Официальной привязки Python нет, поэтому обёртку пишете вы сами. Учтите, что PMSHANDLE — это void*, а параметры bool& нужно передавать через ctypes.byref.

Можно ли смешивать SDK и сырые последовательные команды?

Технически да, но не делайте этого на одной линии. Оба обращаются к одним и тем же аппаратным регистрам, и их смешивание — особенно вблизи исходной точки (home) — приводит к несогласованному состоянию. Выберите один подход на проект.

Какой тайм-аут задать для WaitForOpticalFinished?

По умолчанию 100000 ms. Задайте его не менее чем в два раза больше времени, которое самый большой ход зума занимает на вашем оборудовании. Справочное значение в руководстве — 10 секунд или более.

Это интерфейс ИИ-зрения?

Нет, и описывать его так не следует. SDK предоставляет программируемый интерфейс управления оптикой — позицию, состояние и обратное чтение. Его можно интегрировать в архитектуру ИИ-зрения, где управляющее ПО выдаёт новую команду увеличения на основе результата инспекции, но сам SDK не содержит возможностей ИИ или анализа изображений. Точная формулировка: моторизованную зум-оптику можно интегрировать в управляемый ИИ рабочий процесс машинного зрения.

Есть ли известные проблемы в заголовочном файле?

Две стоит знать. GetVer2 объявляет свой параметр как u8lennum — опечатка, не влияющая на вызов, но её стоит нормализовать в собственной обёртке. И на восемь нереализованных функций, описанных выше, полагаться нельзя.

Полезные материалы

Похожие продукты

Вернуться к началу
VK Message
WhatsApp

Отсканируйте QR-код

QR-код WhatsApp
Wechat

Отсканируйте QR-код

QR-код Wechat
Номер телефона
+8618598102007
Скопировано!
Сообщение в режиме онлайн

Сообщение в режиме онлайн

Click to refresh