zproto

Module ascii

Source
Available on crate feature ascii only.
Expand description

Types and traits for communicating with Zaber products over Zaber’s ASCII protocol.

§Communicating with Devices

All communication with Zaber products starts with a Port, which can be either a serial or TCP port:

let mut port = Port::open_serial("/dev/ttyUSB0")?;
// OR
let mut port = Port::open_tcp("192.168.0.1:55550")?;

Send a command to and receive a reply from devices/axes connected to that port with the command_reply method. A command can be created from most standard types that are effectively bytes, such as &str, String, or &[u8]:

// Send `/get device.id` and receive a reply
let reply = port.command_reply("get device.id")?;

To target a specific device and/or axis prepend the target to the command data as part of a tuple, (target, data):

// Send `/2 get device.id` and receive a reply
let reply = port.command_reply((2, "get device.id"))?;

The target can be:

  • the device address: (2, "home")
  • the device address and axis number as a tuple: ((2, 1), "home")
  • a Target type: (Target::for_device(2).with_axis(1), "home")

As a convenience that reduces the number of nested parentheses, the command tuple can also have the form (device, axis, data):

// Send `/2 1 get pos` and receive a reply
let reply = port.command_reply((2, 1, "get pos"))?;

§Checking Responses

The library requires users to be explicit about checking the contents of responses. To do this, many methods either take a validation function or return a NotChecked<R> (where R is the response type, like a Reply). To access the inner response, users must validate it’s contents using the methods on NotChecked and/or the validation functions in the check module. If you want you can also write your own validation functions.

use zproto::ascii::response::check::warning_is;

let reply = port.command_reply((1, "get device.id"))?
    .flag_ok_and(warning_is("WR"))?; // check that the reply's flag is "OK"
                                     // and the warning flag is "WR".

§Reading Data

Reading data from a response is as simple as calling data() on the response and then using Rust’s standard parse() method to convert the string to your desired data type.

let reply = port.command_reply("get device.id")?.flag_ok()?;
let device_id: u32 = reply.data().parse()?;

§Other Port Methods

The Port has many other helpful methods for receiving any type and number of responses: Replys, Infos, and Alerts. For instance, to read an Alert use the response method:

let alert: Alert = port.response()?.check_minimal()?;

Or to read the reply and info messages sent in response to a command use the command_reply_infos method:

use zproto::ascii::response::check::minimal;
let (reply, infos) = port.command_reply_infos("stream buffer 1 print", minimal())?;
println!("{reply}");  // `@01 0 OK IDLE -- 0` (for example)
for info in infos {
    println!("{info}"); // `#01 0 setup store 1 1` (for example)
}

It also provides convenience functions for other common tasks, like waiting until a specific target is IDLE:

use zproto::ascii::response::check::flag_ok;
let target = (1, 2);
port.command_reply((target, "move max"))?.flag_ok()?;
port.poll_until_idle(target, flag_ok())?;
// Axis 2 on device 1 is now idle

§Sending a Port between threads

By default a Port does not implement Send, so cannot be sent to another thread. If you’re application requires this, use the Port::try_into_send method to convert it to one that can be. Doing so places Send bounds on any packet or unexpected alert handlers.

let sendable_port = Port::open_serial("...")?.try_into_send()?;

Re-exports§

Modules§

  • Types and traits for generating ASCII commands.
  • Types for parsing ASCII packets from bytes.
  • Types for opening and using a serial port with the ASCII protocol.
  • Types and traits related to ASCII response messages.