Guía de integración del SDK PMSOpticDll V4.4.7 para lentes zoom motorizados
El SDK PMSOptical expone 44 funciones C exportadas desde una única DLL de Windows, que cubren conexión serie y Ethernet, control de posición absoluta, lectura de estado de vuelta, funciones de tarjeta de control cifrada y una familia completa de API paralela para lentes de doble motor. El flujo de trabajo central son cuatro llamadas: abrir → origen → mover → esperar. Se obtiene un manejador con PMSOptical_OpenComm("COM1", 9600) para serie, o PMSOptical_OpenSocket("192.168.1.200", 4196) para TCP.
Esta guía documenta las familias de funciones, la secuencia de llamadas recomendada y las cuatro restricciones de integración que causan la mayoría de los problemas de primera integración — incluida una que importa para la seguridad de la máquina: el SDK no contiene una parada de emergencia por software utilizable.
Datos clave a simple vista
| Elemento | Valor |
| Funciones exportadas | 44 (24 de motor simple, 20 de doble motor) |
| Plataforma | Windows x64 / x86 (DLL) |
| Conexión | Serie a 9600 baudios, o TCP en el puerto 4196 |
| Tipo de manejador | PMSHANDLE (void*) — verificar siempre si es nulo |
| Secuencia central | Abrir → GoHome → MoveTo(pulse) → WaitForOpticalFinished → GetPos → Cerrar |
| Tiempo de espera predeterminado de la API de espera | 100000 ms (100 s) |
| Funciones no implementadas | 8, incluidas Stop y Stop2 |
| Enlaces de lenguaje | C++ nativo; C# vía P/Invoke; otros lenguajes vía ctypes/cffi (sin enlace oficial) |
Disposición del paquete
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
La DLL debe estar junto al ejecutable o en el PATH del sistema.
Conectar
| Método | Función | Parámetros |
| Serie | PMSOptical_OpenComm(char* comname, int nBaud) | comname como "COM1"; nBaud = 9600 |
| Ethernet | PMSOptical_OpenSocket(char* ip, int nPort) | ip como "192.168.1.200"; nPort = 4196 |
| Consultar estado | PMSOptical_IsOpened(PMSHANDLE, bool&) | — |
| Cerrar | PMSOptical_Close(PMSHANDLE&) | Manejador pasado por referencia |
Para una conexión de red, la PC host y la tarjeta de control del lente deben estar en la misma subred — los primeros tres octetos deben coincidir, por ejemplo 192.168.1.xxx. La máscara de subred se obtiene automáticamente.
#include "PMSOpticalDll.h"
PMSHANDLE h = PMSOptical_OpenComm("COM2", 9600); // serial
// PMSHANDLE h = PMSOptical_OpenSocket("192.168.1.200", 4196); // Ethernet
if (!h) { /* connection failed */ }
Las 44 funciones, por familia
Familia 1 — gestión de conexión (1–4)
| # | Función | Propósito |
| 1 | PMSOptical_OpenSocket(char* ip, int nPort) | Abrir por Ethernet, devolver manejador de dispositivo |
| 2 | PMSOptical_OpenComm(char* comname, int nBaud) | Abrir por serie, devolver manejador de dispositivo |
| 3 | PMSOptical_IsOpened(PMSHANDLE, bool& bIsOpened) | Reportar si el manejador está abierto |
| 4 | PMSOptical_Close(PMSHANDLE&) | Cerrar el manejador |
Las funciones 3 y 4 pasan su resultado y manejador por referencia. Esto es deliberado: la cabecera señala que las firmas se moldearon así para compatibilidad con C# P/Invoke.
Familia 2 — control de motor simple (5–15)
| # | Función | Propósito | Implementada |
| 5 | GoHome(PMSHANDLE) | Regresar al origen | Sí |
| 6 | IsHomed(PMSHANDLE, bool&) | Reportar si el origen está completo | No — marcada no realizada |
| 7 | MoveTo(PMSHANDLE, int nPulse) | Mover a una posición de pulso absoluta | Sí |
| 8 | Stop(PMSHANDLE) | Detener inmediatamente | No — marcada no realizada |
| 9 | JogStart(PMSHANDLE, int nJogSpeed) | Jog (velocidad positiva o negativa) | No — marcada no realizada |
| 10 | JogStop(PMSHANDLE) | Detener el jog | No — marcada no realizada |
| 11 | GetPos(PMSHANDLE, int& nCurPulse) | Leer la posición actual | Sí |
| 12 | GetMaxPos(PMSHANDLE, int& nMaxPulse) | Leer el pulso máximo (recorrido total) | Sí |
| 13 | GetStatus(PMSHANDLE, int& nStatus) | Leer estado de movimiento: 0 en movimiento, 1 detenido, 2 fallo de inicialización | Sí |
| 14 | WaitForOpticalFinished(PMSHANDLE, int nTimeOut = 100000) | Bloquear hasta que termine el movimiento de zoom | Sí |
| 15 | GetVer(PMSHANDLE, char* Ver) | Leer la versión del firmware | Sí |
WaitForOpticalFinished envuelve internamente la lógica de sondeo de estado — sondea la consulta de estado y comprueba el indicador de parada — con un tiempo de espera predeterminado de 100000 ms. En la mayoría de las aplicaciones debe llamarlo en lugar de escribir su propio bucle de sondeo.
Familia 3 — tarjeta de control cifrada (16–24)
Disponible solo cuando el lente está equipado con la tarjeta de control cifrada (indicada por encrypt en el nombre de archivo de la tabla de pulsos).
| # | Función | Propósito |
| 16 | EncryptCommStatus(PMSHANDLE, bool& IsConnected) | Si la tarjeta cifrada está conectada |
| 17 | EncryptReadTimes(PMSHANDLE, int& nTimes) | Leer el contador de ciclos de zoom |
| 18 | EncryptWriteTimes(PMSHANDLE, int nTimes) | Escribir el contador de ciclos de zoom |
| 19 | EncryptAddTimes(PMSHANDLE) | Incrementar el contador de ciclos de zoom |
| 20 | EncryptReadFlashMaxPos(PMSHANDLE, int&) | Leer el pulso máximo almacenado en Flash |
| 21 | EncryptWriteFlashMaxPos(PMSHANDLE, int) | Escribir el pulso máximo en Flash |
| 22 | EncryptCheckHomeStatus(PMSHANDLE, bool& bHasStatus, bool& bNowStatus) | Estado de origen y final de carrera |
| 23 | EncryptReadFlashLensInfo(PMSHANDLE, unsigned char buf[64]) | Leer información del lente (bloque fijo de 64 bytes) |
| 24 | EncryptWriteFlashLensInfo(PMSHANDLE, unsigned char buf[64]) | Escribir información del lente (solo ASCII imprimible) |
Para qué sirve realmente la tarjeta cifrada: almacena el contador de ciclos de zoom y un bloque de identidad del lente de 64 bytes en la Flash del controlador. Eso respalda el seguimiento de activos del equipo, las estadísticas de uso y la identificación de lentes genuinos — directamente útil para integradores de máquinas, flotas de alquiler y operaciones posventa.
Familia 4 — lentes de doble motor (25–44)
Cada función de arriba tiene una versión paralela con un sufijo 2 y un parámetro final unsigned char u8lensnum = 0 que selecciona el motor 1 o el motor 2.
| Motor simple | Doble motor | Propósito |
GoHome | GoHome2(h, u8lensnum) | Llevar el motor seleccionado al origen |
IsHomed | IsHomed2(h, bool&, u8lensnum) | No realizada |
MoveTo | MoveTo2(h, nPulse, u8lensnum) | Mover el motor seleccionado a una posición absoluta |
Stop | Stop2(h, u8lensnum) | No realizada |
JogStart / JogStop | JogStart2 / JogStop2 | No realizada |
GetPos | GetPos2(h, int&, u8lensnum) | Leer la posición |
GetMaxPos | GetMaxPos2(h, int&, u8lensnum) | Leer el recorrido total |
GetStatus | GetStatus2(h, int&, u8lensnum) | Leer el estado |
WaitForOpticalFinished | WaitForOpticalFinished2(h, nTimeOut, u8lensnum) | Esperar la finalización |
GetVer | GetVer2(h, char*, u8lensnum) | Leer la versión del firmware |
Encrypt* (9 funciones) | Encrypt*2(h, …, u8lensnum) | Conjunto completo de tarjeta cifrada |
Los lentes de doble motor emparejan un motor de zoom con un motor de ajuste de enfoque independiente — por ejemplo un lente zoom 12.5X con un ajuste de enfoque motorizado de 12 mm, o un zoom de doble motor 12.5X con un eje de ajuste de 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);
Secuencia de llamadas recomendada
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()
El diagrama de flujo de referencia del fabricante especifica tres reglas para la ruta de sondeo:
- Esperar al menos 50 ms antes de cada consulta de estado.
- Definir un tiempo de espera global — el manual sugiere 10 segundos o más.
- Si el tiempo de espera global expira sin una respuesta válida, declarar un error de conexión del lente y salir limpiamente.
Cuatro restricciones de integración
1. Las comunicaciones se detienen mientras el motor se mueve
Mientras la tarjeta de control acciona el motor, las comunicaciones se suspenden. Una consulta de estado puede no devolver nada en absoluto. Manéjelo con tiempo de espera y reintento, o llamando a WaitForOpticalFinished. No lo trate como un fallo y no reinicie la conexión.
2. Una solicitud de movimiento igual a la posición actual no hace nada
Si el pulso solicitado coincide con el pulso actual, el lente no se mueve y reporta éxito. Nunca use "comando enviado" como prueba de vida del enlace. Use GetMaxPos o GetPos en su lugar.
3. La inicialización al encender tarda 25–35 segundos
Al encenderse el lente se lleva a su origen, y no acepta comandos durante esa ventana. Una aplicación host debe esperar al menos 35 segundos antes de abrir la conexión y emitir comandos. No permitir esto es una causa frecuente de informes de "dispositivo sin respuesta" que en realidad no son fallos.
4. No hay parada de emergencia por software
Stop y Stop2 están ambos marcados como no realizado en la cabecera, junto con IsHomed, JogStart, JogStop y sus equivalentes de doble motor — ocho funciones en total. No diseñe una función de seguridad sobre ellas. Determine la finalización con GetStatus o WaitForOpticalFinished, e implemente la parada de emergencia con un circuito de hardware — un corte de energía o una señal de enclavamiento externa.
Reglas de hardware de las que depende el software
- Conecte y bloquee el cable del motor y el cable RS-232 antes de aplicar energía. Conectarlos en vivo puede dañar el circuito de accionamiento.
- Nunca conecte ni desconecte el cable del motor con energía. Esta es la acción más destructiva en campo y puede dañar permanentemente el motor.
- Si el cable del motor debe superar los 5 m, pida el cable largo de fábrica. No empalme varios cables cortos ni los haga usted mismo.
- Elija serie o Ethernet, nunca ambos. La tarjeta de control admite uno u otro; el modo de conexión del software debe coincidir con el cableado del hardware.
¿Tarjeta de control cifrada o estándar?
| Requisito | Recomendación |
| Solo control de zoom | Tarjeta estándar |
| Conteo de uso, verificación de autenticidad, facturación de alquiler | Tarjeta cifrada (EncryptReadTimes, EncryptReadFlashLensInfo) |
| Flota mixta | Observe que las dos tarjetas usan tablas de pulsos distintas — cambiar la tarjeta implica cambiar la tabla |
Preguntas frecuentes
¿El SDK admite Linux o macOS?
El SDK oficial solo distribuye DLL de Windows (x64 y x86). En otras plataformas, implemente el protocolo serie directamente — son cinco comandos ASCII sin dependencia de plataforma, por lo que funciona en cualquier host con un puerto serie o un socket TCP.
¿Puedo llamar al SDK desde Python?
Sí, vía ctypes o cffi, porque las exportaciones usan enlace C. No hay un enlace oficial de Python, así que usted escribe el contenedor. Observe que PMSHANDLE es un void* y los parámetros bool& deben pasarse con ctypes.byref.
¿Puedo mezclar el SDK y los comandos serie en bruto?
Técnicamente sí, pero no lo haga en el mismo enlace. Ambos acceden a los mismos registros de hardware, y mezclarlos — especialmente alrededor de la referencia de origen — produce un estado inconsistente. Elija un enfoque por proyecto.
¿Qué tiempo de espera debo usar para WaitForOpticalFinished?
El valor predeterminado es 100000 ms. Defínalo al menos al doble del tiempo que tarda el recorrido de zoom más largo en su hardware. La cifra de referencia del manual es 10 segundos o más.
¿Es esta una interfaz de visión artificial con IA?
No, y no debe describirse como tal. El SDK proporciona una interfaz de control óptico programable — posición, estado y lectura de vuelta. Puede integrarse en una arquitectura de visión artificial con IA, donde un software supervisor emite un nuevo comando de aumento basado en un resultado de inspección, pero el SDK en sí no contiene capacidad de IA ni de análisis de imagen. La redacción precisa es que la óptica zoom motorizada puede integrarse en un flujo de trabajo de visión artificial controlado por IA.
¿Hay algún problema conocido en el archivo de cabecera?
Dos que vale la pena conocer. GetVer2 declara su parámetro como u8lennum — un error tipográfico que no afecta la llamada, pero que conviene normalizar en su propio contenedor. Y las ocho funciones no realizadas descritas arriba no deben usarse como base.
Lecturas recomendadas
Productos relacionados