The Zaber Serial Library in Python

Introduction

The Zaber Serial Library is a small Python library for communicating with Zaber devices over a serial port. It is built on top of PySerial.

The library is tested with Python 2.7 and 3.5. It is released under the Apache License.

Deprecation Notice

Development of this library is being discontinued in favor of the new Zaber Motion Library (for the ASCII Protocol, or for the Binary Protocol), which provides more features and more robust protocol handling.

Note however that the Zaber Motion Library does not support Python 2; if you cannot update to Python 3, you should use this Zaber Core Serial Library.

Zaber will still support existing users of the Zaber Core Serial Libraries, but no new feature development is planned.

Installation

The Zaber Serial Library can be installed from the Python Package Index using pip:

pip install zaber.serial

Once the installation finishes, you can use the library by importing it in any Python file:

import zaber.serial

Or directly import just the classes you want:

from zaber.serial import AsciiSerial, AsciiDevice, AsciiCommand

Known Issues

  • AsciiSerial and BinarySerial constructors may fail when used with pyserial versions later than 2.7, because of this bug, which looks like it may be fixed in the next release after 3.0.1. Until then if you encounter this problem we recommend manually installing pyserial 2.7:

    pip uninstall pyserial
    pip install pyserial==2.7
    
  • Class names are accessible via more paths than intended, and the documentation is confusing about whether the library contains one module or three. It is intended to appear as one module; class names live under zaber.serial, not zaber.serial.ascii etc.

  • The command “help(zaber.serial)” produces incorrect output.

Release Notes

v0.9.1:
  • Deprecated the library.

v0.9:
  • Fixed an error in the documentation about how BinaryDevice.send() handles message IDs.

  • The thread safety introduced in v0.8.3 has been made finer-grained, in that there are now separate locks for port reads and writes.

  • Fixed an ambiguity about whether the AsciiReply constructor accepts bytes objects. It doesn’t.

  • Added lockstep support in ASCII. AsciiDevice.lockstep() will return a lockstep axis object which can be used to move all axes together on a multi-axis controller such as the X-MCB2. Calling disable() on that object will return the controller to normal mode.

  • Verified that the library is compatible with current versions of Firmware 7.

  • Non-breaking refactor for maintainability: the ASCII helper functions (move, home etc) are now in a mixin class rather than being duplicated.

  • Known issue: There are multiple ways to qualify class names, and some of them changed in 0.8.3 due to code reorganization. It may change again in a future release. For now we recommend using the shortest names, as shown in the documentation. For example, use “zaber.serial.AsciiSerial” in preference to “zaber.serial.ascii.AsciiSerial” or “zaber.serial.asciidevice.AsciiDevice”.

v0.8.3:
  • Port access is now thread-safe; overlapping send operations on the same port are mutually exclusive.

  • Added get_position() helper methods to AsciiAxis, AsciiDevice and BinaryDevice. These methods return the current position of the device in its native units.

  • Added can_read() methods to the AsciiSerial and BinarySerial classes, as a convenient way to check if there is response data to be read.

  • BinaryDevice.send() will now throw an exception if message IDs are in use and the reply ID does not match the command ID. This matches the ASCII behavior.

  • Fixed ASCII reply parsing removing whitespace from data payload.

  • Changed default inter-byte timeout to 0.5ms based on recommendations from users.

  • Updated documentation to mention that the AsciiSerial and BinarySerial classes are compatible with Python’s “with” statement.

  • Split up the monolithic source files into one file per class, for easier maintenance and code browsing.

  • Fixed the tests not working under Windows due to a dependency on a Unix-only package.

v0.8.1:
  • Fixed a Python 3 specific problem with passing strings to BinarySerial.write()

v0.8:
  • Fixed AsciiReply failure to correctly parse some valid ASCII info messages.

  • Allow passing URLs as well as port names to the AsciiSerial and BinarySerial constructors.

  • Made API documentation link more prominent in help landing page.

  • Added a Change Log section to README and help landing page.

  • Fixed help landing page link for PySerial to point to current version.

  • Clarified which TimeoutError implementation can be thrown by the serial port classes’ read methods - it’s zaber.serial.TimeoutError and not either of the builtin ones.

  • Added a type check to the AsciiSerial constructor to make sure the port argument is a string. The BinarySerial constructor already had the same.

  • Exposed inter-character timeout via optional arguments to the AsciiSerial and BinarySerial constructors. This allows increasing the timeout to avoid spurious errors on overloaded computers.

  • Set the AsciiReply.reply_flag attribute to None in the cases of info and alert messages. It wasn’t being defined at all before, which was inconsistent.

  • Added debug-level logging of receive timeouts.

  • BinaryDevice.send() will now return replies with message IDs if the commands passed in have message IDs.

  • BinaryReply will now sign-extend 24 bits of data to 32 bits if message IDs are enabled. This will still produce incorrect data if the actual value requires more than 24 bits, but it will now correctly handle negative numbers that fit in 24 bits.

  • BinarySerial.write() will now work if passed a string, as indicated by its documentation.

  • Added flush() methods to the AsciiSerial and BinarySerial classes. These just call the flush() method of the underlying serial ports.

  • Added more complete example scripts to the online documentation.

v0.7:
  • Fixed AsciiReply raising StopIterationError instead of ValueError when parsing incomplete strings.

  • Fixed AsciiReply incorrectly rejecting single digit checksums.

v0.6:
  • Added message logging.

  • Fixed a bytes vs. string issue in Python 3.

  • Added module index to documentation.

v0.5:
  • Assorted documentation and packaging improvements.

up to v0.4: Initial internal development.

Indices and tables