Software/MATLAB
Here are two short examples of controlling a Zaber device with either Zaber ASCII or Binary protocol. A newer and complete official Zaber MATLAB Toolbox is also available.
ASCII
In this example, two helper functions are provided. The helper functions should be saved as separate files, sendCommand.m and pollUntilIdle.m, at the same directory of the main script, or within project search path.
% Specifying serial port examples % Windows: 'COM5' % Linux: '/dev/ttyUSB0' % Mac: '/dev/tty.usbserial-DA00FT01' portName = 'COM5'; deviceAddress = 1; axisNumber = 1; % Set up serial object s = serial(portName); set(s, 'BaudRate',115200, 'DataBits',8, 'FlowControl','none',... 'Parity','none', 'StopBits',1, 'Terminator','CR/LF'); % Open serial port. Fails if port is already opened or non-existent. fopen(s); try % Send a home command, ignoring the reply sendCommand(s, deviceAddress, axisNumber, 'home'); % Wait until axis finishes homing pollUntilIdle(s, deviceAddress, axisNumber); % Get current position reply = sendCommand(s, deviceAddress, axisNumber, 'get pos'); pos = str2num(reply.data); disp(['Current position is ' num2str(pos) '.']); catch e % close port first if an exception occurs fclose(s); rethrow(e) end % Close port and clean up serial object fclose(s); delete(s); clear s
In sendCommand.m
function reply = sendCommand(ser, deviceAddress, axisNumber, command) % SENDCOMMAND Send an ASCII command to a Zaber device and receive a reply. % REPLY = SENDCOMMAND(SER, DEVICEADDRESS, AXISNUMBER, COMMAND) % % This function sends an ASCII command formatted as % '/DEVICEADDRESS AXISNUMBER COMMAND\n' to the serial object SER. % The reply is formatted as a struct. % % EXAMPLE % sendCommand(s,1,2,'move abs 256') will result in % '/1 2 move abs 256\n' % being sent to the device at serial object s, and a struct % type : '@' % deviceAddress : 1 % axisNumber : 2 % flag : 'OK' % status : 'BUSY' % warning : '--' % data : '0' % to be returned by the function. % % NOTE % The 'Terminator' property of the serial object should be set to 'CR/LF' % so that ASCII message footer is properly handled when sending commands % and receiving replies. % % Complete protocol manual can be found at % https://www.zaber.com/wiki/Manuals/ASCII_Protocol_Manual if isempty(command) fprintf(ser, '/%d %d\n', [deviceAddress, axisNumber]); else fprintf(ser, '/%d %d %s\n', [deviceAddress, axisNumber, command]); end % Get device reply. FGETL blocks a line is received. replyStr = fgetl(ser); % Parse reply into struct. [type, deviceAddress, axisNumber, flag, status, warning, data] = ... strread(replyStr, '%c%d %d %s %s %s %s'); reply = struct('type', type, 'deviceAddress', deviceAddress,... 'axisNumber', axisNumber, 'flag', flag, 'status', status,... 'warning', warning, 'data', data);
In pollUntilIdle.m
function pollUntilIdle(ser, deviceAddress, axisNumber, pauseDuration) % POLLUNTILIDLE Poll an axis until it becomes idle. % POLLUNTILIDLE(SER, DEVICEADDRESS, AXISNUMBER) % POLLUNTILIDLE(SER, DEVICEADDRESS, AXISNUMBER, PAUSEDURATION) % % This function sends an empty ASCII command and checks whether an axis has % become idle. If axis is busy, pauses for a specific duration and retry. % This function returns when the axis is idle. % % PAUSEDURATION is specified in seconds. If not provided, 0.05 is used. % % EXAMPLE % This example sends a 'home' command and waits until axis has finished % homing. % sendCommand(ser, 1, 2, 'home'); % pollUntilIdle(ser, 1, 2); % disp('Finished homing!'); % % NOTE % The 'Terminator' property of the serial object should be set to 'CR/LF' % so that ASCII message footer is properly handled when sending commands % and receiving replies. % % Complete protocol manual can be found at % https://www.zaber.com/wiki/Manuals/ASCII_Protocol_Manual if nargin < 4 pauseDuration = 0.05; end while true reply = sendCommand(ser, deviceAddress, axisNumber, ''); if strcmp(reply.status, 'IDLE') == 1 % axis is now idle break end % axis still busy, sleep a while before checking again pause(pauseDuration) end
Binary
s = serial('COM5','BaudRate',9600); % Open serial port. Fails if port is already opened. fopen(s); % Send a home command command_home = [1 1 0 0 0 0]; fwrite(s,command_home); % send command to device % Device replies once command is completed when using Binary protocol % This is different from ASCII, which replies immediately after receiving a command while s.BytesAvailable < 6 % wait for response pause(0.01); end % Read response response = fread(s,6) fclose(s); delete(s); clear s;
Working with serial ports
Available serial ports and port status can be queried with INSTRHWINFO and INSTRFIND.
>> info = instrhwinfo('serial') info = AvailableSerialPorts: {3x1 cell} JarFileVersion: 'Version 2.8.0' ObjectConstructorName: {3x1 cell} SerialPorts: {3x1 cell} >> info.AvailableSerialPorts ans = 'COM1' 'COM3' 'COM4'
If a port has been previously opened and is preventing a script from opening it again, try the following to close the port.
>> s = serial('COM3'); >> fopen(s) ??? Error using ==> serial.fopen at 72 Port: COM3 is not available. Available ports: COM1, COM4. Use INSTRFIND to determine if other instrument objects are connected to the requested device. >> serialObj = instrfind Instrument Object Array Index: Type: Status: Name: 1 serial closed Serial-COM3 2 serial open Serial-COM3 3 serial closed Serial-COM3 >> fclose(serialObj(2))
Unofficial Drivers and Examples
We have removed previously customer-supplied drivers and examples, which do not support newer products. If you require one of these drivers or examples, please contact us.