Controller Feature: Scope
By Stephen Hunt, Firmware Team
Published on Nov. 08, 2022
There are many situations in which it is helpful to capture the value of one or more device settings in real-time. For instance, in some high-precision applications it may be useful to track how closely a device is following its planned trajectory. In situations like this, repeatedly querying the value of a setting is insufficient; the communication overhead adds unnecessary delays and makes it hard to know precisely when the setting had a particular value. Zaber's scope feature is designed to assist with this. Read on to understand more about how to precisely sample a setting's value at high-frequency and easily process it.
Note that the information below assumes some basic understanding of Zaber products and how they are connected and controlled from a computer. If you're not familiar with this you may want to review our Quick Setup Guide first.
Capturing data by polling
The simplest way to monitor a setting's value over time is to repeatedly query the device for the setting's value with the get command. This is known as "polling" the device. However, polling has some limitations. First, multiple settings cannot be polled at the same time; separate get
commands must be sent for each setting. This means that the effective polling frequency for each setting is reduced with every additional polled setting and that it is not possible to compare the value of two settings at any particular instant. Second, the time required to send the command and receive a reply can significantly limit how frequently a setting's value can be polled. The amount of communication overhead depends heavily on whether RS-232, USB, or Ethernet is used, how much data is sent and received, and how busy the computer is at the moment. Third, the polling frequency is not consistent and will vary over time. For instance, the polling frequency over RS-232 with an X-USBDC usually averages 20-60 Hz while the average can go as high as 600 Hz over USB or Ethernet. But that is the average; the time for each individual poll will vary unpredictably around that average.
There are many cases where polling a setting is very effective, such as when monitoring setting values that change relatively slowly or when the precise timing is not important. But in cases where multiple settings need to be captured at the same time and/or the settings must be captured at high frequencies that are consistent and precise, the scope
feature should be used.
Capturing data with the scope
The scope
feature gets its name from an oscilloscope (a tool for precisely monitoring electrical signals at high frequency) and behaves similarly to one.
Zaber devices allow up to scope.numchannels channels (i.e. settings) to be recorded at up to 10 kHz. The scope add command will add a scope channel and configure which setting it should capture.
To start recording the added channels simultaneously, use the scope start command. Once the device is recording data, the values of every channel will be recorded at a precise, regular interval until the internal buffer becomes full or the scope stop command is received. The recording interval is configured via the scope.timebase setting. Once the scope capture is complete, the data can be read out with the scope print command, which will return the data for each captured channel in a series of Info messages.
Manually sending these commands and then parsing scope data can be cumbersome. Instead we recommend using the Zaber Motion Library with the programming language of your choice for configuring the scope, parsing the resulting data, and converting it to units of your choice. For example, the following Python code will configure the device to capture both pos and encoder.pos every 0.1 milliseconds (10 kHz) while doing a move and then read out the data in units of millimetres.
device = # get the device from the zaber_motion.ascii.Connection
# Configure the scope
scope = device.oscilloscope
scope.add_channel(1, "pos")
scope.add_channel(1, "encoder.pos")
scope.set_timebase(0.1)
# Start a move on axis 1 and begin capturing position information.
# Then wait for the motion to end before reading the scope data.
axis = device.get_axis(1)
axis.move_max(wait_until_idle=False)
scope.start()
axis.wait_until_idle()
scope.stop()
channels = scope.read()
pos_data_points = channels[0].get_data(Units.LENGTH_MILLIMETRES)
encoder_pos_data_points = channels[1].get_data(Units.LENGTH_MILLIMETRES)
Processing data
Capturing setting data is only the first of many steps towards getting the data into a spreadsheet for analysis and/or plotting. To streamline all of these steps while still giving you the flexibility to quickly reconfigure things, Zaber provides the Oscilloscope app in Zaber Launcher. It is a graphical interface for capturing, graphing, inspecting, and exporting setting data, and supports not only the scope
feature but polling as well.
The scope
feature, its Zaber Motion Library APIs, and the Oscilloscope app are excellent tools to help you easily capture and process precise, real-time data from your device. If you require any assistance configuring or using these tools, please contact us.