Motorized Zoom Lens RS-232 Serial Protocol: Complete Command Reference and Position Formulas

POMEAS motorized zoom lenses are controlled over RS-232 (or Ethernet) with a compact ASCII protocol of five commands. Every command is three bytes: the letter X, a command letter, and a carriage return 0x0D. The controller answers position and travel queries with a nine-byte frame, and reports motion completion with the single status byte 0x55. This reference documents the protocol exactly as implemented, including the two conversion formulas and the behaviour that most often surprises integrators: the controller stops answering while the motor is moving.

It is written for engineers who are connecting a motorized zoom lens to a PLC, a motion controller, a single-board computer, or a Linux host — situations where the Windows SDK is not available and the raw byte stream is the only option.

Key facts at a glance

ItemValue
Commands5 (XH, XG, XZ, XM, XN)
Frame terminator0x0D (CR) — on both commands and replies
Serial configuration9600 baud, 8 data bits, no parity
Ethernet port4196
Stop indicator0x55 — any other value, or a read timeout, means "still moving"
Travel formulamaxLength = (readData − 750) × 1.3
Position formulapos = (readData − 500) × 1.3
Polling guidanceWait at least 50 ms between status calls; use an overall timeout of 10 s or more

Port settings and wiring prerequisites

ParameterValueNotes
Physical layerRS-232 (direct or via USB-to-RS-232) or EthernetThe controller supports one or the other — not both at the same time
Baud rate9600The protocol document and the control-card API documentation agree on this value
Data bits8—
ParityNone—
TCP port4196Used when connecting over the network interface
Terminator0x0DBoth directions

Before any of this matters, the wiring has to be correct: connect and lock the motor cable and the RS-232 cable before applying power. Hot-plugging the motor cable while the controller is powered is the single most damaging action in the field — it can permanently damage the motor. If your motor cable needs to run more than 5 m, order the factory long cable rather than splicing several short ones, because spliced or self-made cables do not meet the impedance and shielding requirements.

The five commands

Every command has the form 'X' + <command letter> + 0x0D.

#FunctionASCIIHEXReply
1Return to origin (home)X H CR0x58 0x48 0x0DNone
2Move to a target pulse positionX G + 6 HEX digits + CR0x58 0x47 … 0x0DNone
3Query motion statusX Z CR0x58 0x5A 0x0D1 byte
4Read total travel (maximum pulse)X M CR0x58 0x4D 0x0D9 bytes
5Read current positionX N CR0x58 0x4E 0x0D9 bytes

1. Return to origin — XH

TX:  0x58 0x48 0x0D          # 'X' 'H' CR

The lens returns to its mechanical origin. Note that the lens also performs this reset automatically every time it is powered on, and the initialisation takes 25–35 seconds, during which the lens accepts no commands at all. A host application should therefore wait at least 35 seconds after power-up before opening the port.

2. Move to a target position — XG

The payload is formatted with the C format string "%C%C%6X%C": the letter X, the letter G, a six-digit hexadecimal number padded on the left with space characters (0x20) when it is shorter than six digits, and a terminating 0x0D.

Target pulseASCII charactersByte sequence
100X G ␠␠␠␠ 6 4 CR0x58 0x47 0x20 0x20 0x20 0x20 0x36 0x34 0x0D
1000X G ␠␠␠ 3 E 8 CR0x58 0x47 0x20 0x20 0x20 0x33 0x45 0x38 0x0D
5000X G ␠␠ 1 3 8 8 CR0x58 0x47 0x20 0x20 0x31 0x33 0x38 0x38 0x0D
10000X G ␠␠ 2 7 1 0 CR0x58 0x47 0x20 0x20 0x32 0x37 0x31 0x30 0x0D

Important behaviour: if the requested position equals the current position, the lens does not move and reports no error. A host application must therefore never treat "command sent" as proof that the link is working. Reading the position back is the reliable link probe.

// Move to an absolute pulse position
int moveTo(int fd, long pulse) {
    char buf[16];
    // "%C%C%6X%C" - six hex digits, space-padded, CR-terminated
    int n = snprintf(buf, sizeof(buf), "%c%c%6lX%c", 'X', 'G', pulse, '\r');
    return write(fd, buf, n) == n ? 0 : -1;
}

3. Query motion status — XZ

TX:  0x58 0x5A 0x0D
wait 20 ms
RX:  1 byte
ReplyMeaning
0x55Motion finished — lens has stopped
Any other valueStill moving
No data at allAlso treated as "still moving"

This is the most important behavioural detail in the whole protocol, and it is documented by the manufacturer: while the control card is driving the motor, communications are suspended. The serial or network link may return nothing at all during a zoom movement.

The practical consequence is that the polling loop must be built around retries rather than around failure detection. The reference implementation is:

  1. Send XZ.
  2. Wait at least 20 ms.
  3. Read one byte.
  4. If the read times out, or the byte is not 0x55, wait and retry — do not declare a fault.

The manufacturer's own API flow chart uses a 50 ms wait before each status call and an overall timeout of 10 seconds or more. Only when that overall timeout expires without a valid reply should the host conclude that the lens connection has failed.

// Wait for motion to complete: 50 ms per poll, 10 s overall timeout
int waitStop(int fd, int timeout_ms) {
    int waited = 0;
    char c;
    while (waited < timeout_ms) {
        usleep(50 * 1000);              // reference flow chart: wait 50 ms or more
        write(fd, "XZ\r", 3);           // 0x58 0x5A 0x0D
        usleep(20 * 1000);              // protocol: wait 20 ms before reading
        if (read(fd, &c, 1) == 1 && (unsigned char)c == 0x55)
            return 0;                   // stopped
        waited += 70;
    }
    return -1;                          // connection or motion fault
}

4. Read total travel — XM

TX:  0x58 0x4D 0x0D
wait 20 ms
RX:  9 bytes
ByteContent
10x58 (fixed)
2empty
3–7Travel data — five bytes, parsed as an integer with "%5X" into readData
80x0D
9empty
sscanf(tbuffer + 2, "%5X", &readData);
maxLength = (readData - 750) * 1.3;

Worked example from the manufacturer's documentation: a reply of 0x58 -- -- -- '2' '7' '1' '0' 0x0D -- gives readData = 10000, so maxLength = (10000 − 750) × 1.3 = 12025.

5. Read current position — XN

TX:  0x58 0x4E 0x0D
wait 20 ms
RX:  9 bytes   (identical structure to XM)
sscanf(tbuffer + 2, "%5X", &readData);
pos = (readData - 500) * 1.3;

Worked example: readData = 10000 gives pos = (10000 − 500) × 1.3 = 12350.

Reference interaction sequence

(1)  XH            return to origin        -> poll XZ until stopped
(2)  XM            read total travel        -> validates the link, yields maxLength
(3)  XG <6 HEX>    move to target position  -> poll XZ until stopped
(4)  XN            read current position     -> compare with the target (closed loop)

Two points make this sequence work reliably:

  • Step 2 is the only dependable link probe. Step 3 cannot be used for that purpose, because a move request equal to the current position produces no motion and no error.
  • Step 4 closes the loop. Only when the read-back value matches the requested value can the host be confident that the magnification change actually took effect.

The whole protocol is strictly serial in semantics — command → motion → status read-back → next command. It does not support issuing commands concurrently to the same lens.

This protocol provides position read-back only. It does not define or guarantee a repeatability figure. Testing methodology is covered in the companion article on magnification and pulse mapping; any numeric accuracy claim should come from your own measurements under your own conditions.

Common misconceptions

"RS-232 motorized zoom lens" means one thing

It means two very different things, and choosing the wrong model is a common and expensive mistake.

FormModel markingActual capability
Passive magnification feedbackSuffix DS9 or DS6, e.g. PMS-LZ-63100DS9Zoom is still manual. RS-232 only outputs the current magnification or detent position. It cannot accept commands.
Active motorized controlZoom-type code 04, 05, 09 or 10, e.g. PMS-LZ-650104All five commands are accepted. RS-232 actively drives magnification.

Check the model suffix before ordering. A DS9 lens can be read but not commanded.

"Communications dropped out during the zoom — the link is broken"

Not a fault. The control card suspends communications while it drives the motor. This is designed behaviour. Handle it with timeout-and-retry, not with a fault alarm or a restart.

"Sending a command always produces motion"

If the target equals the current position, the lens stays still and silently succeeds. Either track the current position in the host application, or read it back with XN before each move.

"Any position value can be commanded"

Pulse positions are lens-specific. They come from the per-model pulse table supplied with the SDK, and the same magnification maps to different pulse counts on different models and different motor types. Read the total travel with XM first and confirm that the target lies inside the valid range.

Raw serial commands or the SDK?

Protocol commandLegacy SDK APISDK V4.4.7
XH homeMoveHome(Motor)GoHome
XG moveMoveGoto(Motor, long dest)MoveTo(pulse)
XZ statusMoveStatus(Motor) → 0 moving / 1 idle / 2 errorGetStatus
XM travelMoveMaxLength(Motor)GetMaxPos
XN positionMovePos(Motor)GetPos
  • Integrating with a PLC, motion controller or microcontroller — use the raw commands above. No DLL is required, and the protocol is pure ASCII with no platform dependency, so it also works on Linux and macOS.
  • Developing on Windows in C++ or C# — use the SDK, which handles frame assembly, retries and the dual-motor case for you.

Do not mix the two approaches on the same link. They address the same hardware registers, and mixing them — particularly around the homing reference — produces inconsistent state.

Frequently asked questions

What baud rate do POMEAS motorized zoom lenses use?

9600 baud, 8 data bits, no parity. The Ethernet option uses TCP port 4196.

Why can't I read anything from the lens while it is zooming?

Because the control card deliberately suspends communications while it drives the motor. Retry your status query with a timeout instead of treating the silence as a failure.

How do I tell whether a lens supports active RS-232 control?

Check the zoom-type code in the model number. Codes 04, 05, 09 and 10 denote motorized types. A DS9 or DS6 suffix denotes passive feedback only, where zoom remains manual.

Can I connect the lens directly to a PLC?

Yes. The command set is five ASCII strings, so a PLC with a free serial port can format and send them directly. The PLC-side program is yours to write; POMEAS supplies the protocol definition, not a PLC function block.

Do I need the DLL to control the lens?

No. The DLL is a Windows convenience layer over the same byte-level protocol. Any platform that can open a serial port or TCP socket can control the lens.

Related reading

Product pages for motorized zoom lenses

Related reading

Real integration example: Motorized zoom lens equipment integration: WD, mechanical length and parfocality verified - a documented automation case, not a product spec sheet.

Go Back Top
VK Message
WhatsApp

Scan QR Code

WhatsApp QR Code
Wechat

Scan QR Code

Wechat
Phone Number
+8618598102007
Copied!
Online Message

Online Message

Click to refresh