function asiGui
% a basic GUI that interfaces with an Applied Scientific Instrumentation
% microscope stage micropositioning system
if ~isappdata(0, 'asiGui')
if ~ispref('locations', 'asiGui')
setpref('locations', 'asiGui', [100 50 46 10.4]);
end
figHandle = hgload('asiGui');
handles = guihandles(figHandle);
setappdata(0, 'asiGui', figHandle);
set(figHandle, 'position', getpref('locations', 'asiGui'), 'closeRequestFcn', @closeMe);
set(handles.xStep, 'callback', @setXStep);
set(handles.yStep, 'callback', @setYStep);
set(handles.zStep, 'callback', @setZStep);
set(handles.incX, 'callback', @incX);
set(handles.decX, 'callback', @decX);
set(handles.incY, 'callback', @incY);
set(handles.decY, 'callback', @decY);
set(handles.incZ, 'callback', @incZ);
set(handles.decZ, 'callback', @decZ);
set(handles.doZStack, 'callback', @doZStack);
if ~ispref('ASI', 'commPort')
setupASI;
end
try
commPort = serial(['COM' sprintf('%0.0f', getpref('ASI', 'commPort'))]);
set(commPort,...
'baudrate', 9600,...
'parity', 'none',...
'databits', 8,...
'stopbits', 1,...
'requesttosend', 'on',...
'dataterminalready', 'on',...
'timeout', 1,...
'outputbuffersize', 512,...
'inputbuffersize', 1024,...
'bytesAvailableFcnMode', 'byte',...
'bytesAvailableFcnCount', 3,...
'terminator', '',...
'flowControl', 'hardware',...
'recordName', 'myRecord.txt',...
'recordDetail', 'verbose');
fopen(commPort)
catch
error(['Error with serial port COM' sprintf('%0.0f', getpref('ASI', 'commPort')) ' in setting up ASI']);
end
setappdata(0, 'asiPort', commPort);
% let the port open and get set
pause(1)
asiTimer =timer('name', 'asiLocation', 'TimerFcn', @asiLocation, 'Period', 0.5, 'executionMode', 'fixedDelay', 'busyMode', 'drop');
% setup increments
fwrite(commPort, [char(255) char(66)]); % low level commands mode
setXStep;
setYStep;
setZStep;
start(asiTimer);
% set the starting path for z stacks
path = pwd;
else
% restack the windows
figHandle = figure(getappdata(0, 'asiGui'));
end
tempPos = get(figHandle, 'position');
set(0, 'units', get(figHandle, 'units'));
screenLims = get(0, 'monitorPosition');
screenLims = [min(screenLims(:,1:2), [], 1) max(screenLims(:,3:4), [], 1)];
set(figHandle, 'position', [max([screenLims(1) min([screenLims(3) - tempPos(3) tempPos(1)])]) max([screenLims(2) min([screenLims(4) - tempPos(4) tempPos(2)])]) tempPos(3:4)]);
function decX(varargin)
fwrite(commPort, [char(24) char(45) char(0) char(58)]);
end
function incX(varargin)
fwrite(commPort, [char(24) char(43) char(0) char(58)]);
end
function decY(varargin)
fwrite(commPort, [char(25) char(45) char(0) char(58)]);
end
function incY(varargin)
fwrite(commPort, [char(25) char(43) char(0) char(58)]);
end
function decZ(varargin)
fwrite(commPort, [char(26) char(45) char(0) char(58)]);
end
function incZ(varargin)
fwrite(commPort, [char(26) char(43) char(0) char(58)]);
end
function setXStep(varargin)
fwrite(commPort, [char(24) char(68) char(3) char(mod(str2double(get(handles.xStep, 'string')) * 10, 256)) char(round(mod(str2double(get(handles.xStep, 'string')) * 10 / 256, 256))) char(round(mod(str2double(get(handles.xStep, 'string')) * 10 / 256 / 256, 256))) char(58)]);
end
function setYStep(varargin)
fwrite(commPort, [char(25) char(68) char(3) char(mod(str2double(get(handles.yStep, 'string')) * 10, 256)) char(round(mod(str2double(get(handles.yStep, 'string')) * 10 / 256, 256))) char(round(mod(str2double(get(handles.yStep, 'string')) * 10 / 256 / 256, 256))) char(58)]);
end
function setZStep(varargin)
fwrite(commPort, [char(26) char(68) char(3) char(mod(str2double(get(handles.zStep, 'string')) * 10, 256)) char(round(mod(str2double(get(handles.zStep, 'string')) * 10 / 256, 256))) char(round(mod(str2double(get(handles.zStep, 'string')) * 10 / 256 / 256, 256))) char(58)]);
end
function doZStack(varargin)
% take a Z-stack image
stop(asiTimer);
tempPath = path;
path = uigetdir(path, 'Enter location for stack');
if path == 0
path = tempPath;
return
end
currentPosition = readASI;
stopPoint = currentPosition(3) + str2double(get(handles.stackHeight, 'string'));
cellName = get(handles.txtCellName, 'string');
cellName(cellName == '.') = '_';
stackName = get(handles.txtStackName, 'string');
stackName(stackName == '.') = '_';
if stopPoint >= currentPosition(3)
comparisonFunction = @le;
movementFunction = @incZ;
else
comparisonFunction = @ge;
movementFunction = @decZ;
end
imageCounter = 1;
while comparisonFunction(currentPosition(3), stopPoint)
% call the image acquisition function, letting it know the
% current position
rasterScan([path filesep cellName '.' stackName '.' num2str(imageCounter)], readASI);
movementFunction();
pause(.5); % wait for the movement to settle
asiLocation;
imageCounter = imageCounter + 1;
currentPosition = readASI;
end
start(asiTimer);
end
function asiLocation(varargin)
% update the position of the ASI on the graphical display
currentPosition = readASI;
tempLabel{1} = ['X = ' num2str(currentPosition(1)) char(181) 'm'];
tempLabel{2} = ['Y = ' num2str(currentPosition(2)) char(181) 'm'];
tempLabel{3} = ['Z = ' num2str(currentPosition(3)) char(181) 'm'];
set(handles.lblLocation, 'string', tempLabel);
end
function currentPosition = readASI
% return the current position of the ASI
fwrite(commPort, [char(24) char(97) char(3) char(58)]);
tempData = fread(commPort, 3, 'char');
if numel(tempData)
currentPosition(1) = (tempData(1) + 256 * tempData(2) + 256 * 256 * tempData(3)) / 10;
if currentPosition(1) > 2^23 / 10
currentPosition(1) = -2^24 / 10 + currentPosition(1);
end
else
currentPosition(1) = nan;
warning off last
end
fwrite(commPort, [char(25) char(97) char(3) char(58)]);
tempData = fread(commPort, 3, 'char');
if numel(tempData)
currentPosition(2) = (tempData(1) + 256 * tempData(2) + 256 * 256 * tempData(3)) / 10;
if currentPosition(2) > 2^23 / 10
currentPosition(2) = -2^24 / 10 + currentPosition(2);
end
else
currentPosition(2) = nan;
warning off last
end
fwrite(commPort, [char(26) char(97) char(3) char(58)]);
tempData = fread(commPort, 3, 'char');
if numel(tempData)
currentPosition(3) = (tempData(1) + 256 * tempData(2) + 256 * 256 * tempData(3)) / 10;
if currentPosition(3) > 2^23 / 10
currentPosition(3) = -2^24 / 10 + currentPosition(3);
end
else
currentPosition(3) = nan;
warning off last
end
end
function closeMe(varargin)
% close the serial ports and clean up data
stop(asiTimer);
delete(asiTimer);
fclose(commPort);
delete(commPort);
rmappdata(0, 'asiPort');
setpref('locations', 'asiGui', get(figHandle, 'position'));
rmappdata(0, 'asiGui');
delete(figHandle);
end
end
function setupASI
% ask what serial port the ASI is connected to
commPort = inputdlg('Enter serial port to which ASI is connected', 'Comm ', 1, {'1'});
if isempty(commPort)
error('Must set a value for ASI serial port')
end
if any(commPort{1} > 57 | commPort{1} < 48)
error('Value must be a number')
end
setpref('ASI', 'commPort', str2double(commPort));
end
function rasterScan(filename, currentLocation)
% this is just a dummy function that you ought to replace with one that
% takes images on your system
disp([filename ' taken at X = ' num2str(currentLocation(1)) char(181) 'm, Y = ' num2str(currentLocation(2)) char(181) 'm, Z = ' num2str(currentLocation(3)) char(181) 'm']);
pause(1)
end