Code covered by the BSD License  

Highlights from
CO2gui - lab control and automation

CO2gui - lab control and automation

by

 

06 Jan 2010 (Updated )

Software used for controlling and data logging lab equipment.

linkvalue(masterSerialObject, masterCommand, slaveSerialObject, slaveCommand, varargin)
function varargout = linkvalue(masterSerialObject, masterCommand, slaveSerialObject, slaveCommand, varargin)
% LINKVALUE slaves a parameter of a serial object to another object.
% timer = linkvalue(masterSerialObject, masterCommand, slaveSerialObject,
% slaveCommand, <Property-Value pairs>) returns a timer that checks the
% parameter of a serial object (the master), then sends it to the other
% serial object (the slave).  The master command must be a function handle
% in the form someValue = someFunction(serialObject), and for the slave
% command, someFunction(serialObject, someValue).  Any optional
% Property-Value pairs can be specified for the timer.

% checks the number of arguments
error(nargchk(4, Inf, nargin))

% checks the details
if ~isserial(masterSerialObject) || ~isrunning(masterSerialObject) || ~isscalar(masterSerialObject)
    % errors
    error('Master serial object must be valid and connected.')
    
elseif ~isa(masterCommand, 'function_handle') || ~isscalar(masterCommand)
    % errors
    error('Master command must be a valid scalar function handle.')
    
elseif ~isserial(slaveSerialObject) || ~isrunning(slaveSerialObject) || ~isscalar(slaveSerialObject)
    % errors
    error('Slave serial object must be valid and connected.')
    
elseif ~isa(slaveCommand, 'function_handle') || ~isscalar(slaveCommand)
    % errors
    error('Slave command must be a valid scalar function handle.')
    
elseif nargin > 4 && ~ispv(varargin{:})
    % errors
    error('Property-Value pairs must be valid.')
end

% creates the timer
linkTimer = timer(  'TimerFcn', {@linkCallback, masterSerialObject, masterCommand, slaveSerialObject, slaveCommand},...
                    'ErrorFcn', @linkError,...
                    'ExecutionMode', 'fixedRate',...
                    'Period', 60);

% if extra properties were supplied...
if nargin > 4
    % tries
    try
        % apply them
        set(linkTimer, varargin{:})

    catch
        % it obviously didn't work - so clean up before erroring
        delete(linkTimer)

        % rethrow the error
        rethrow(lasterror)
    end
end

% start the link timer immediately
start(linkTimer)

% if there are any output arguments, then send the linkTimer to them,
% otherwise, keep quiet
if nargout
    % set it
    varargout{1} = linkTimer;
end


function linkCallback(timerObject, eventdata, masterSerialObject, masterCommand, slaveSerialObject, slaveCommand)
% LINKCALLBACK tries to apply the function

% checks the validity of the objects each time
if ~isserial(masterSerialObject) || ~isrunning(masterSerialObject) || ~isserial(slaveSerialObject) || ~isrunning(slaveSerialObject)
    % deletes the timer and displays a warning
    stop(timerObject)
    delete(timerObject)
    
    % displays a warning
    warning('linkTimer:serialObjectNotValid', 'At least one serial object is no longer valid so the link has been severed and the timer deleted.')
    
else
    % tries to find the CO2gui handle (fetches it from the pico timer
    % if it exists, is empty otherwise)
    mainGuiHandle = getguihandles;

    % only disable the fields if its not empty
    if ~isempty(mainGuiHandle)
        % defines the collect data flag field
        masterCollectDataFlag = sprintf('collectDataFlag%d', masterSerialObject.UserData.objectNumber);

        % turns the collect data flag off
        setappdata(mainGuiHandle, masterCollectDataFlag, false)
    end

    % defines the number as empty
    masterValue = [];
    
    % tries to get the value
    try
        % sends the command
        masterValue = feval(masterCommand, masterSerialObject);
        
    catch
        % screwed up so display a warning
        warning('linkTimer:masterValueRetrievalFailure', 'Could not retrieve the value from the master serial object.')
    end

    % turns the collect data flag back on if it can
    if ~isempty(mainGuiHandle)
        % turns the collect data flag back on
        setappdata(mainGuiHandle, masterCollectDataFlag, true)

        % defines the slave collect data flag field
        slaveCollectDataFlag = sprintf('collectDataFlag%d', slaveSerialObject.UserData.objectNumber);

        % turns the collect data flag off
        setappdata(mainGuiHandle, slaveCollectDataFlag, false)
    end

    % if the master value is not empty, now try and send it to the slave
    if ~isempty(masterValue)
        % if it got this far, now try and send it to the slave
        try
            % sends command
            feval(slaveCommand, slaveSerialObject, masterValue)

        catch
            % it screwed up on writing the value to the slave
            warning('linkTimer:slaveValueNotWritten', 'Could not write master value to the slave object.')
        end
    end

    % turns the collect data flag back on if it can
    if ~isempty(mainGuiHandle)
        % turns the collect data flag back on
        setappdata(mainGuiHandle, slaveCollectDataFlag, true)
    end
end


function linkError(timerObject, eventdata)
% LINKERROR displays a warning if it screwed up
warning('linkValue:timerError', 'Error caused link timer to stop.')

Contact us