The following complete example demonstrates the basic usage of the library.
Running the program will make your Zaber device move.
Before running the code, replace the placeholder port name with the name of your port (for example COM2).
If you are uncertain about the name, see our guide to finding the right port.
Python
C#
C++
JavaScript
MATLAB
Java
Swift
Octave
MATLAB (legacy)
from zaber_motion import Units
from zaber_motion.asciiimport Connection
with Connection.open_serial_port("COM3") as connection:
connection.enable_alerts()
device_list = connection.detect_devices()
print("Found {} devices".format(len(device_list)))
device = device_list[0]
axis = device.get_axis(1)
ifnot axis.is_homed():
axis.home()
# Move to 10mm
axis.move_absolute(10, Units.LENGTH_MILLIMETRES)
# Move by an additional 5mm
axis.move_relative(5, Units.LENGTH_MILLIMETRES)
using System;
using Zaber.Motion;
using Zaber.Motion.Ascii;
namespacecsharp
{
classProgram
{
staticvoidMain(string[] args)
{
using (var connection = Connection.OpenSerialPort("COM3")) {
connection.EnableAlerts();
var deviceList = connection.DetectDevices();
Console.WriteLine($"Found {deviceList.Length} devices.");
var device = deviceList[0];
var axis = device.GetAxis(1);
if (!axis.IsHomed())
{
axis.Home();
}
// Move to 10mm
axis.MoveAbsolute(10, Units.Length_Millimetres);
// Move by an additional 5mm
axis.MoveRelative(5, Units.Length_Millimetres);
}
}
}
}
const { Length, ascii: { Connection } } = require('@zaber/motion');
asyncfunctionmain() {
const connection = awaitConnection.openSerialPort('COM3');
try {
await connection.enableAlerts();
const deviceList = await connection.detectDevices();
console.log(`Found ${deviceList.length} devices.`);
const device = deviceList[0];
const axis = device.getAxis(1);
if (!await axis.isHomed()) {
await axis.home();
}
// Move to 10mmawait axis.moveAbsolute(10, Length.mm);
// Move by an additional 5mmawait axis.moveRelative(5, Length.mm);
} finally {
// close the port to allow Node.js to exitawait connection.close();
}
}
main();
let connection =tryawaitConnection.openSerialPort(
portName: "/dev/tty.usbserial-A4017DXH"
)
tryawait connection.enableAlerts()
// ...
• Drag to pan • Ctrl + Scroll to zoom
The first step towards communicating with the device is opening a connection.
In the example we create a connection by opening a serial port but the library supports other ways such as TCP.
If you encounter a problem at this step, head to the Troubleshooting section below.
The code also demonstrates use of a try-catch statement to ensure that the serial port closes in case of an exception.
Calling the
enableAlerts
method allows devices to communicate back without preceding requests.
This allows more timely detection of the end of movement when using ZML.
If you are planning to implement your own low-level communication (e.g. using Arduino),
alert handling may increase the complexity of your implementation.
Additionally, some of Zaber's legacy software may not be able to handle alerts.
In such cases, you can omit this line or later set comm.alert setting back to 0.
Detecting devices
Calling the
detectDevices
method searches the connection for all the present devices and performs their identification.
let deviceList =tryawait connection.detectDevices()
print("Found \(deviceList.count) devices.")
• Drag to pan • Ctrl + Scroll to zoom
During the identification, the library connects to the internet to retrieve information about Zaber devices.
No personal or identifying information is exchanged with Zaber servers.
The library stores all the information in the operating system cache folder to later allow for offline use.
For more information about the behaviour see Device Database.
Homing the Device
After detecting the devices, we pick the first device from the list and make sure it's homed.
let device = deviceList[0]
let axis =try device.getAxis(axisNumber: 1)
if!(tryawait axis.isHomed()) {
tryawait axis.home()
}
• Drag to pan • Ctrl + Scroll to zoom
Homing a device moves it so that it finds a reference position.
A reference position is necessary in order to perform accurate absolute position movements.
The device retains the reference position until it's powered off, so repeated homing is unnecessary as long as power is maintained.
Note that homing is performed using the
axis
object rather than the
device
object.
Some devices have multiple axes, so the
Axis
class allows control of a specific axis on the device.
Axes are indexed from 1. Therefore the code above homes the first axis of the device.
Moving the Device
Once homed, we can start moving the device by calling
moveAbsolute
and
moveRelative
methods.
Python
C#
C++
JavaScript
MATLAB
Java
Swift
Octave
MATLAB (legacy)
# Move to 10mm
axis.move_absolute(10, Units.LENGTH_MILLIMETRES)
# Move by an additional 5mm
axis.move_relative(5, Units.LENGTH_MILLIMETRES)
// Move to 10mm
axis.MoveAbsolute(10, Units.Length_Millimetres);
// Move by an additional 5mm
axis.MoveRelative(5, Units.Length_Millimetres);
// Move to 10mmawait axis.moveAbsolute(10, Length.mm);
// Move by an additional 5mmawait axis.moveRelative(5, Length.mm);
// Move to 10mm
axis.moveAbsolute(10, Units.LENGTH_MILLIMETRES);
// Move by an additional 5mm
axis.moveRelative(5, Units.LENGTH_MILLIMETRES);
% Move to 10mm
axis.moveAbsolute(10, Units.LENGTH_MILLIMETRES);
% Move by an additional 5mm
axis.moveRelative(5, Units.LENGTH_MILLIMETRES);
% Move to 10mm
axis.moveAbsolute(10, Units.LengthMillimetres);
% Move by an additional 5mm
axis.moveRelative(5, Units.LengthMillimetres);
% Move to 10mm
axis.moveAbsolute(10, LENGTH_MILLIMETRES);
% Move by an additional 5mm
axis.moveRelative(5, LENGTH_MILLIMETRES);
// Move to 10mm
axis.moveAbsolute(10, Units::LENGTH_MILLIMETRES);
// Move by an additional 5mm
axis.moveRelative(5, Units::LENGTH_MILLIMETRES);
// Move to 10mmtryawait axis.moveAbsolute(position: 10, unit: Units.Length.mm)
// Move by additional 5mmtryawait axis.moveRelative(position: 10, unit: Units.Length.mm)
• Drag to pan • Ctrl + Scroll to zoom
At a low level, the devices operate in native units related to their drive type, such as microsteps for a stepper driver or encoder counts for a direct drive device. The library allows you to specify real-world units like millimetres, and handles the conversion to the specific native units. Use native units directly by omitting the second argument in the move methods, or by specifying the units to be native. To read more about native units refer, to the ASCII Protocol manual.
The above movements will execute one after the other, with the program waiting for the movement to finish before continuing. This behaviour can be controlled by including a third argument in the move method, with a boolean false indicating that the method should not wait.
If you have a rotary device use Units.AngleDegrees in the code above.
Troubleshooting
Connection Failed Exception
Ensure that you have specified the correct serial port name.
Check also that other applications, such as Zaber Console, do not have the port open by either selecting Close or exiting the application.
Using the Zaber Launcher application does not cause a conflict over the serial port.
No Device Found Exception
Check that the device is connected correctly and powered on.
Also ensure that you have specified the correct serial port name.
You can use the Zaber Launcher application to verify communication with the devices.
Device Address Conflict Exception
If you encounter
DeviceAddressConflictException
,
open the port in the Zaber Launcher application which will automatically reassign unique addresses to your devices.
Project Download
Additionally, we provide a download link to a complete project for each programming language.