Core Serial Library in C#  1.3.0.102
Examples

Table of Contents

Here can be found a collection of short examples of the intended usage of the library. The examples are divided by protocol, with a few examples of switching between protocols to be found at the end of the page.

ASCII

Homing a Single Device

When a Zaber device is first powered-on, it does not know its position and must be sent to find its "home" sensor. This is done using the "home" command.

This example opens a serial port named "COM1", creates a ZaberAsciiAxis to represent the first axis of the first device connected, homes the axis, and then closes the port.

var port = new ZaberAsciiPort("COM1");
port.Open();
var axis = new ZaberAsciiAxis(port, 1, 1);
axis.Home();
port.Close();

Getting the Position of a Device

Classes implementing IZaberAxis (ZaberAsciiAxis and ZaberBinaryDevice) have a method for querying the position of a device.

This example creates a ZaberAsciiAxis to model axis 1 of device 1, gets its position, then moves it 1000 microsteps farther forward using MoveAbsolute(). This emulates the behaviour of the MoveRelative() method.

var axis = new ZaberAsciiAxis(port, 1, 1);
var position = axis.GetCurrentPosition();
axis.MoveAbsolute(position + 1000);

Controlling Two Devices

The ZaberAsciiAxis class provides several helpful methods for sending common commands to Zaber devices. These commands are used mostly to move the device.

This example moves two devices through a series of coordinates using the two most common "move" commands, MoveAbsolute and MoveRelative.

var axis1 = new ZaberAsciiAxis(port, 1, 1); // device 1, axis 1
var axis2 = new ZaberAsciiAxis(port, 2, 1); // device 2, axis 1
// Move to (100, 200).
axis1.MoveAbsolute(100);
axis2.MoveAbsolute(200);
// Move to (200, 400).
axis1.MoveRelative(100);
axis2.MoveRelative(200);
// Move to (300, 300).
axis1.MoveAbsolute(300);
axis2.MoveRelative(-100);

Controlling Two Devices at the Same Time

ZaberAsciiAxis waits for an axis to complete a command before continuing execution. Because of this, it is limited to moving just one axis at a time. Sending multiple commands to devices asynchronously requires you to use the ZaberAsciiPort class directly. This requires a certain amount of discipline, as it means you must manually read and handle replies from devices, and ensure the contents of the input buffer remain in a known state.

This example uses ZaberAsciiPort.Write() and ZaberAsciiPort.Read() to send and receive messages to a two-axis device like the ASR. It refers to axis 1 of the device as X, and axis 2 as Y.

This example will be given twice: first, in a way that models the entire set-up of devices using ZaberAsciiAxis objects and their properties, creating AsciiCommand objects to represent commands to be sent to devices, and receiving AsciiReply objects from the library when reading replies. The example will then be written a second time in a more minimal way which sacrifices code clarity for shorter code.

var xAxis = new ZaberAsciiAxis(port, 1, 1);
var yAxis = new ZaberAsciiAxis(port, 1, 2);
// Move X axis to position 1000.
var moveXCommand = new AsciiCommand(xAxis.ParentAddress, xAxis.Number, "move abs 1000");
// Move Y axis to position 2000.
var MoveYCommand = new AsciiCommand(yAxis.ParentAddress, yAxis.Number, "move abs 2000");
// Send the commands to the devices, without waiting for a response.
port.Write(moveXCommand);
port.Write(moveYCommand);
// Read the replies to get them out of the input buffer.
port.Read();
port.Read();

This second example writes strings directly to the serial port, eschewing all unnecessary objects in favour of hard-coded values.

// Send the same commands as above.
port.Write("/1 1 move abs 1000\r\n");
port.Write("/1 2 move abs 2000\r\n");
// We should still read the replies out of the input buffer.
port.Read();
port.Read();

Both of these samples accomplish an identical task, and in different circumstances each one is more appropriate than the other. This library provides the extra layers of abstraction with larger, more complex programs in mind, while still providing support for directly writing strings to the serial port for smaller scripting applications.

Finding Axes Connected to a Port

Detection of devices on a serial port is supported directly by the library in the ZaberAsciiPort.FindAxes() method. It sends a global command to the serial port, and then listens for responses for a short period of time. FindAxes returns a list of connected axes.

This example finds and homes all axes connected to the port "COM1".

var port = new ZaberAsciiPort("COM1");
port.Open();
foreach (ZaberAsciiAxis axis in port.FindAxes())
{
axis.Home();
}
port.Close();

Binary

The ZaberBinaryDevice Class

Both ZaberAsciiAxis and ZaberBinaryDevice implement IZaberAxis. Zaber's Binary Protocol treats every axis as a separate device. This library follows this quirk in Binary, and so ZaberBinaryDevice implements IZaberAxis.

This example creates a ZaberBinaryPort and two ZaberBinaryDevice objects numbered 1 and 2, and then instructs both of the devices to move to position 1000.

var port = new ZaberBinaryPort("COM1");
port.Open();
var device1 = new ZaberBinaryDevice(port, 1);
var device2 = new ZaberBinaryDevice(port, 2);
device1.MoveAbsolute(1000);
device2.MoveAbsolute(1000);
port.Close();

Moving Axes at a Specified Velocity

IZaberAxis defines a MoveVelocity method, which behaves a little differently than MoveAbsolute and MoveRelative. MoveVelocity returns immediately, leaving the device moving while program execution continues. To help with this, Stop and PollUntilIdle methods are also provided.

This example demonstrates sending a device moving backwards at a certain rate, waiting two seconds, stopping it again, then sending it forward at a faster rate and waiting until it gets to the end of its length of travel and reports itself as idle.

var device = new ZaberBinaryDevice(port, 1);
device.MoveVelocity(-100); // Move backwards slowly.
System.Threading.Thread.Sleep(2000); // Wait two seconds.
device.Stop();
device.MoveVelocity(1000); // Move forwards faster.
device.PollUntilIdle(); // Wait until the device is done.

Using ZaberBinaryPort

As mentioned in the ASCII examples, classes implementing IZaberAxis can only move one axis at a time, blocking until movement is complete. This means that to move more than one device simultaneously, you will need to use ZaberBinaryPort to send your own BinaryCommand objects, and receive BinaryReply objects from the device.

This example sends two devices, numbered 1 and 2, to position 3000. The binary protocol specifies that a device should only reply once a movement has completed* rather than replying immediately when the command has been received like in the ASCII protocol.

This examples assumes the devices are connected to COM1.

var port = new ZaberBinaryPort("COM1");
port.Open();
// Device 1, command 20 (Move Absolute), position 3000.
var moveAxis1 = new BinaryCommand(1, 20, 3000);
var moveAxis2 = new BinaryCommand(2, 20, 3000); // Same as above, but to device 2.
port.Write(moveAxis1);
port.Write(moveAxis2);
// NB: The devices will only respond once they get to their destinations.
// These calls to Read() will block until the devices get there.
port.Read();
port.Read();
port.Close();

Switching to ASCII

Most A-Series Zaber devices are capable of communicating in ASCII, but default to binary. It is a common operation to want to switch a device or set of devices to ASCII from binary. Command 124 will switch a binary device to ASCII. The data field of command 124 should be the desired ASCII baud rate. The recommended baud rate for ASCII is 115200.

When changing the protocol of Zaber devices, you should always change every device connected to a serial port to the same protocol at the same time. Commands sent in one protocol at one baud rate can easily be misinterpreted as valid commands in another protocol at another baud rate. For example, a single null byte (a byte with value 0) sent at 9600 will be interpreted as 12 bytes, all with value 0, at a baud rate of 115200. This could be disastrous, as a string of 6 consecutive 0 bytes is interpreted in binary as a Reset command, sent to all devices!

This example sends a "Convert to ASCII" command to all binary devices connected to COM1, then closes the port. After doing this, the port should be re-opened using a ZaberAsciiPort object to reflect the change in protocol.

var port = new ZaberBinaryPort("COM1");
port.Open();
// Change *all* devices (device number 0) to ASCII, baud 115200.
var changeProtocolCommand = new BinaryCommand(0, 124, 115200);
port.Write(changeProtocolCommand);
port.Close();