Python interface to Xeryon precision piezo stages, over USB serial or over a serial-to-Ethernet terminal server.
Xeryon.py is the manufacturer's library, vendored with a handful of documented changes; see
VENDOR_PATCHES.md. XeryonController wraps it in the
hardware_device_base interface the other COO drivers implement, and is what applications should
use.
- Python 3.8+
pyserial,hardware_device_base- A Xeryon XD-C, XD-M or XD-OEM controller
from xeryon import Stage, XeryonController
controller = XeryonController(settings_file="config/settings_FEI_XD24494_20250828.txt")
# Declare every axis the controller has, wired or not: the library matches
# replies to axes by their position in this list
controller.add_axis("A", Stage.XLS_5_3N, units="mm")
controller.add_axis("B", Stage.XLS_5_3N, units="mm")
controller.add_axis("C", Stage.XLS_5_3N, units="mm")
controller.connect(host="192.168.29.100", port=10001) # or com_port="/dev/ttyACM0"
controller.close_loop("A")
controller.home("A") # searches the encoder index
controller.set_pos(1.5, "A") # returns as soon as the move is commanded
while controller.is_moving("A"):
pass
print(controller.get_pos("A"))
controller.disconnect()Motion calls return once the command is queued. Pass blocking=True to home() or set_pos()
to wait for completion instead, and flush_commands() to wait for a queued command to reach the
controller without waiting for the motion it starts.
connect() defaults to leaving the controller as it found it:
do_reset=Falseskips the axis reset. A reset invalidates the encoder index, so resetting on every connect would cost a referenced stage its reference.send_settings=Falseloads the settings file into the library (which needs it for unit conversion and travel limits) without pushing it to a controller that already has those settings in flash.
Pass either as True to get the manufacturer's behavior back.
Each controller needs its own settings file, as generated by the Xeryon Windows interface; see
config/. Lines are TAG=value, prefixed with the axis letter on multi-axis
controllers, and % starts a comment:
A:LLIM=-25
A:HLIM=25
A:SSPD=5
POLI=97get_limits() reports LLIM/HLIM from this file, since the controller only echoes them back
when echo is enabled.
The library logs through the standard logging module, under the xeryon.Xeryon logger;
XeryonController logs under hardware_device_base's configuration. Nothing is printed.
python -m pytestThe tests run against a fake controller port, so no hardware is needed.