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.

writeco2guiconfig.m
function [guiConfig, objectTypes, objectConfig, tc08Types, tc08Config] = writeco2guiconfig(guiConfig, objectTypes, objectConfig, tc08Types, tc08Config)
% writeco2guiconfig write the CO2gui configuration
% [guiConfig, objectTypes, objectConfig, tc08Types, tc08Config] =
% writeco2guiconfig(guiConfig, objectTypes, objectConfig, tc08Types,
% tc08Config) writes the CO2gui configuration, optionally returning the
% values back (useful for using default arguments)

% filename for the GUI configuration
filename = [fileparts(mfilename('fullpath')), '\co2guiconfig'];

% if there are no arguments, generate default ones
if ~nargin
    % prepares default data before writing it
    
    % guiConfig -----------------------------------------------------------
    
    % timer properties
    guiConfig.picoTimerPeriod = 1.5;
    guiConfig.serialTimerPeriod = 20;
    guiConfig.lockTimers = false;
    
    % options for shutting down MATLAB completely when the GUI is closed
    guiConfig.closeMatlabOnExit = false;
    
    % opening the status window on startup or not
    guiConfig.statusWindowStartup = false;
    
    % the default export data format (excel)
    guiConfig.defaultExportDataFormat = 0;
    
    % whether to hide the pressure drop axes or not
    guiConfig.showPressDropAxes = true;
    
    % options for plotting the fibre intensities
    guiConfig.showFibreIntensity1 = true;
    guiConfig.showFibreIntensity2 = false;
    
    
    % objectTypes ---------------------------------------------------------
    
    % objectType, objectCommand, connectCommand, disconnectCommand,
    % currentTempCommand , readSetTempCommand, writeSetTempCommand,
    % currentPressCommand, readSetPressCommand ,writeSetPressCommand,
    % readFlowCommand, writeFlowCommand, readAllCommand, startCommand,
    % stopCommand, mainCommand, moreCommand, statusCommand

    % each objectCommand is in the form: of serialObject =
    % command(comPortNumber), and each connect or disconnect command should
    % be in the form of: command(serialObject)

    % each read command MUST be of the form: output =
    % command(serialObject), and each write command MUST be of the form:
    % command(serialObj, newValue) where both output and newValue must be
    % numbers

    % mainCommand is the main command for that device, e.g. for Jasco Pumps
    % it would be 'pumpobjwriteflow'

    % startOnConnect is 1 if the start command is to be run immediately on
    % connection, 0 otherwise

    % status command is designed to always return "something" if the
    % instrument is connected, and to error if the instrument is not
    % responding (used for auto-detection of instruments)
    
    % readAllCommand returns the five fields in a cell array - those which
    % are not available give an empty cell

    % empty object (incorporated for tidiness)

    % label to be used in GUI in drop-down menu
    objectTypes(1).name = '';

    % generates the serial object: serialObj = objectCommand(comPortNumber)
    objectTypes(1).objectCommand = '';

    % connects the instrument: connectCommand(serialObj)
    objectTypes(1).connectCommand = '';

    % disconnects the instrument: disconnectCommand(serialObj)
    objectTypes(1).disconnectCommand = '';

    % reads current temperature: currentTemp = currentTempCommand(serialObj)
    objectTypes(1).currentTempCommand = '';

    % reads set temperature: setTemp = readSetTempCommand(serialObj)
    objectTypes(1).readSetTempCommand = '';

    % writes set temperature: writeSetTempCommand(serialObj, setTemp)
    objectTypes(1).writeSetTempCommand = '';

    % reads current pressure: currentPress = currentPressCommand(serialObj)
    objectTypes(1).currentPressCommand = '';

    % reads set pressure: setPress = readSetPressCommand(serialObj)
    objectTypes(1).readSetPressCommand = '';

    % writes set pressure: writeSetPressCommand(serialObj, setPress)
    objectTypes(1).writeSetPressCommand = '';

    % reads current flow rate: currentFlow = readFlowCommand(serialObj)
    objectTypes(1).readFlowCommand = '';

    % writes flow rate: writeFlowCommand(serialObj, flow)
    objectTypes(1).writeFlowCommand = '';
    
    % returns a 5x1 cell array with all the fields filled (or blank if n/a
    % for that particular instrument) - implemented since frequently more
    % than one piece of information can be collected at once - this gives a
    % saving in communications time
    objectTypes(1).readAllCommand = '';

    % starts the instrument: startCommand(serialObj)
    objectTypes(1).startCommand = '';

    % stops the instrument: stopCommand(serialObj)
    objectTypes(1).stopCommand = '';

    % the main command: mainCommand(serialObj, parameter)
    objectTypes(1).mainCommand = '';
    
    % the main field that the main command would fill, i.e. it returns
    % whatever the main command sets - mainReadCommand(serialObj)
    objectTypes(1).mainField = '';
    
    % something comparable for the obvious field to write to
    objectTypes(1).mainSetField = 'flow';

    % the command to start the more options GUI
    objectTypes(1).moreCommand = '';

    % returns with a 1 if it is a function object (used in autodetect)
    objectTypes(1).statusCommand = '';
    
    % the command to use if the device is functioning or not
    objectTypes(1).testCommand = '';
    
    % the allowed amount of noise for the parameter to be stable
    objectTypes(1).allowedNoise = [];
    objectTypes(1).allowedDeviation = [];
    
    % minimum and maximum values for parameters
    objectTypes(1).minSetTemp = [];
    objectTypes(1).maxSetTemp = [];
    objectTypes(1).setTempResolution = [];
    objectTypes(1).minSetPress = [];
    objectTypes(1).maxSetPress = [];
    objectTypes(1).setPressResolution = [];
    objectTypes(1).minFlow = 2.5;
    objectTypes(1).maxFlow = 8192;
    objectTypes(1).flowResolution = []; % although this is 10 / 8192, it gets rouded off in practice
    
    % defines what the object is - the current ones are: 'dummy', 'pump',
    % 'bpr' and 'heat'
    objectTypes(1).class = 'dummy';
    

    % Jasco Pump
    objectTypes(2).name = 'Jasco Pump';
    objectTypes(2).objectCommand = 'pumpobj';
    objectTypes(2).connectCommand = 'pumpobjconnect';
    objectTypes(2).disconnectCommand = 'pumpobjdisconnect';
    objectTypes(2).currentTempCommand = '';
    objectTypes(2).readSetTempCommand = '';
    objectTypes(2).writeSetTempCommand = '';
    objectTypes(2).currentPressCommand = 'pumpobjcurrentpress';
    objectTypes(2).readSetPressCommand = 'pumpobjreadsetpress';
    objectTypes(2).writeSetPressCommand = 'pumpobjwritesetpress';
    objectTypes(2).readFlowCommand = 'pumpobjreadflow';
    objectTypes(2).writeFlowCommand = 'pumpobjwriteflow';
    objectTypes(2).readAllCommand = 'pumpobjreadall';
    objectTypes(2).startCommand = 'pumpobjstart';
    objectTypes(2).stopCommand = 'pumpobjstop';
    objectTypes(2).mainCommand = 'pumpobjwriteflow';
    objectTypes(2).mainField = 'flow';
    objectTypes(2).mainSetField = 'flow';
    objectTypes(2).moreCommand = 'pumpobjgui';
    objectTypes(2).statusCommand = 'pumpobjstatus';
    objectTypes(2).testCommand = 'pumpobjreadflow';
    objectTypes(2).allowedNoise = 0.9;
    objectTypes(2).allowedDeviation = [];
    objectTypes(2).minSetTemp = [];
    objectTypes(2).maxSetTemp = [];
    objectTypes(2).setTempResolution = [];
    objectTypes(2).minSetPress = 0;
    objectTypes(2).maxSetPress = 350;
    objectTypes(2).setPressResolution = 1;
    objectTypes(2).minFlow = 0;
    objectTypes(2).maxFlow = 10;
    objectTypes(2).flowResolution = 0.001;
    objectTypes(2).class = 'pump';

    % Jasco BPR
    objectTypes(3).name = 'Jasco BPR';
    objectTypes(3).objectCommand = 'bprobj';
    objectTypes(3).connectCommand = 'bprobjconnect';
    objectTypes(3).disconnectCommand = 'bprobjdisconnect';
    objectTypes(3).currentTempCommand = 'bprobjcurrenttemp';
    objectTypes(3).readSetTempCommand = 'bprobjreadsettemp';
    objectTypes(3).writeSetTempCommand = 'bprobjwritesettemp';
    objectTypes(3).currentPressCommand = 'bprobjcurrentpress';
    objectTypes(3).readSetPressCommand = 'bprobjreadsetpress';
    objectTypes(3).writeSetPressCommand = 'bprobjwritesetpress';
    objectTypes(3).readFlowCommand = '';
    objectTypes(3).writeFlowCommand = '';
    objectTypes(3).readAllCommand = 'bprobjreadall';
    objectTypes(3).startCommand = 'bprobjstart';
    objectTypes(3).stopCommand = 'bprobjstop';
    objectTypes(3).mainCommand = 'bprobjwritesetpress';
    objectTypes(3).mainField = 'currentPress';
    objectTypes(3).mainSetField = 'setPress';
    objectTypes(3).moreCommand = 'bprobjgui';
    objectTypes(3).statusCommand = 'bprobjstatus';
    objectTypes(3).testCommand = 'bprobjtestconnect';
    objectTypes(3).allowedNoise = 0.9;
    objectTypes(3).allowedDeviation = [];
    objectTypes(3).minSetTemp = 30;
    objectTypes(3).maxSetTemp = 80;
    objectTypes(3).setTempResolution = 0.01;
    objectTypes(3).minSetPress = 0;
    objectTypes(3).maxSetPress = 350;
    objectTypes(3).setPressResolution = 0.1;
    objectTypes(3).minFlow = [];
    objectTypes(3).maxFlow = [];
    objectTypes(3).flowResolution = [];
    objectTypes(3).class = 'bpr';

    % Eurotherm Series 2000 temperature controllers
    objectTypes(4).name = 'Eurotherm Controller';
    objectTypes(4).objectCommand = 'tempobj';
    objectTypes(4).connectCommand = 'tempobjconnect';
    objectTypes(4).disconnectCommand = 'tempobjdisconnect';
    objectTypes(4).currentTempCommand = 'tempobjcurrenttemp';
    objectTypes(4).readSetTempCommand = 'tempobjreadsettemp';
    objectTypes(4).writeSetTempCommand = 'tempobjwritesettemp';
    objectTypes(4).currentPressCommand = '';
    objectTypes(4).readSetPressCommand = '';
    objectTypes(4).writeSetPressCommand = '';
    objectTypes(4).readFlowCommand = '';
    objectTypes(4).writeFlowCommand = '';
    objectTypes(4).readAllCommand = 'tempobjreadall';
    objectTypes(4).startCommand = 'tempobjstart';
    objectTypes(4).stopCommand = 'tempobjstop';
    objectTypes(4).mainCommand = 'tempobjwritesettemp';
    objectTypes(4).mainField = 'currentTemp';
    objectTypes(4).mainSetField = 'setTemp';
    objectTypes(4).moreCommand = 'tempobjgui';
    objectTypes(4).statusCommand = 'tempobjstatus';
    objectTypes(4).testCommand = 'tempobjreadsettemp';
    objectTypes(4).allowedNoise = 0.9;
    objectTypes(4).allowedDeviation = [];
    objectTypes(4).minSetTemp = -199.9;
    objectTypes(4).maxSetTemp = 500;
    objectTypes(4).setTempResolution = eps('single'); % the precision is enormous so this could in fact be left at 0 or blank
    objectTypes(4).minSetPress = [];
    objectTypes(4).maxSetPress = [];
    objectTypes(4).setPressResolution = [];
    objectTypes(4).minFlow = [];
    objectTypes(4).maxFlow = [];
    objectTypes(4).flowResolution = [];
    objectTypes(4).class = 'temp';

    % Gilson 30x Pumps
    objectTypes(5).name = 'Gilson 30x Pump';
    objectTypes(5).objectCommand = 'gilsonpumpobj';
    objectTypes(5).connectCommand = 'gilsonpumpobjconnect';
    objectTypes(5).disconnectCommand = 'gilsonpumpobjdisconnect';
    objectTypes(5).currentTempCommand = '';
    objectTypes(5).readSetTempCommand = '';
    objectTypes(5).writeSetTempCommand = '';
    objectTypes(5).currentPressCommand = 'gilsonpumpobjcurrentpress';
    objectTypes(5).readSetPressCommand = '';
    objectTypes(5).writeSetPressCommand = '';
    objectTypes(5).readFlowCommand = 'gilsonpumpobjreadflow';
    objectTypes(5).writeFlowCommand = 'gilsonpumpobjwriteflow';
    objectTypes(5).readAllCommand = 'gilsonpumpobjreadallmanometric';
    objectTypes(5).startCommand = 'gilsonpumpobjstart';
    objectTypes(5).stopCommand = 'gilsonpumpobjstop';
    objectTypes(5).mainCommand = 'gilsonpumpobjwriteflow';
    objectTypes(5).mainField = 'flow';
    objectTypes(5).mainSetField = 'flow';
    objectTypes(5).moreCommand = 'gilsonpumpobjgui';
    objectTypes(5).statusCommand = 'gilsonpumpobjstatus';
    objectTypes(5).testCommand = 'gilsonpumpobjreadmanometricmodule';
    objectTypes(5).allowedNoise = 0.9;
    objectTypes(5).allowedDeviation = [];
    objectTypes(5).minSetTemp = [];
    objectTypes(5).maxSetTemp = [];
    objectTypes(5).setTempResolution = [];
    objectTypes(5).minSetPress = [];
    objectTypes(5).maxSetPress = [];
    objectTypes(5).setPressResolution = [];
    objectTypes(5).minFlow = 0;
    objectTypes(5).maxFlow = 5; % issues with this not working for 10 SC pump heads etc.
    objectTypes(5).flowResolution = 0.0005; % actually this is 0.001 above 0.5 mLmin-1, but there is no way to incorporate this at present (the mid-level comms routines deal with this anyway)
    objectTypes(5).class = 'pump';

    % Thar ABPR-20 BPR
    objectTypes(6).name = 'Thar ABPR-20';
    objectTypes(6).objectCommand = 'tharbprobj';
    objectTypes(6).connectCommand = 'tharbprobjconnect';
    objectTypes(6).disconnectCommand = 'tharbprobjdisconnect';
    objectTypes(6).currentTempCommand = 'tharbprobjcurrenttemp';
    objectTypes(6).readSetTempCommand = '';
    objectTypes(6).writeSetTempCommand = '';
    objectTypes(6).currentPressCommand = 'tharbprobjcurrentpress';
    objectTypes(6).readSetPressCommand = 'tharbprobjreadsetpress';
    objectTypes(6).writeSetPressCommand = 'tharbprobjwritesetpress';
    objectTypes(6).readAllCommand = 'tharbprobjreadall';
    objectTypes(6).readFlowCommand = '';
    objectTypes(6).writeFlowCommand = '';
    objectTypes(6).startCommand = 'tharbprobjstart';
    objectTypes(6).stopCommand = 'tharbprobjstop';
    objectTypes(6).mainCommand = 'tharbprobjwritesetpress';
    objectTypes(6).mainField = 'currentPress';
    objectTypes(6).mainSetField = 'setPress';
    objectTypes(6).moreCommand = 'tharbprobjgui';
    objectTypes(6).statusCommand = 'tharbprobjstatus';
    objectTypes(6).testCommand = 'tharbprobjcurrentpress';
    objectTypes(6).allowedNoise = 0.9;
    objectTypes(6).allowedDeviation = [];
    objectTypes(6).minSetTemp = [];
    objectTypes(6).maxSetTemp = [];
    objectTypes(6).setTempResolution = [];
    objectTypes(6).minSetPress = 0;
    objectTypes(6).maxSetPress = 590;
    objectTypes(6).setPressResolution = 1;
    objectTypes(6).minFlow = [];
    objectTypes(6).maxFlow = [];
    objectTypes(6).class = 'bpr';
    
    % all of the instruments with alternative connection are included
    % AFTERWARDS, since autodetect stops when it finds a valid match
    
    % Jasco Pump (Realterm)
    objectTypes(7).name = 'Jasco Pump (RT)';
    objectTypes(7).objectCommand = 'pumpobj2';
    objectTypes(7).connectCommand = 'pumpobjconnect';
    objectTypes(7).disconnectCommand = 'pumpobjdisconnect';
    objectTypes(7).currentTempCommand = '';
    objectTypes(7).readSetTempCommand = '';
    objectTypes(7).writeSetTempCommand = '';
    objectTypes(7).currentPressCommand = 'pumpobjcurrentpress';
    objectTypes(7).readSetPressCommand = 'pumpobjreadsetpress';
    objectTypes(7).writeSetPressCommand = 'pumpobjwritesetpress';
    objectTypes(7).readFlowCommand = 'pumpobjreadflow';
    objectTypes(7).writeFlowCommand = 'pumpobjwriteflow';
    objectTypes(7).readAllCommand = 'pumpobjreadall';
    objectTypes(7).startCommand = 'pumpobjstart';
    objectTypes(7).stopCommand = 'pumpobjstop';
    objectTypes(7).mainCommand = 'pumpobjwriteflow';
    objectTypes(7).mainField = 'flow';
    objectTypes(7).mainSetField = 'flow';
    objectTypes(7).moreCommand = 'pumpobjgui';
    objectTypes(7).statusCommand = 'pumpobjstatus';
    objectTypes(7).testCommand = 'pumpobjreadflow';
    objectTypes(7).allowedNoise = 0.9;
    objectTypes(7).allowedDeviation = [];
    objectTypes(7).minSetTemp = [];
    objectTypes(7).maxSetTemp = [];
    objectTypes(7).setTempResolution = [];
    objectTypes(7).minSetPress = 0;
    objectTypes(7).maxSetPress = 350;
    objectTypes(7).setPressResolution = 1;
    objectTypes(7).minFlow = 0;
    objectTypes(7).maxFlow = 10;
    objectTypes(7).flowResolution = 0.001;
    objectTypes(7).class = 'pump';

    % Jasco BPR (Realterm)
    objectTypes(8).name = 'Jasco BPR (RT)';
    objectTypes(8).objectCommand = 'bprobj2';
    objectTypes(8).connectCommand = 'bprobjconnect';
    objectTypes(8).disconnectCommand = 'bprobjdisconnect';
    objectTypes(8).currentTempCommand = 'bprobjcurrenttemp';
    objectTypes(8).readSetTempCommand = 'bprobjreadsettemp';
    objectTypes(8).writeSetTempCommand = 'bprobjwritesettemp';
    objectTypes(8).currentPressCommand = 'bprobjcurrentpress';
    objectTypes(8).readSetPressCommand = 'bprobjreadsetpress';
    objectTypes(8).writeSetPressCommand = 'bprobjwritesetpress';
    objectTypes(8).readFlowCommand = '';
    objectTypes(8).writeFlowCommand = '';
    objectTypes(8).readAllCommand = 'bprobjreadall';
    objectTypes(8).startCommand = 'bprobjstart';
    objectTypes(8).stopCommand = 'bprobjstop';
    objectTypes(8).mainCommand = 'bprobjwritesetpress';
    objectTypes(8).mainField = 'currentPress';
    objectTypes(8).mainSetField = 'setPress';
    objectTypes(8).moreCommand = 'bprobjgui';
    objectTypes(8).statusCommand = 'bprobjstatus';
    objectTypes(8).testCommand = 'bprobjtestconnect';
    objectTypes(8).allowedNoise = 0.9;
    objectTypes(8).allowedDeviation = [];
    objectTypes(8).minSetTemp = 30;
    objectTypes(8).maxSetTemp = 80;
    objectTypes(8).setTempResolution = 0.01;
    objectTypes(8).minSetPress = 0;
    objectTypes(8).maxSetPress = 350;
    objectTypes(8).setPressResolution = 0.1;
    objectTypes(8).minFlow = [];
    objectTypes(8).maxFlow = [];
    objectTypes(8).flowResolution = [];
    objectTypes(8).class = 'bpr';

    % Eurotherm Series 2000 temperature controllers (Realterm)
    objectTypes(9).name = 'Eurotherm (RT)';
    objectTypes(9).objectCommand = 'tempobj2';
    objectTypes(9).connectCommand = 'tempobjconnect';
    objectTypes(9).disconnectCommand = 'tempobjdisconnect';
    objectTypes(9).currentTempCommand = 'tempobjcurrenttemp';
    objectTypes(9).readSetTempCommand = 'tempobjreadsettemp';
    objectTypes(9).writeSetTempCommand = 'tempobjwritesettemp';
    objectTypes(9).currentPressCommand = '';
    objectTypes(9).readSetPressCommand = '';
    objectTypes(9).writeSetPressCommand = '';
    objectTypes(9).readFlowCommand = '';
    objectTypes(9).writeFlowCommand = '';
    objectTypes(9).readAllCommand = 'tempobjreadall';
    objectTypes(9).startCommand = 'tempobjstart';
    objectTypes(9).stopCommand = 'tempobjstop';
    objectTypes(9).mainCommand = 'tempobjwritesettemp';
    objectTypes(9).mainField = 'currentTemp';
    objectTypes(9).mainSetField = 'setTemp';
    objectTypes(9).moreCommand = 'tempobjgui';
    objectTypes(9).statusCommand = 'tempobjstatus';
    objectTypes(9).testCommand = 'tempobjreadsettemp';
    objectTypes(9).allowedNoise = 0.9;
    objectTypes(9).allowedDeviation = [];
    objectTypes(9).minSetTemp = -199.9;
    objectTypes(9).maxSetTemp = 500;
    objectTypes(9).setTempResolution = eps('single');
    objectTypes(9).minSetPress = [];
    objectTypes(9).maxSetPress = [];
    objectTypes(9).setPressResolution = [];
    objectTypes(9).minFlow = [];
    objectTypes(9).maxFlow = [];
    objectTypes(9).flowResolution = [];
    objectTypes(9).class = 'temp';

    % Gilson 30x Pumps
    objectTypes(10).name = 'Gilson 30x Pump (RT)';
    objectTypes(10).objectCommand = 'gilsonpumpobj2';
    objectTypes(10).connectCommand = 'gilsonpumpobjconnect';
    objectTypes(10).disconnectCommand = 'gilsonpumpobjdisconnect';
    objectTypes(10).currentTempCommand = '';
    objectTypes(10).readSetTempCommand = '';
    objectTypes(10).writeSetTempCommand = '';
    objectTypes(10).currentPressCommand = 'gilsonpumpobjcurrentpress';
    objectTypes(10).readSetPressCommand = '';
    objectTypes(10).writeSetPressCommand = '';
    objectTypes(10).readFlowCommand = 'gilsonpumpobjreadflow';
    objectTypes(10).writeFlowCommand = 'gilsonpumpobjwriteflow';
    objectTypes(10).readAllCommand = 'gilsonpumpobjreadallmanometric';
    objectTypes(10).startCommand = 'gilsonpumpobjstart';
    objectTypes(10).stopCommand = 'gilsonpumpobjstop';
    objectTypes(10).mainCommand = 'gilsonpumpobjwriteflow';
    objectTypes(10).mainField = 'flow';
    objectTypes(10).mainSetField = 'flow';
    objectTypes(10).moreCommand = 'gilsonpumpobjgui';
    objectTypes(10).statusCommand = 'gilsonpumpobjstatus';
    objectTypes(10).testCommand = 'gilsonpumpobjreadmanometricmodule';
    objectTypes(10).allowedNoise = 0.9;
    objectTypes(10).allowedDeviation = [];
    objectTypes(10).minSetTemp = [];
    objectTypes(10).maxSetTemp = [];
    objectTypes(10).setTempResolution = [];
    objectTypes(10).minSetPress = [];
    objectTypes(10).maxSetPress = [];
    objectTypes(10).setPressResolution = [];
    objectTypes(10).minFlow = 0;
    objectTypes(10).maxFlow = 5; % issues with this not working for 10 SC pump heads etc.
    objectTypes(10).flowResolution = 0.0005;
    objectTypes(10).class = 'pump';
    
    % Thar ABPR-20 BPR (using Realterm)
    objectTypes(11).name = 'Thar ABPR-20 (RT)';
    objectTypes(11).objectCommand = 'tharbprobj2';
    objectTypes(11).connectCommand = 'tharbprobjconnect';
    objectTypes(11).disconnectCommand = 'tharbprobjdisconnect';
    objectTypes(11).currentTempCommand = 'tharbprobjcurrenttemp';
    objectTypes(11).readSetTempCommand = '';
    objectTypes(11).writeSetTempCommand = '';
    objectTypes(11).currentPressCommand = 'tharbprobjcurrentpress';
    objectTypes(11).readSetPressCommand = 'tharbprobjreadsetpress';
    objectTypes(11).writeSetPressCommand = 'tharbprobjwritesetpress';
    objectTypes(11).readAllCommand = 'tharbprobjreadall';
    objectTypes(11).readFlowCommand = '';
    objectTypes(11).writeFlowCommand = '';
    objectTypes(11).startCommand = 'tharbprobjstart';
    objectTypes(11).stopCommand = 'tharbprobjstop';
    objectTypes(11).mainCommand = 'tharbprobjwritesetpress';
    objectTypes(11).mainField = 'currentPress';
    objectTypes(11).mainSetField = 'setPress';
    objectTypes(11).moreCommand = 'tharbprobjgui';
    objectTypes(11).statusCommand = 'tharbprobjstatus';
    objectTypes(11).testCommand = 'tharbprobjcurrentpress';
    objectTypes(11).allowedNoise = 0.9;
    objectTypes(11).allowedDeviation = [];
    objectTypes(11).minSetTemp = [];
    objectTypes(11).maxSetTemp = [];
    objectTypes(11).setTempResolution = [];
    objectTypes(11).minSetPress = 0;
    objectTypes(11).maxSetPress = 590;
    objectTypes(11).setPressResolution = 1;
    objectTypes(11).minFlow = [];
    objectTypes(11).maxFlow = [];
    objectTypes(11).flowResolution = [];
    objectTypes(11).class = 'bpr';
    
    % Rheodyne serial objects (proper RS232 communications)
    objectTypes(12).name = 'Rheodyne (RS232)';
    objectTypes(12).objectCommand = 'rheodyne232obj';
    objectTypes(12).connectCommand = 'rheodyne232objconnect';
    objectTypes(12).disconnectCommand = 'rheodyne232objdisconnect';
    objectTypes(12).currentTempCommand = '';
    objectTypes(12).readSetTempCommand = '';
    objectTypes(12).writeSetTempCommand = '';
    objectTypes(12).currentPressCommand = '';
    objectTypes(12).readSetPressCommand = '';
    objectTypes(12).writeSetPressCommand = '';
    objectTypes(12).readAllCommand = 'rheodyne232objreadall';
    objectTypes(12).readFlowCommand = 'rheodyne232objreadperiod';
    objectTypes(12).writeFlowCommand = 'rheodyne232objwriteperiod';
    objectTypes(12).startCommand = 'rheodyne232objstart';
    objectTypes(12).stopCommand = 'rheodyne232objstop';
    objectTypes(12).mainCommand = 'rheodyne232objwriteperiod';
    objectTypes(12).mainField = 'flow';
    objectTypes(12).mainSetField = 'flow';
    objectTypes(12).moreCommand = 'rheodyne232objgui';
    objectTypes(12).statusCommand = 'rheodyne232objstatus';
    objectTypes(12).testCommand = 'rheodyne232objtestcommand';
    objectTypes(12).allowedNoise = [];
    objectTypes(12).allowedDeviation = [];
    objectTypes(12).minSetTemp = [];
    objectTypes(12).maxSetTemp = [];
    objectTypes(12).setTempResolution = [];
    objectTypes(12).minSetPress = [];
    objectTypes(12).maxSetPress = [];
    objectTypes(12).setPressResolution = [];
    objectTypes(12).minFlow = 2.5;
    objectTypes(12).maxFlow = 30;
    objectTypes(12).flowResolution = 0.001; % limited by the MATLAB timer resolution
    objectTypes(12).class = 'valve';
    
    % Rheodyne serial objects (proper RS232 communications)
    objectTypes(13).name = 'Rheodyne (RS232) (RT)';
    objectTypes(13).objectCommand = 'rheodyne232obj2';
    objectTypes(13).connectCommand = 'rheodyne232objconnect';
    objectTypes(13).disconnectCommand = 'rheodyne232objdisconnect';
    objectTypes(13).currentTempCommand = '';
    objectTypes(13).readSetTempCommand = '';
    objectTypes(13).writeSetTempCommand = '';
    objectTypes(13).currentPressCommand = '';
    objectTypes(13).readSetPressCommand = '';
    objectTypes(13).writeSetPressCommand = '';
    objectTypes(13).readAllCommand = 'rheodyne232objreadall';
    objectTypes(13).readFlowCommand = 'rheodyne232objreadperiod';
    objectTypes(13).writeFlowCommand = 'rheodyne232objwriteperiod';
    objectTypes(13).startCommand = 'rheodyne232objstart';
    objectTypes(13).stopCommand = 'rheodyne232objstop';
    objectTypes(13).mainCommand = 'rheodyne232objwriteperiod';
    objectTypes(13).mainField = 'flow';
    objectTypes(13).mainSetField = 'flow';
    objectTypes(13).moreCommand = 'rheodyne232objgui';
    objectTypes(13).statusCommand = 'rheodyne232objstatus';
    objectTypes(13).testCommand = 'rheodyne232objvalvestatus';
    objectTypes(13).allowedNoise = [];
    objectTypes(13).allowedDeviation = [];
    objectTypes(13).minSetTemp = [];
    objectTypes(13).maxSetTemp = [];
    objectTypes(13).setTempResolution = [];
    objectTypes(13).minSetPress = [];
    objectTypes(13).maxSetPress = [];
    objectTypes(13).setPressResolution = [];
    objectTypes(13).minFlow = 2.5;
    objectTypes(13).maxFlow = 30;
    objectTypes(13).flowResolution = 0.001; % limited by the MATLAB timer resolution
    objectTypes(13).class = 'valve';
        
    % objectConfig --------------------------------------------------------
    
    % object 1
    objectConfig(1).enabled = true;
    objectConfig(1).name = 'CO2 Pump';
    objectConfig(1).type = 2;
    objectConfig(1).comPort = 'COM5';
    objectConfig(1).currentTempPlotFlag = false;
    objectConfig(1).setTempPlotFlag = false;
    objectConfig(1).currentPressPlotFlag = false;
    objectConfig(1).setPressPlotFlag = false;
    objectConfig(1).flowPlotFlag = true;
    objectConfig(1).persistentData = [];

    % object 2
    objectConfig(2).enabled = false;
    objectConfig(2).name = 'CO2 BPR';
    objectConfig(2).type = 3;
    objectConfig(2).comPort = '';
    objectConfig(2).currentTempPlotFlag = false;
    objectConfig(2).setTempPlotFlag = false;
    objectConfig(2).currentPressPlotFlag = false;
    objectConfig(2).setPressPlotFlag = false;
    objectConfig(2).flowPlotFlag = false;
    objectConfig(2).persistentData = [];

    % object 3
    objectConfig(3).enabled = true;
    objectConfig(3).name = 'Organic 1';
    objectConfig(3).type = 5;
    objectConfig(3).comPort = 'COM10';
    objectConfig(3).currentTempPlotFlag = false;
    objectConfig(3).setTempPlotFlag = false;
    objectConfig(3).currentPressPlotFlag = false;
    objectConfig(3).setPressPlotFlag = false;
    objectConfig(3).flowPlotFlag = true;
    objectConfig(3).persistentData = [];

    % object 4
    objectConfig(4).enabled = false;
    objectConfig(4).name = 'Organic 2';
    objectConfig(4).type = 2;
    objectConfig(4).comPort = '';
    objectConfig(4).currentTempPlotFlag = false;
    objectConfig(4).setTempPlotFlag = false;
    objectConfig(4).currentPressPlotFlag = false;
    objectConfig(4).setPressPlotFlag = false;
    objectConfig(4).flowPlotFlag = false;
    objectConfig(4).persistentData = [];
    
    % object 5
    objectConfig(5).enabled = true;
    objectConfig(5).name = 'Pre-heater';
    objectConfig(5).type = 4;
    objectConfig(5).comPort = 'COM4';
    objectConfig(5).currentTempPlotFlag = false;
    objectConfig(5).setTempPlotFlag = false;
    objectConfig(5).currentPressPlotFlag = false;
    objectConfig(5).setPressPlotFlag = false;
    objectConfig(5).flowPlotFlag = false;
    objectConfig(5).persistentData = [];

    % object 6
    objectConfig(6).enabled = true;
    objectConfig(6).name = 'Reactor';
    objectConfig(6).type = 4;
    objectConfig(6).comPort = 'COM11';
    objectConfig(6).currentTempPlotFlag = false;
    objectConfig(6).setTempPlotFlag = false;
    objectConfig(6).currentPressPlotFlag = false;
    objectConfig(6).setPressPlotFlag = false;
    objectConfig(6).flowPlotFlag = false;
    objectConfig(6).persistentData = [];

    % object 7
    objectConfig(7).enabled = true;
    objectConfig(7).name = 'BPR';
    objectConfig(7).type = 11;
    objectConfig(7).comPort = 'COM6';
    objectConfig(7).currentTempPlotFlag = false;
    objectConfig(7).setTempPlotFlag = false;
    objectConfig(7).currentPressPlotFlag = false;
    objectConfig(7).setPressPlotFlag = false;
    objectConfig(7).flowPlotFlag = false;
    objectConfig(7).persistentData = [];

    % object 8
    objectConfig(8).enabled = true;
    objectConfig(8).name = 'Fibre Heater';
    objectConfig(8).type = 4;
    objectConfig(8).comPort = 'COM8';
    objectConfig(8).currentTempPlotFlag = false;
    objectConfig(8).setTempPlotFlag = false;
    objectConfig(8).currentPressPlotFlag = false;
    objectConfig(8).setPressPlotFlag = false;
    objectConfig(8).flowPlotFlag = false;
    objectConfig(8).persistentData = [];

    % object 9 (Rheodyne)
    objectConfig(9).enabled = true;
    objectConfig(9).name = 'Rheodyne';
    objectConfig(9).type = 1;
    objectConfig(9).comPort = 'RHEODYNEDUMMYOBJECT';
    objectConfig(9).currentTempPlotFlag = false;
    objectConfig(9).setTempPlotFlag = false;
    objectConfig(9).currentPressPlotFlag = false;
    objectConfig(9).setPressPlotFlag = false;
    objectConfig(9).flowPlotFlag = false;
    objectConfig(9).persistentData = [];

    % object 10 (PicoLog) (note that type here refers to the PicoLog type -
    % NOT the object type)
    objectConfig(10).enabled = true;
    objectConfig(10).name = 'PicoLog';
    objectConfig(10).type = 2;
    objectConfig(10).comPort = '';
    objectConfig(10).currentTempPlotFlag = false;
    objectConfig(10).setTempPlotFlag = false;
    objectConfig(10).currentPressPlotFlag = false;
    objectConfig(10).setPressPlotFlag = false;
    objectConfig(10).flowPlotFlag = false;
    objectConfig(10).persistentData = [];
    
    % object 11 (Fibre Optic Reflectometer)
    objectConfig(11).enabled = true;
    objectConfig(11).name = 'Fibre Optic Reflectometer (FOR)';
    objectConfig(11).type = 1;
    objectConfig(11).comPort = 'COM9';
    objectConfig(11).currentTempPlotFlag = false;
    objectConfig(11).setTempPlotFlag = false;
    objectConfig(11).currentPressPlotFlag = false;
    objectConfig(11).setPressPlotFlag = false;
    objectConfig(11).flowPlotFlag = false;
    objectConfig(11).persistentData = [];
    
    
    % tc08Types -----------------------------------------------------------
    
    % configuration for different Pico TC-08 protocols
    
    % empty first item
    tc08Types(1).name = '';
    tc08Types(1).connectCommand = '';
    tc08Types(1).disconnectCommand = '';
    tc08Types(1).queryCommand = '';
    tc08Types(1).filePath = '';

    % default data collection method - fast but requires the PicoLog
    % application to be open
    tc08Types(2).name = 'TC-08 (any - DDE)';
    tc08Types(2).connectCommand = 'tc08connect';
    tc08Types(2).disconnectCommand = 'tc08connect';
    tc08Types(2).queryCommand = 'tc08query';
    tc08Types(2).filePath = 'C:\Program Files\Pico Technology\Pico Full\plw32.exe';

    % slower method for USB TC-08 only (couldn't get a similar method for
    % serial TC-08 working properly)
    tc08Types(3).name = 'USB TC-08 (slow)';
    tc08Types(3).connectCommand = 'usbtc08connect';
    tc08Types(3).disconnectCommand = 'usbtc08disconnect';
    tc08Types(3).queryCommand = 'usbtc08query';
    tc08Types(3).filePath = 'C:\Program Files\Pico\Drivers\win32\';
    
    
    % tc08Config ----------------------------------------------------------
    
    % configuration for all of the channels
    
    % channel 1
    tc08Config(1).name = 'Reactor internal';
    tc08Config(1).units = 'C';
    tc08Config(1).plotFlag = 0;
    tc08Config(1).ddeCalibration = 0;
    tc08Config(1).dllCalibration = 0;
    tc08Config(1).type = 'K';
    tc08Config(1).slope = 1;
    tc08Config(1).offset = 0;

    % channel 2
    tc08Config(2).name = 'Fibre internal';
    tc08Config(2).units = 'C';
    tc08Config(2).plotFlag = 1;
    tc08Config(2).ddeCalibration = 0;
    tc08Config(2).dllCalibration = 0;
    tc08Config(2).type = 'K';
    tc08Config(2).slope = 1;
    tc08Config(2).offset = 0;

    % channel 3
    tc08Config(3).name = 'BPR inlet';
    tc08Config(3).units = 'C';
    tc08Config(3).plotFlag = 1;
    tc08Config(3).ddeCalibration = 0;
    tc08Config(3).dllCalibration = 0;
    tc08Config(3).type = 'K';
    tc08Config(3).slope = 1;
    tc08Config(3).offset = 0;

    % channel 4
    tc08Config(4).name = 'CO2 Pump Pressure';
    tc08Config(4).units = 'bar';
    tc08Config(4).plotFlag = 1;
    tc08Config(4).ddeCalibration = 0;
    tc08Config(4).dllCalibration = 0;
    tc08Config(4).type = 'X';
    tc08Config(4).slope = 5.1575;
    tc08Config(4).offset = 0.2821;

    % channel 5
    tc08Config(5).name = 'CO2 BPR Pressure';
    tc08Config(5).units = 'bar';
    tc08Config(5).plotFlag = 0;
    tc08Config(5).ddeCalibration = 0;
    tc08Config(5).dllCalibration = 0;
    tc08Config(5).type = 'X';
    tc08Config(5).slope = 5.85;
    tc08Config(5).offset = 0;

    % channel 6
    tc08Config(6).name = 'Pre-Organic Pressure';
    tc08Config(6).units = 'bar';
    tc08Config(6).plotFlag = 1;
    tc08Config(6).ddeCalibration = 0;
    tc08Config(6).dllCalibration = 0;
    tc08Config(6).type = 'X';
    tc08Config(6).slope = 6.9629;
    tc08Config(6).offset = -0.7684;

    % channel 7
    tc08Config(7).name = 'BPR Pressure';
    tc08Config(7).units = 'bar';
    tc08Config(7).plotFlag = 1;
    tc08Config(7).ddeCalibration = 0;
    tc08Config(7).dllCalibration = 0;
    tc08Config(7).type = 'X';
    tc08Config(7).slope = 5.0051;
    tc08Config(7).offset = -0.0473;

    % channel 8
    tc08Config(8).name = 'H2 Pressure';
    tc08Config(8).units = 'bar';
    tc08Config(8).plotFlag = 0;
    tc08Config(8).ddeCalibration = 0;
    tc08Config(8).dllCalibration = 0;
    tc08Config(8).type = 'X';
    tc08Config(8).slope = 6.9209;
    tc08Config(8).offset = -0.0598;
    
    % channel 9 (actually a calculated parameter)
    tc08Config(9).name = 'Pressure Drop';
    tc08Config(9).units = 'bar';
    tc08Config(9).plotFlag = 1;
    tc08Config(9).ddeCalibration = 0;
    tc08Config(9).dllCalibration = 0;
    tc08Config(9).type = '';
    tc08Config(9).slope = 1;
    tc08Config(9).offset = 0;
    
    % channel 10 (actually a calculated parameter)
    tc08Config(10).name = 'H2 Overpressure';
    tc08Config(10).units = 'bar';
    tc08Config(10).plotFlag = 0;
    tc08Config(10).ddeCalibration = 0;
    tc08Config(10).dllCalibration = 0;
    tc08Config(10).type = '';
    tc08Config(10).slope = 1;
    tc08Config(10).offset = 0;
    
else
    % need to check the supplied arguments - note that the field names of
    % guiConfig are not checked on purpose for the ease of addition of new
    % features
    if isstruct(guiConfig)
        % checks the timers
        if ~isnumber(guiConfig.picoTimerPeriod) || guiConfig.picoTimerPeriod <= 0
            % errors
            error('guiConfig.picoTimerPeriod must be a real scalar number larger than 0.')
            
        elseif ~isnumber(guiConfig.serialTimerPeriod) || guiConfig.serialTimerPeriod <= 0
            % errors
            error('guiConfig.serialTimerPeriod must be a real scalar number larger than 0.')
        end
        
    else
        % errors
        error('guiConfig must be a structure.')
    end
    
    % checks the objectTypes
    if isstruct(objectTypes)
        % checks all of the arguments (end part commented out so that new
        % fields can be more easily added)
        if ~iscellstr({objectTypes.name}) %&& isequal(fieldnames.objectTypes, {'objectType', 'objectCommand', 'connectCommand', 'disconnectCommand', 'currentTempCommand' , 'readSetTempCommand', 'writeSetTempCommand', 'currentPressCommand', 'readSetPressCommand' ,'writeSetPressCommand', 'readFlowCommand', 'writeFlowCommand', 'readAllCommand', 'startCommand', 'stopCommand', 'mainCommand', 'moreCommand', 'statusCommand', 'testCommand'})
            % errors
            error('objectTypes.name must be all be strings.')
            
        elseif ~iscellstr({objectTypes.objectCommand})
            % errors
            error('objectTypes.objectCommand must be all be strings.')
            
        elseif ~iscellstr({objectTypes.connectCommand})
            % errors
            error('objectTypes.connectCommand must be all be strings.')
            
        elseif ~iscellstr({objectTypes.disconnectCommand})
            % errors
            error('objectTypes.disconnectCommand must all be strings.')
            
        elseif ~iscellstr({objectTypes.currentTempCommand})
            % errors
            error('objectTypes.currentTemp must all be strings.')
            
        elseif ~iscellstr({objectTypes.readSetTempCommand})
            % errors
            error('objectTypes.readSetTempCommand must all be strings.')
            
        elseif ~iscellstr({objectTypes.writeSetTempCommand})
            % errors
            error('objectTypes.writeSetTempCommand must all be strings.')
                        
        elseif ~iscellstr({objectTypes.currentPressCommand})
            % errors
            error('objectTypes.currentPressCommand must all be strings.')
            
        elseif ~iscellstr({objectTypes.readSetPressCommand})
            % errors
            error('objectTypes.readSetPressCommand must all be strings.')
            
        elseif ~iscellstr({objectTypes.writeSetPressCommand})
            % errors
            error('objectTypes.writeSetPressCommand must all be strings.')
            
        elseif ~iscellstr({objectTypes.readFlowCommand})
            % errors
            error('objectTypes.readFlowCommand must all be strings.')
            
        elseif ~iscellstr({objectTypes.writeFlowCommand})
            % errors
            error('objectTypes.writeFlowCommand must all be strings.')
            
        elseif ~iscellstr({objectTypes.readAllCommand})
            % errors
            error('objectTypes.readAllCommand must all be strings.')
            
        elseif ~iscellstr({objectTypes.startCommand})
            % errors
            error('objectTypes.startCommand must all be strings.')
            
        elseif ~iscellstr({objectTypes.stopCommand})
            % errors
            error('objectTypes.stopCommand must all be strings.')
            
        elseif ~iscellstr({objectTypes.mainCommand})
            % errors
            error('objectTypes.mainCommand must all be strings.')
            
        elseif ~iscellstr({objectTypes.statusCommand})
            % errors
            error('objectTypes.statusCommand must all be strings.')
            
        elseif ~iscellstr({objectTypes.testCommand})
            % errors
            error('objectTypes.testCommand must all strings.')
        end
    else
        % errors
        error('objectTypes must be a structure.')
    end
    
    % checks the objectConfig
    if isstruct(objectConfig) %&& isequal(fieldnames(objectConfig), {'enabled'; 'name'; 'comPort'; 'currentTempPlotFlag'; 'setTempPlotFlag'; 'currentPressPlotFlag'; 'setPressPlotFlag'; 'flowPlotFlag'})
        % checks all of the arguments
        if ~isalogical([objectConfig.enabled])
            % errors
            error('objectConfig.enabled must be either 0 or 1.')
            
        elseif ~iscellstr({objectConfig.name})
            % errors
            error('objectConfig.name must all be strings.')
            
        elseif ~ispositiveinteger([objectConfig.type])
            % errors
            error('objectConfig.types must all be positive non-zero integers.')
            
        elseif ~iscellstr({objectConfig.comPort})
            % errors
            error('objectConfig.comPort must all be strings.')
            
        elseif ~isalogical([objectConfig.currentTempPlotFlag])
            % errors
            error('objectConfig.currentTempPlotFlag must be either 0 or 1.')
            
        elseif ~isalogical([objectConfig.setTempPlotFlag])
            % errors
            error('objectConfig.setTempPlotFlag must be either 0 or 1.')
            
        elseif ~isalogical([objectConfig.currentPressPlotFlag])
            % errors
            error('objectConfig.currentPressPlotFlag must be either 0 or 1.')
            
        elseif ~isalogical([objectConfig.setPressPlotFlag])
            % errors
            error('objectConfig.setPressPlotFlag must be either 0 or 1.')
            
        elseif ~isalogical([objectConfig.flowPlotFlag])
            % errors
            error('objectConfig.flowPlotFlag must be either 0 or 1.')
        end
        
    else    
        % errors
        error('objectConfig must be a structure.')
    end
    
    % checks the tc08Types
    if isstruct(tc08Types) && isequal(fieldnames(tc08Types), {'name'; 'connectCommand'; 'disconnectCommand'; 'queryCommand'; 'filePath'})
        % checks all of the arguments
        if ~iscellstr({tc08Types.name})
            % errors
            error('tc08Types.name must all be strings.')
            
        elseif ~iscellstr({tc08Types.connectCommand})
            % errors
            error('tc08Types.connectCommand must all be strings.')
            
        elseif ~iscellstr({tc08Types.disconnectCommand})
            % errors
            error('tc08Types.disconnectCommand must all be strings.')
            
        elseif ~iscellstr({tc08Types.queryCommand})
            % errors
            error('tc08Types.queryCommand must all be strings.')
            
        elseif ~iscellstr({tc08Types.filePath})
            % errors
            error('tc08Types.filePath must all be strings.')
        end
        
    else
        % errors
        error('tc08Types must be a structure with the fieldnames: name, connectCommand, disconnectCommand, queryCommand and filePath.')
    end
    
    % checks the tc08Config
    if isstruct(tc08Config) && isequal(fieldnames(tc08Config), {'name'; 'units'; 'plotFlag'; 'ddeCalibration'; 'dllCalibration'; 'type'; 'slope'; 'offset'})
        % checks all of the arguments
        if ~iscellstr({tc08Config.name})
            % errors
            error('tc08Config.name must all be strings.')
            
        elseif ~iscellstr({tc08Config.units})
            % errors
            error('tc08Config.units must all be strings.')
            
        elseif ~isalogical([tc08Config.plotFlag])
            % errors
            error('tc08Config.plotFlag must be either 0 or 1.')
            
        elseif ~isalogical([tc08Config.ddeCalibration])
            % errors
            error('tc08Config.ddeCalibration must be either 0 or 1.')
            
        elseif ~isalogical([tc08Config.dllCalibration])
            % errors
            error('tc08Config.dllCalibration must be either 0 or 1.')
            
        elseif ~iscellstr({tc08Config.type})
            % errors
            error('tc08Config.type must all be strings.')
            
        elseif ~isnumeric([tc08Config.slope])
            % errors
            error('tc08Config.slope must be numeric.')
            
        elseif ~isnumeric([tc08Config.offset])
            % errors
            error('tc08Config.offset must be numeric.')
        end
        
    else
        % errors
        error('tc08Config must be a structure with the fieldnames: name, units, plotFlag, type, slope, and offset.')
    end
end

% saves the data
save(filename, 'guiConfig', 'objectTypes', 'objectConfig', 'tc08Types', 'tc08Config')

Contact us