Code covered by the BSD License  

Highlights from
Knauer pump RS232 communication

Knauer pump RS232 communication

by

 

Functions for communicating with Knauer pumps via RS232.

knauerpumpobjcomm(serialObject, type, command)
function output = knauerpumpobjcomm(serialObject, type, command)
% KNAUERPUMPOBJCOMM Reads and writes data from Knauer pumps
% knauerpumpobjcomm(serialObject, type, command) reads from or writes
% information to Knauer pumps connected via RS232 serial ports.
% serialObject is the valid serial object, type is 'read' or 'write',  and
% command the command to be sent (string). Automatically leaves a 0.15 s
% pause after any commands where there is no response expected to prevent
% communications issues. (PAUSE HAS NOT BEEN OPTIMISED)

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

% error checking here
if ~isa(serialObject, 'serial') || ~isvalid(serialObject) || ~strcmp(serialObject.Status, 'open')
    
    % the serial object must be valid and open to send or receive data
    error('serialObject must be a valid open serial object.')
    
elseif ~isequal(type, 'read') && ~isequal(type, 'write')
    
    % errors
    error('type must be "read" or "write".')
    
elseif ~ischar(command) || ~isvector(command) || any(command == ' ')
    
    % string must only be a single "word"
    error('command must a string with no spaces.')
end

% sees if a colon has been specified
commandColonPosition = strfind(command, ':');

% if there's a colon in there then check there's a valid number after it
if ~isempty(commandColonPosition)
    
    % if there's a colon, then you also can't put a ? at the end
    
    if command(end) == '?'
        
        % complain
        error('If '':'' is present, then cannot have a ''?'' at the end of the command.')
    end
    
    % convert it to a number
    commandNum = str2double(command(commandColonPosition + 1:end));
    
    % checks that number is OK
    if isempty(commandNum) || isnan(commandNum) || isinf(commandNum) || ~isreal(commandNum) || commandNum < 0 || commandNum ~= round(commandNum)
        
        % complain
        error('If a number is specified, it must be a valid positive integer.')
    end
    
    % if it got that far then define the commandWord for further checking
    % later
    commandWord = command(1:commandColonPosition - 1);    

elseif command(end) == '?'
    
    % if it was a read command, then return that, less the '?'
    commandWord = command(1:end - 1);
    
else
    
    % then it was neither of those, and the commandWord is the command
    % as-is
    commandWord = command;
end

% flushes everything in the buffer
fread(serialObject, serialObject.BytesAvailable);

% sends command
fprintf(serialObject, command, 'async')

% gets the response up to the terminator, discard it
response = fgetl(serialObject);

% if no response, then there was a problem
if isempty(response)
    
    % error
    error('No response to command.')
end    

% now parse the response - find the location of the colon
responseColonPosition = strfind(response, ':');

% complain if it wasn't there
if isempty(responseColonPosition)
    
    % complain
    error('Unexpected response from Knauer pump - no '':''.')
    
else
    
    % it's OK, so we can define the word that the instrument sent
    responseWord = response(1:responseColonPosition - 1);
end

% if it was an error...
if strcmp(responseWord, 'ERROR')
    
    % then say so
    error(['Error response from Knauer pump - code ', response(responseColonPosition + 1:end)])
end

% check that it matched the initial command (case-insensitive check - the
% pump appears to be case insensitive)
if ~strcmpi(commandWord, responseWord)
    
    % problem
    error('Unexpected response from Knauer pump (''%s'') - does not match initial command.', response)
end

% if reading data, check the response
if strcmp(type, 'read')
    
    % the number is nearly always just a number, but ERRORS returns the
    % last five error codes as x,x,x,x,x so we need to cover that
    % eventuality - most of the timer this is overkill but this
    % futureproofs it
    response = textscan(response(responseColonPosition + 1:end), '%f', 'Delimiter', ',');
    
    % annoying formatting (thanks MATLAB) - turns it into a horizontal
    % vector
    output = response{1}';
    
elseif strcmp(type, 'write')
    
    % need to check it was written... the response is command:OK if it was
    if ~strcmp(response(responseColonPosition + 1:end), 'OK')
        
        % error
        error('Command was not written to pump - no OK was received.')
    end
    
end

Contact us