Something went wrong on our end
-
Tim Stadtmann authored
On linux/mac: MATLAB's virtual serial port implementation On windows: Instrument Control toolbox
Tim Stadtmann authoredOn linux/mac: MATLAB's virtual serial port implementation On windows: Instrument Control toolbox
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
btBrickIO.m 11.31 KiB
%btBrickIO Bluetooth interface between MATLAB and the brick
%
% Methods::
%
% btBrickIO Constructor, initialises and opens the bluetooth connection
% delete Destructor, closes the bluetooth connection
%
% open Open a bluetooth connection to the brick
% close Close the bluetooth connection to the brick
% read Read data from the brick through bluetooth
% write Write data to the brick through bluetooth
%
% Example::
% btbrick = btBrickIO(1,'/dev/rfcomm0')
%
% Notes::
% - Connects to the bluetooth module on the host through a serial
% connection. Hence be sure that a serial connection to the bluetooth
% module can be made. Also be sure that the bluetooth module can be paired
% to the brick before MATLAB is opened.
% - Works under mac and potentially linux (have yet to find a suitable
% bluetooth device that can pair with the brick under linux).
% - Does not work under windows (will need to either virtualise the serial
% bluetooth port or use the instrumentation and control toolbox BrickIO
% version).
classdef btBrickIO < BrickIO
properties
% debug input
debug;
% bluetooth serial port (used if backend == 'serial')
serialPort;
% bluetooth brick device name (used if backend == 'instrumentControl')
deviceName;
% bluetooth connection channel (used if backend == 'instrumentControl')
channel;
% time-out period in seconds (if 0, no time-out)
timeOut;
% use implementation based on the serial-connection implementation by MATLAB (should
% work on mac & linux) or based on the Instrumentation & Control Toolbox
% (should work on windows) (-> 'serial'|'instrumentControl')
backend;
end
properties (Access = 'protected')
% connection handle
handle
end
methods
function brickIO = btBrickIO(brickIO, varargin)
%btBrickIO.btBrickIO Create a btBrickIO object
%
% btbrick = btBrickIO(debug,serialPort) is an object which
% initialises and opens a bluetooth connection between MATLAB
% and the brick.
p = inputParser();
p.KeepUnmatched = 1;
p.addOptional('debug', 0);
p.addOptional('serPort', '/dev/rfcomm0');
p.addOptional('deviceName', 'EV3');
p.addOptional('channel', 1);
p.addOptional('timeOut', 10);
if(ispc == 1)
p.addOptional('backend', 'instrumentControl');
else
p.addOptional('backend', 'serial');
end
p.parse(varargin{:});
brickIO.debug = p.Results.debug;
brickIO.serialPort = p.Results.serPort;
brickIO.deviceName = p.Results.deviceName;
brickIO.channel = p.Results.channel;
brickIO.timeOut = p.Results.timeOut;
brickIO.backend = p.Results.backend;
if brickIO.debug > 0
fprintf('btBrickIO init\n');
end
% Set the connection handle
try
if strcmp(brickIO.backend, 'serial')
brickIO.handle = serial(brickIO.serialPort);
else
brickIO.handle = Bluetooth(brickIO.deviceName,brickIO.channel);
end
catch ME
if ~isempty(strfind(ME.identifier, 'invalidPORT'))
% Throw a clean InvalidSerialPort to avoid confusion in upper layers
msg = 'Couldn''t connect to BT-device because given serial port is invalid.';
id = [ID(), ':', 'InvalidSerialPort'];
throw(MException(id, msg));
else
% Throw combined error because error did not happen due to known reasons...
msg = 'Unknown error occurred while creating serial-port-object for BT connection.';
id = [ID(), ':', 'UnknownError'];
newException = MException(id, msg);
newException = addCause(newException, ME);
throw(newException);
end
end
% Open the connection handle
brickIO.open;
end
function delete(brickIO)
%btBrickIO.delete Delete the btBrickIO object
%
% delete(brickIO) closes the bluetooth connection handle
if brickIO.debug > 0
fprintf('btBrickIO delete\n');
end
% Disconnect
try
brickIO.close;
catch
% Connection already closed (probably due to an error) - do nothing
end
end
function open(brickIO)
%btBrickIO.open Open the btBrickIO object
%
% btBrickIO.open() opens the bluetooth connection to the brick
% using fopen.
if brickIO.debug > 0
fprintf('btBrickIO open\n');
end
% Open the bt handle
try
fopen(brickIO.handle);
catch ME
if strcmp(ME.identifier, 'MATLAB:serial:fopen:opfailed')
% Throw only clean CommError to avoid confusion in upper layers
msg = 'Failed to open connection to Brick via Bluetooth.';
id = [ID(), ':', 'CommError'];
throw(MException(id, msg));
else
% Throw combined error because error did not happen due to communication
% failure
msg = 'Unknown error occurred while connecting to the Brick via Bluetooth.';
id = [ID(), ':', 'UnknownError'];
newException = MException(id, msg);
newException = addCause(newException, ME);
throw(newException);
end
end
end
function close(brickIO)
%btBrickIO.close Close the btBrickIO object
%
% btBrickIO.close() closes the bluetooth connection the brick
% using fclose.
if brickIO.debug > 0
fprintf('btBrickIO close\n');
end
try
% Close the close handle
fclose(brickIO.handle);
catch ME
% Throw combined error because error did not happen due to communication
% failure
msg = 'Unknown error occurred while disconnecting from the Brick via Bluetooth.';
id = [ID(), ':', 'UnknownError'];
newException = MException(id, msg);
newException = addCause(newException, ME);
throw(newException);
end
end
function rmsg = read(brickIO)
%btBrickIO.read Read data from the btBrickIO object
%
% rmsg = btBrickIO.read() reads data from the brick through
% bluetooth via fread and returns the data in uint8 format.
if brickIO.debug > 0
fprintf('btBrickIO read\n');
end
try
% Get the number of bytes to be read from the bt handle
nLength = fread(brickIO.handle,2);
% Read the remaining bytes
rmsg = fread(brickIO.handle,double(typecast(uint8(nLength),'uint16')));
catch ME
if strcmp(ME.identifier, 'MATLAB:serial:fread:opfailed')
% Throw only clean CommError to avoid confusion in upper layers
msg = 'Failed to read data from Brick via Bluetooth.';
id = [ID(), ':', 'CommError'];
throw(MException(id, msg));
else
% Throw combined error because error did not happen due to known reasons...
msg = 'Unknown error occurred while reading data from the Brick via BT.';
id = [ID(), ':', 'UnknownError'];
newException = MException(id, msg);
newException = addCause(newException, ME);
throw(newException);
end
end
% Append the reply size to the return message
rmsg = uint8([nLength' rmsg']);
end
function write(brickIO,wmsg)
%btBrickIO.write Write data to the btBrickIO object
%
% btBrickIO.write(wmsg) writes data to the brick through
% bluetooth.
%
% Notes::
% - wmsg is the data to be written to the brick via bluetooth
% in uint8 format.
if brickIO.debug > 0
fprintf('btBrickIO write\n');
end
try
% Write to the bluetooth handle
fwrite(brickIO.handle,wmsg);
catch ME
if strcmp(ME.identifier, 'MATLAB:serial:fwrite:opfailed')
% Throw only clean CommError to avoid confusion in upper layers
msg = 'Failed to send data to Brick via Bluetooth.';
id = [ID(), ':', 'CommError'];
throw(MException(id, msg));
else
% Throw combined error because error did not happen due to known reasons...
msg = 'Unknown error occurred while sending data to the Brick via BT.';
id = [ID(), ':', 'UnknownError'];
newException = MException(id, msg);
newException = addCause(newException, ME);
throw(newException);
end
end
end
function set.timeOut(brickIO, timeOut)
if ~isnumeric(timeOut) || timeOut < 0
error(ID(), 'timeOut-period of Bluetooth-handle can only be set to positive numerical values.');
end
brickIO.timeOut = timeOut;
if timeOut == 0
brickIO.handle.Timeout = 9999999; % MATLAB.serial seems to have no option to disable timeout
end
end
function set.backend(brickIO, backend)
if ~strcmp(backend, 'serial')
if ~strcmp(backend, 'instrumentControl')
msg = 'btBrickIO''s backend-parameter has to be either ''serial'' or ''instrumentControl''.';
id = [ID(), ':', 'InvalidParameter'];
throw(MException(id, msg));
elseif ~license('test', 'instr_control_toolbox')
msg = 'Cannot use Instrument-Control-Toolbox for Bluetooth: Toolbox not installed.';
id = [ID(), ':', 'AssetNotAvailable'];
throw(MException(id, msg));
end
end
brickIO.backend = backend;
end
end
end