Something went wrong on our end
-
Tim Stadtmann authored
Fixes issue #45.
Tim Stadtmann authoredFixes issue #45.
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
CommunicationInterface.m 82.75 KiB
classdef CommunicationInterface < handle
% Brick Interface to Lego Minstorms EV3 brick
%
% Methods::
% brick Constructor, establishes communications
% delete Destructor, closes connection
% send Send data to the brick
% receive Receive data from the brick
%
%
% uiReadVBatt Returns battery level as a voltage
% uiReadLBatt Returns battery level as a percentage
%
% drawTest Shows the drawing capabilities of the brick
%
%
% soundTest @MMI: Returns state of speaker
% soundReady @MMI: Halts the execution of commands on Brick until speakers are ready
% soundPlayTone Plays a tone at a volume with a frequency and duration
% soundStopTone @MMI: Stops current sound playback
%
% beep Plays a beep tone with volume and duration
% playThreeTone Plays three tones one after the other
%
%
% inputDeviceList @MMI: Returns list of sensor types on each port
% inputDeviceGetName Returns the device name at a layer and NO
% inputDeviceGetTypeMode @MMI: Returns type and mode of device at a layer and NO
% inputDeviceSetTypeMode @MMI: Sets type and mode of device which is recognized by old
% type and mode.
% inputDeviceGetModeName @MMI: Returns the device's mode at a layer and NO
% inputDeviceGetConnection @MMI: Returns the connection type (=sensor type) at a layer and NO
% inputDeviceGetMinMax @MMI: Returns the min and max SI value of device at a layer and NO
% inputDeviceGetChanges @MMI: Returns positive changes(=button releases) since last clear at a layer and NO
% inputDeviceGetFormat @MMI: Returns no. of datasets, returned data type in
% active sensor mode, no. of sensor modes and no. of
% visible sensor modes at a layer and NO
% inputDeviceGetBumps @MMI: Returns negatives changes (=button presses) since last clear at a layer and NO
% inputDeviceSymbol Returns the symbol for the device at a layer, NO and mode
% inputDeviceClrChanges @MMI: Clears changes(&bumps) at a layer and NO
% inputDeviceClrAll Clears all the sensor data at a layer
% inputReady @MMI: Halts the execution of commands on Brick until given devices are ready
% inputTest @MMI: Returns the state of the device at a layer and NO
% inputRead @MMI: Reads a connected sensor at a layer, NO, type and mode in percentage
% inputReadSI Reads a connected sensor at a layer, NO, type and mode in SI units
%
% plotSensor Plots a sensor readings over time
% displayColor Displays the color from a color sensor
%
%
% outputStop Stops motor at a layer, NOS and brake
% outputStopAll Stops all the motors
% outputPower Sets motor output power at a layer, NOS and speed
% outputSpeed @MMI: Sets motor output speed at a layer, NOS and speed
% outputStart Starts motor at a layer, NOS and speed
% outputTest Returns the state of the motor at a layer and NOS
% outputStepSpeed Moves a motor to set position with layer, NOS, speed,
% ramp up angle, constant angle, ramp down angle and brake
% outputStepPower @MMI: Moves a motor to set position with layer, NOS, power,
% ramp up angle, constant angle, ramp down angle and brake
% outputTimeSpeed @MMI: Moves a motor for set time at a layer, NOS, speed,
% ramp up time, constant time, ramp down time and brake
% outputTimePower @MMI: Moves a motor for set time at a layer, NOS, power,
% ramp up time, constant time, ramp down time and brake
% outputStepSync @MMI: Moves two motors synchronized at a layer, NOS,
% power, turn ratio, tacho limit, and brake
% outputTimeSync @MMI: Moves two motors synchronized at a layer, NOS,
% power, turn ratio, time limit, and brake
% outputClrCount Clears a motor tachometer at a layer and NOS
% outputGetCount Returns the tachometer at a layer and NO
% outputReset @MMI:
% outputRead @MMI:
% outputPolarity @MMI: Sets a motor's polarity ('rotational direction')
% outputReady @MMI: Halts the execution of commands on Brick until given
% motors have stopped
%
%
% comTest @MMI: Returns state of communication adapter of device.
% comReady @MMI: Halts the execution of commands of Brick until
% communication adapter is ready
% comGetBrickName Returns the name of the brick
% comSetBrickName Sets the name of the brick
% comGetMACAddress@MMI: Returns the MAC-address of the brick
% comGetBTID @MMI: Returns BT-address information
%
% mailBoxWrite Writes a mailbox message from the brick to another device
% fileUpload Uploads a file to the brick
% fileDownload Downloads a file from the brick
% listFiles Lists files on the brick from a directory
% createDir Creates a directory on the brick
% deleteFile Deletes a file from the brick
% writeMailBox Writes a mailbox message to the brick
% readMailBox Reads a mailbox message sent from the brick
%
%
% threeToneByteCode Generates the bytecode for the playThreeTone function
%
% Example::
% b = Brick('ioType','usb')
% b = Brick('ioType','wifi','wfAddr','192.168.1.104','wfPort',5555,'wfSN','0016533dbaf5')
% b = Brick('ioType','bt','serPort','/dev/rfcomm0')
properties
% Debug
debug;
end
properties (Dependent)
% Time-out period in seconds (if 0, no time-out)
timeOut;
end
properties (SetAccess = private)
% IO connection type
ioType;
% Bluetooth brick device name
btDevice = '';
% Bluetooth brick communication channel
btChannel = 0;
% Wifi brick IP address
wfAddr = '';
% Wifi brick TCP port
wfPort = '';
% Brick serial number
wfSN = '';
% Bluetooth serial port
serPort;
end
properties (Hidden, Access = private)
% Connection handle
conn;
end
methods
%% Constructor, Destructor, Setter...
function commInterface = CommunicationInterface(varargin)
% Brick.Brick Create a Brick object
%
% b = Brick(OPTIONS) is an object that represents a connection
% interface to a Lego Mindstorms EV3 brick.
%
% Options::
% 'debug',D Debug level, show communications packet
% 'ioType',P IO connection type, either usb, wifi or bt
% 'btDevice',bt Bluetooth brick device name
% 'btChannel',cl Bluetooth connection channel
% 'wfAddr',wa Wifi brick IP address
% 'wfPort',pr Wifi brick TCP port, default 5555
% 'wfSN',sn Wifi brick serial number (found under Brick info on the brick OR through sniffing the UDP packets the brick emits on port 3015)
% 'serPort',SP Serial port connection
%
% Notes::
% - Can connect through: usbBrickIO, wfBrickIO, btBrickIO or
% instrBrickIO.
% - For usbBrickIO:
% b = Brick('ioType','usb')
% - For wfBrickIO:
% b = Brick('ioType','wifi','wfAddr','192.168.1.104','wfPort',5555,'wfSN','0016533dbaf5')
% - For btBrickIO:
% b = Brick('ioType','bt','serPort','/dev/rfcomm0')
% - For instrBrickIO (wifi)
% b = Brick('ioType','instrwifi','wfAddr','192.168.1.104','wfPort',5555,'wfSN','0016533dbaf5')
% - For instrBrickIO (bluetooth)
% b = Brick('ioType','instrbt','btDevice','EV3','btChannel',1)
commInterface.setProperties(varargin{:});
% % Init the properties
% opt.debug = 0;
% opt.btDevice = 'EV3';
% opt.btChannel = 1;
% opt.wfAddr = '192.168.1.104';
% opt.wfPort = 5555;
% opt.wfSN = '0016533dbaf5';
% opt.ioType = 'usb';
% opt.serPort = '/dev/rfcomm0';
%
% % Read in the options
% opt = tb_optparse(opt, varargin);
% commInterface.debug = opt.debug;
% commInterface.ioType = opt.ioType;
try
if(strcmp(commInterface.ioType,'usb')) % USB
commInterface.conn = usbBrickIO(commInterface.debug);
elseif(strcmp(commInterface.ioType,'wifi')) % WiFi
commInterface.wfAddr = opt.wfAddr;
commInterface.wfPort = opt.wfPort;
commInterface.wfSN = opt.wfSN;
commInterface.conn = wfBrickIO(commInterface.debug,commInterface.wfAddr,commInterface.wfPort,commInterface.wfSN);
elseif(strcmp(commInterface.ioType,'bt')) % Bluetooth
% commInterface.serPort = opt.serPort;
commInterface.conn = btBrickIO(commInterface.debug,commInterface.serPort);
elseif(strcmp(commInterface.ioType,'instrwifi')) % Instrumentation and Control: WiFi
commInterface.wfAddr = opt.wfAddr;
commInterface.wfPort = opt.wfPort;
commInterface.wfSN = opt.wfSN;
commInterface.conn = instrBrickIO(commInterface.debug,'wf',commInterface.wfAddr,commInterface.wfPort,commInterface.wfSN);
elseif(strcmp(commInterface.ioType,'instrbt')) % Instrumentation and Control: Bluetooth
commInterface.btDevice = opt.btDevice;
commInterface.btChannel = opt.btChannel;
commInterface.conn = instrBrickIO(commInterface.debug,'bt',commInterface.btDevice,commInterface.btChannel);
end
catch ME
commInterface.conn = [];
rethrow(ME);
end
end
function delete(brick)
% Brick.delete Delete the Brick object
%
% delete(b) closes the connection to the brick
if isa(brick.conn, 'handle') && isvalid(brick.conn)
brick.conn.delete();
end
end
function set.debug(brick, debug)
% If debug is set in this layer, also set BrickIO.debug in lower layer
brick.debug = debug;
brick.conn.debug = debug;
end
function set.timeOut(brick, timeOut)
if ~isnumeric(timeOut) || timeOut < 0
error(ID(), 'timeOut-period of USB-handle can only be set to positive numerical values.');
end
brick.conn.timeOut = timeOut;
end
function timeOut = get.timeOut(brick)
timeOut = brick.conn.timeOut;
end
function setProperties(brick, varargin)
p = inputParser();
p.KeepUnmatched = true;
% Set default values
defaultIOType = 'usb';
defaultSerPort = '/dev/rfcomm0';
defaultDebug = false;
% Define anonymous function that will return whether given value in varargin is valid
%validTypes = ;
checkIOType = @(x) ismember(x, {'usb', 'bt'});
checkDebug = @(x) isBool(x);
% Add parameters
p.addRequired('ioType', checkIOType);
p.addOptional('serPort', defaultSerPort);
p.addOptional('debug', defaultDebug, checkDebug);
% Parse input...
p.parse(varargin{:});
% Set properties
brick.ioType = p.Results.ioType;
brick.serPort = p.Results.serPort;
brick.debug = p.Results.debug;
end
%% Commands
% Methods in this block each correspond to a certain opCode which is implemented in the
% EV3 firmware -> each method creates one packet and sends it.
function voltage = uiReadVbatt(brick)
% Brick.uiReadVbatt Return battery level (voltage)
%
% voltage = uiReadVbatt returns battery level as a voltage. (DATAF)
%
% Example::
% voltage = b.uiReadVbatt()
cmd = Command();
cmd.addHeaderDirectReply(42,4,0);
cmd.opUI_READ_GET_VBATT(0);
cmd.addLength();
brick.send(cmd);
% receive the command
reply = brick.receive()';
msg = reply.msg;
voltage = typecast(uint8(msg(6:9)),'single');
if brick.debug > 0
fprintf('Battery voltage: %.02fV\n', voltage);
end
end
function level = uiReadLbatt(brick)
% Brick.uiReadLbatt Return battery level (percentage)
%
% Brick.uiReadLbatt() returns battery level as a
% percentage from 0 to 100%. (DATA8)
%
% Example::
% level = b.uiReadLbatt()
cmd = Command();
cmd.addHeaderDirectReply(42,1,0);
cmd.opUI_READ_GET_LBATT(0);
cmd.addLength();
brick.send(cmd);
% receive the command
reply = brick.receive()';
msg = reply.msg;
level = msg(6);
if brick.debug > 0
fprintf('Battery level: %d%%\n', level);
end
end
% Implemented @ MMI
function state = soundTest(brick)
% Brick.soundTest Test speaker
%
% Brick.soundTest tests, if a sound file or tone is beeing
% played back.
%
% Notes::
% - state is 0 when ready and 1 when busy (playing tone or
% sound file). (DATA8)
%
% Example::
% b.soundTest()
cmd = Command();
cmd.addHeaderDirectReply(42,1,0);
cmd.opSOUND_TEST(0);
cmd.addLength();
brick.send(cmd);
% receive the state
reply = brick.receive()';
msg = reply.msg;
% speaker state is the 6th byte
state = msg(6);
end
% Implemented @ MMI
function soundReady(brick)
% Brick.soundReady Wait for speaker
%
% Brick.soundReady(layer,nos) halts program until current
% sound playback is done by waiting until reply is received.
%
% Example::
% b.soundReady()
cmd = Command();
cmd.addHeaderDirectReply(42,0,0);
cmd.opSOUND_READY();
cmd.addLength();
brick.send(cmd);
% receive reply
brick.waitForReply();
end
function soundPlayTone(brick, volume, frequency, duration)
% Brick.soundPlayTone Play a tone on the brick
%
% Brick.soundPlayTone(volume,frequency,duration) plays a tone at a
% volume, frequency and duration.
%
% Notes::
% - volume is the tone volume from 0 to 100. (DATA8)
% - frequency is the tone frequency in Hz from 250 - 10000. (DATA16)
% - duration is the tone duration in ms. (DATA16)
%
% Example::
% b.soundPlayTone(5,400,500)
cmd = Command();
cmd.addHeaderDirect(42,0,0);
cmd.opSOUND_TONE(volume,frequency,duration);
cmd.addLength();
brick.send(cmd);
end
% Implemented @ MMI
function soundStopTone(brick)
% Brick.soundStopTone Stop current sound playback
%
% Brick.soundStopTone() stops current sound playbacks.
%
% Example::
% b.soundStopTone()
cmd = Command();
cmd.addHeaderDirect(42,0,0);
cmd.opSOUND_BREAK;
cmd.addLength();
brick.send(cmd);
end
function playThreeTones(brick)
% Brick.playThreeTones Play three tones on the brick
%
% Brick.playThreeTones() plays three tones consequentively on
% the brick with one upload command.
%
% Example::
% b.playThreeTones();
cmd = Command();
cmd.addHeaderDirect(42,0,0);
cmd.opSOUND_TONE(5,440,500);
cmd.opSOUND_READY();
cmd.opSOUND_TONE(10,880,500);
cmd.opSOUND_READY();
cmd.opSOUND_TONE(15,1320,500);
cmd.opSOUND_READY();
cmd.addLength();
% print message
fprintf('Sending three tone message ...\n');
brick.send(cmd);
end
% Implemented @ MMI
function types = inputDeviceList(brick)
% Brick.inputDeviceList Get an array of sensor types
%
% Brick.inputDeviceList() returns an array of sensor types on
% each sensor port.
%
% Notes::
% - types is the 1x4-array of sensor types
%
% Example::
% types = b.inputDeviceList();
%
cmd = Command();
cmd.addHeaderDirectReply(42,5,0);
cmd.opINPUT_DEVICE_LIST(4,0,4);
cmd.addLength();
brick.send(cmd);
% receive the command
reply = brick.receive()';
msg = reply.msg;
% return the type array
types = [msg(6), msg(7), msg(8), msg(9)];
end
function name = inputDeviceGetName(brick,layer,no)
% Brick.inputDeviceGetName Get the input device name
%
% Brick.inputDeviceGetName(layer,no) returns the name of the
% device connected.
%
% Notes::
% - layer is the usb chain layer (usually 0).
% - NO is the output port number from [0..3] or port
% number minus 1.
% - name is the device's name (string)
%
% Example::
% name = b.inputDeviceGetName(0,SensorPort.Sensor1)
cmd = Command();
cmd.addHeaderDirectReply(42,12,0);
cmd.opINPUT_DEVICE_GET_NAME(layer,no,12,0);
cmd.addLength();
brick.send(cmd);
% receive the command
reply = brick.receive()';
msg = reply.msg;
% return the device name
name = sscanf(char(msg(6:end)),'%s');
end
% Implemented @ MMI
function [type, mode] = inputDeviceGetTypeMode(brick,layer,no)
% Brick.inputDeviceGetTypeMode Get the input device's type and
% mode
%
% Brick.inputDeviceGetTypeMode(layer,no) returns the input device's
% type and mode, coded as in Device.m, at a layer and NO.
%
% Notes::
% - layer is the usb chain layer (usually 0).
% - NO is the output port number from [0..3] or port
% number minus 1.
% - type,mode are the type and current mode of the device (each DATA8)
% -> refer to typedata.rcf for more information
%
% Example::
% [type,mode] = b.inputDeviceTypeMode(0,SensorPort.Sensor1)
cmd = Command();
cmd.addHeaderDirectReply(42,2,0);
cmd.opINPUT_DEVICE_GET_TYPEMODE(layer,no,0,1);
cmd.addLength();
brick.send(cmd);
% receive the command
reply = brick.receive()';
msg = reply.msg;
% return the type and mode
type = msg(6);
mode = msg(7);
end
% Implemented @ MMI
function inputDeviceSetTypeMode(brick,oldType,oldMode,newType,newMode)
cmd = Command();
cmd.addHeaderDirectReply(42,0,0);
cmd.opINPUT_DEVICE_SET_TYPEMODE(oldType,oldMode,newType,newMode);
cmd.addLength();
brick.send(cmd);
end
% Implemented @ MMI
function mode = inputDeviceGetModeName(brick,layer,no,mode)
% Brick.inputDeviceGetModeName Get the input device mode name
%
% Brick.inputDeviceGetModeName(layer,no,mode) returns the name of the
% device's mode. (If expected sensor is connected, think of this as
% an enum to string conversion.)
%
% Notes::
% - layer is the usb chain layer (usually 0).
% - NO is the output port number from [0..3] or port
% number minus 1.
% - mode is the name of the current sensor mode (string)
%
% Example::
% mode = b.inputDeviceGetModeName(0,SensorPort.Sensor1,Device.Bumps)
% -> mode = BUMPS afterwards, if touch sensor is connected.
cmd = Command();
cmd.addHeaderDirectReply(42,12,0);
cmd.opINPUT_DEVICE_GET_MODENAME(layer,no,mode,12,0);
cmd.addLength();
brick.send(cmd);
% receive the command
reply = brick.receive()';
msg = reply.msg;
% return the mode name
mode = sscanf(char(msg(6:end)),'%s');
end
% Implemented @ MMI
function conn = inputDeviceGetConnection(brick,layer,no)
% Brick.inputDeviceGetConnection Get the input device
% connection type
%
% Brick.inputDeviceGetConnection(layer,no) returns the connection
% type at a layer and NO.
%
% Notes::
% - layer is the usb chain layer (usually 0).
% - NO is the output port number from [0..3] or port
% number minus 1.
% - connection is the connection type of the sensor (DATA8)
% -> compare with Device.CONN_[..]
%
% Example::
% conn = b.inputDeviceGetConnection(0,SensorPort.Sensor1)
% -> conn = Device.CONN_NONE (if no sensor is detected at Port1)
cmd = Command();
cmd.addHeaderDirectReply(42,1,0);
cmd.opINPUT_DEVICE_GET_CONNECTION(layer,no,0);
cmd.addLength();
brick.send(cmd);
% receive the command
reply = brick.receive()';
msg = reply.msg;
% return the connection type
conn = msg(6);
end
% Implemented @ MMI
function [min,max] = inputDeviceGetMinMax(brick,layer,no)
% Brick.inputDeviceGetMinMax Get min&max SI or pct values.
%
% Brick.inputDeviceGetMinMax(layer,no) returns the min and
% max SI or pct values at a layer and NO.
%
% Notes::
% - layer is the usb chain layer (usually 0).
% - NO is the output port number from [0..3] or port
% number minus 1.
% - min,max are the minimum/maximum SI/pct values of a sensor (each DATAF)
%
% Example::
% [min,max] = brick.inputDeviceGetMinMax(0,SensorPort.Sensor1);
cmd = Command();
cmd.addHeaderDirectReply(42,8,0);
cmd.opINPUT_DEVICE_GET_MINMAX(layer,no,0,4);
cmd.addLength();
brick.send(cmd);
% receive the command
reply = brick.receive()';
msg = reply.msg;
% return the values
min = typecast(uint8(msg(6:9)),'single');
max = typecast(uint8(msg(10:13)),'single');
if brick.debug > 0
fprintf('Minimum: %.02f\n', min);
fprintf('Maximum: %.02f\n', max);
end
end
% Implemented @ MMI
function changes = inputDeviceGetChanges(brick,layer,no)
% Brick.inputDeviceGetChanges Get changes since last clear.
%
% Brick.inputDeviceGetChanges (layer,no) returns positive changes(=button releases) at a layer and NO.
%
% Notes::
% - layer is the usb chain layer (usually 0).
% - NO is the output port number from [0..3] or port
% number minus 1.
% - changes are the button releases since last clear. (DATAF)
%
% Example::
% changes = brick.inputDeviceGetChanges(0,SensorPort.Sensor1)
cmd = Command();
cmd.addHeaderDirectReply(42,4,0);
cmd.opINPUT_DEVICE_GET_CHANGES(layer,no,0);
cmd.addLength();
brick.send(cmd);
% receive the command
reply = brick.receive()';
msg = reply.msg;
% return the changes
changes = typecast(uint8(msg(6:9)),'single');
if brick.debug > 0
fprintf('Changes (button releases) since clear: %.02f\n', changes);
end
end
% Implemented @ MMI
function [datasets,format,modes,view] = inputDeviceGetFormat(brick,layer,no)
% Brick.inputDeviceGetFormat Get format of sensor data.
%
% Brick.inputDeviceGetFormat (layer,no) returns no of
% datasets, format, no of modes, no of 'visible' modes
%
% Notes::
% - layer is the usb chain layer (usually 0).
% - NO is the output port number from [0..3] or port
% number minus 1.
% - datasets equals no of returned datasets (usually 1). (DATA8)
% - format equals format of returned data (0:8 Bit, 1:16 Bit,
% 2: 32 Bit, 3: 32 Bit Float). (DATA8)
% - modes equals no of sensor modes at NO (refer to types.html,
% typedata.rcf). (DATA8)
% - view equals no of sensor modes visible within port view
% app on brick. (DATA8)
%
% Example::
% changes = brick.inputDeviceGetFormat(0,SensorPort.Sensor1)
cmd = Command();
cmd.addHeaderDirectReply(42,4,0);
cmd.opINPUT_DEVICE_GET_FORMAT(layer,no,0,1,2,3);
cmd.addLength();
brick.send(cmd);
% receive the command
reply = brick.receive()';
msg = reply.msg;
% return the data
datasets = msg(6);
format = msg(7);
modes = msg(8);
view = msg(9);
end
% Implemented @ MMI
function bumps = inputDeviceGetBumps(brick,layer,no)
% Brick.inputDeviceGetBumps Get bumps since last clear.
%
% Brick.inputDeviceGetBumps (layer,no) returns bumps (button presses, = 'negative
% changes') at a layer and NO.
%
% Notes::
% - layer is the usb chain layer (usually 0).
% - NO is the output port number from [0..3] or port
% number minus 1.
% - bumps are the button presses since last clear. (DATAF)
%
% Example::
% changes = brick.inputDeviceGetBumps(0,SensorPort.Sensor1)
cmd = Command();
cmd.addHeaderDirectReply(42,4,0);
cmd.opINPUT_DEVICE_GET_BUMPS(layer,no,0);
cmd.addLength();
brick.send(cmd);
% receive the command
reply = brick.receive()';
msg = reply.msg;
% return the bumps
bumps = typecast(uint8(msg(6:9)),'single');
if brick.debug > 0
fprintf('Bumps (button presses) since clear: %.02f\n', bumps);
end
end
function name = inputDeviceSymbol(brick,layer,no)
% Brick.inputDeviceSymbol Get the input device symbol
%
% Brick.inputDeviceSymbol(layer,no) returns the symbol used for
% the device in its current mode.
%
% Notes::
% - layer is the usb chain layer (usually 0).
% - NO is the output port number from [0..3] or sensor port
% number minus 1.
% - name is the symbol of the sensor at NO (refer to types.html,
% typedata.rcf)
%
% Example::
% name = b.inputDeviceSymbol(0,SensorPort.Sensor1)
cmd = Command();
cmd.addHeaderDirectReply(42,5,0);
cmd.opINPUT_DEVICE_GET_SYMBOL(layer,no,5,0);
cmd.addLength();
brick.send(cmd);
% receive the command
reply = brick.receive()';
msg = reply.msg;
% return the symbol name
name = sscanf(char(msg(6:end)),'%s');
end
% Implemented @ MMI
function inputDeviceClrChanges(brick,layer,no)
% Brick.inputDeviceClrChanges Clear changes.
%
% Brick.inputDeviceClrChanges(layer,no) clear changes(&bumps)
% at a layer and NO.
%
% Notes::
% - layer is the usb chain layer (usually 0).
% - NO is the output port number from [0..3] or sensor port
% number minus 1.
%
% Example::
% name = b.inputDeviceClrChanges(0,SensorPort.Sensor1)
cmd = Command();
cmd.addHeaderDirect(42,0,0);
cmd.opINPUT_DEVICE_CLR_CHANGES(layer,no);
cmd.addLength();
brick.send(cmd);
end
function inputDeviceClrAll(brick,layer)
% Brick.inputDeviceClrAll Clear the sensors
%
% Brick.inputDeviceClrAll(layer) clears the sensors connected
% to layer. (@MMI: and tacho counts!)
%
% Notes::
% - layer is the usb chain layer (usually 0).
%
% Example::
% name = b.inputDeviceClrAll(0)
cmd = Command();
% cmd.addHeaderDirectReply(42,5,0);
cmd.addHeaderDirect(42,0,0);
cmd.opINPUT_DEVICE_CLR_ALL(layer);
cmd.addLength();
brick.send(cmd);
end
% Implemented @ MMI
function inputReady(brick,layer,no)
% Brick.inputReady Wait for device
%
% Brick.inputReady(layer,nos) halts program until device at no
% is ready by waiting until reply is received
%
% Notes::
% - layer is the usb chain layer (usually 0).
% - NO is the output port number from [0..3] or sensor port
% number minus 1.
%
% Example::
% b.inputReady(0,SensorPort.Sensor1)
cmd = Command();
cmd.addHeaderDirectReply(42,0,0);
cmd.opINPUT_READY(layer,no);
cmd.addLength();
brick.send(cmd);
% receive reply
brick.waitForReply();
end
% Implemented @ MMI
function state = inputTest(brick,layer,no)
% Brick.inputTest Test a device
%
% Brick.inputTest(layer,nos) tests a device state at a layer and
% NO.
%
% Notes::
% - layer is the usb chain layer (usually 0).
% - NO is the output port number from [0..3] or sensor port
% number minus 1.
% - state is 0 when ready and 1 when busy. (e.g. changing mode) (DATA8)s
%
% Example::
% state = b.inputTest(0,SensorPort.Sensor1)
cmd = Command();
cmd.addHeaderDirectReply(42,1,0);
cmd.opINPUT_TEST(layer,no,0);
cmd.addLength();
brick.send(cmd);
% receive the state
reply = brick.receive()';
msg = reply.msg;
% device state is the 6th (final) byte
state = msg(6);
end
% Implemented @ MMI
function reading = inputRead(brick,layer,no,mode)
% Brick.inputRead Input read in percentage
%
% reading = Brick.inputRead(layer,no,mode) reads a
% connected sensor at a layer, NO and mode in percentage of max
% values.
%
% Notes::
% - layer is the usb chain layer (usually 0).
% - NO is the output port number from [0..3] or sensor port
% number minus 1.
% - mode is the sensor mode from types.html. (-1=don't change)
% - reading is the read value in pct (DATA8)
%
% Example::
% reading = b.inputRead(0,SensorPort.Sensor1,Device.USDistCM)
% reading = b.inputRead(0,SensorPort.Sensor1,Device.ColReflect)
% -> returns the same value as b.inputReadSI..
% reading = b.inputRead(0,SensorPort.Sensor1,Device.Bumps)
% -> returns seemingly pointless values (as
% expected)
cmd = Command();
cmd.addHeaderDirectReply(42,1,0);
cmd.opINPUT_READ(layer,no,0,mode,0);
cmd.addLength();
brick.send(cmd);
% receive the command
reply = brick.receive()';
msg = reply.msg;
reading = msg(6);
if brick.debug > 0
fprintf('Sensor reading: %.02f\n', reading);
end
end
function reading = inputReadSI(brick,layer,no,mode)
% Brick.inputReadSI Input read in SI units
%
% reading = Brick.inputReadSI(layer,no,mode) reads a
% connected sensor at a layer, NO and mode in SI units.
%
% Notes::
% - layer is the usb chain layer (usually 0).
% - NO is the output port number from [0..3] or sensor port
% number minus 1.
% - mode is the sensor mode from types.html. (-1=don't change)
% - reading is the read value in SI units. (DATAF)
%
% Example::
% reading = b.inputReadSI(0,SensorPort.Sensor1,Device.USDistCM)
% reading = b.inputReadSI(0,SensorPort.Sensor1,Device.Pushed)
cmd = Command();
cmd.addHeaderDirectReply(42,4,0);
cmd.opINPUT_READSI(layer,no,0,mode,0);
cmd.addLength();
brick.send(cmd);
% receive the command
reply = brick.receive()';
msg = reply.msg;
reading = typecast(uint8(msg(6:9)),'single');
if brick.debug > 0
fprintf('Sensor reading: %.02f\n', reading);
end
end
function reading = inputReadSIType(brick,layer,no,type,mode)
% Brick.inputReadSI Input read in SI units
%
% reading = Brick.inputReadSI(layer,no,mode) reads a
% connected sensor at a layer, NO and mode in SI units.
%
% Notes::
% - layer is the usb chain layer (usually 0).
% - NO is the output port number from [0..3] or sensor port
% number minus 1.
% - mode is the sensor mode from types.html. (-1=don't change)
% - reading is the read value in SI units. (DATAF)
%
% Example::
% reading = b.inputReadSI(0,SensorPort.Sensor1,Device.USDistCM)
% reading = b.inputReadSI(0,SensorPort.Sensor1,Device.Pushed)
cmd = Command();
cmd.addHeaderDirectReply(42,4,0);
cmd.opINPUT_READSI(layer,no,type,mode,0);
cmd.addLength();
brick.send(cmd);
% receive the command
reply = brick.receive()';
msg = reply.msg;
reading = typecast(uint8(msg(6:9)),'single');
if brick.debug > 0
fprintf('Sensor reading: %.02f\n', reading);
end
end
function outputStop(brick,layer,nos,brake)
% Brick.outputPower Stops a motor
%
% Brick.outputPower(layer,nos,brake) stops motor at a layer
% NOS and brake.
%
% Notes::
% - layer is the usb chain layer (usually 0).
% - NOS is a bit field representing output 1 to 4 (0x01, 0x02, 0x04, 0x08).
% - brake is [0..1] (0=Coast, 1=Brake).
%
% Example::
% b.outputStop(0,MotorBitfield.MotorA,BrakeMode.Brake)
cmd = Command();
cmd.addHeaderDirect(42,0,0);
cmd.opOUTPUT_STOP(layer,nos,brake)
cmd.addLength();
brick.send(cmd);
end
function outputStopAll(brick)
% Brick.outputStopAll Stops all motors
%
% Brick.outputStopAll(layer) stops all motors on layer 0.
%
% Notes::
% - layer is the usb chain layer (usually 0).
% - Sends 0x0F as the NOS bit field to stop all motors.
%
% Example::
% b.outputStopAll(0)
cmd = Command();
cmd.addHeaderDirect(42,0,0);
cmd.opOUTPUT_STOP(0,15,BrakeMode.Brake);
cmd.addLength();
brick.send(cmd);
end
function outputPower(brick,layer,nos,power)
% Brick.outputPower Set the motor output power
%
% Brick.outputPower(layer,nos,power) sets motor output power at
% a layer, NOS and power.
%
% Notes::
% - layer is the usb chain layer (usually 0).
% - NOS is a bit field representing output 1 to 4 (0x01, 0x02, 0x04, 0x08).
% - power is the output power with [+-0..100%] range.
%
% Example::
% b.outputPower(0,MotorBitfield.MotorA,50)
cmd = Command();
cmd.addHeaderDirect(42,0,0);
cmd.opOUTPUT_POWER(layer,nos,power);
cmd.addLength();
brick.send(cmd);
end
% Implemented @ MMI
function outputSpeed(brick,layer,nos,speed)
% Brick.outputSpeed Set the motor output speed
%
% Brick.outputSpeed(layer,nos,speed) sets motor output speed at
% a layer, NOS and speed.
%
% Notes::
% - layer is the usb chain layer (usually 0).
% - NOS is a bit field representing output 1 to 4 (0x01, 0x02, 0x04, 0x08).
% - speed is the output speed with [+-0..100%] range.
% Example::
% b.outputSpeed(0,MotorBitfield.MotorA,50)
cmd = Command();
cmd.addHeaderDirect(42,0,0);
cmd.opOUTPUT_SPEED(layer,nos,speed);
cmd.addLength();
brick.send(cmd);
end
function outputStart(brick,layer,nos)
% Brick.outputStart Starts a motor
%
% Brick.outputStart(layer,nos) starts a motor at a layer and
% NOS.
%
% Notes::
% - layer is the usb chain layer (usually 0).
% - NOS is a bit field representing output 1 to 4 (0x01, 0x02, 0x04, 0x08).
%
% Example::
% b.outputStart(0,MotorBitfield.MotorA)
cmd = Command();
cmd.addHeaderDirect(42,0,0);
cmd.opOUTPUT_START(layer,nos);
cmd.addLength();
brick.send(cmd);
end
function state = outputTest(brick,layer,nos)
% Brick.outputTest Test a motor
%
% Brick.outputTest(layer,nos) tests a motor state at a layer and
% NOS.
%
% Notes::
% - layer is the usb chain layer (usually 0).
% - NOS is a bit field representing output 1 to 4 (0x01, 0x02, 0x04, 0x08).
% - state is 0 when ready and 1 when busy. (DATA8)
%
% Example::
% state = b.outputTest(0,MotorBitfield.MotorA)
cmd = Command();
cmd.addHeaderDirectReply(42,1,0);
cmd.opOUTPUT_TEST(layer,nos,0);
cmd.addLength();
brick.send(cmd);
% receive the command
reply = brick.receive()';
msg = reply.msg;
% motor state is the final byte
state = msg(end);
end
% Implemented @ MMI
function outputReady(brick,layer,nos)
% Brick.outputReady Wait for motor
%
% Brick.outputReady(layer,nos) halts program until motor at nos
% is ready by waiting until reply is received.
%
% Notes::
% - layer is the usb chain layer (usually 0).
% - NOS is a bit field representing output 1 to 4 (0x01, 0x02, 0x04, 0x08).
%
% Example::
% b.outputReady(0,MotorBitfield.MotorA)
cmd = Command();
cmd.addHeaderDirectReply(42,0,0);
cmd.opOUTPUT_READY(layer,nos);
cmd.addLength();
brick.send(cmd);
% receive reply
brick.waitForReply();
end
% Implemented @ MMI
function outputPolarity(brick, layer, nos, pol)
% Brick.outputPolarity Set a motor's polarity
%
% Brick.outputPolarity(layer,nos,pol) sets a motor's polarity
% to pol
%
% Notes::
% - layer is the usb chain layer (usually 0)
% - NOS is a bit field representing output 1 to 4 (0x01, 0x02, 0x04, 0x08)
% - pol is the polarity [-1,0,1], -1 makes the motor run
% backwards, 1 makes the motor run forwards, 0 makes the motor
% run the opposite direction when starting next time
%
% Example::
% b.outputPolarity(0, MotorBitfield.MotorA, -1);
cmd = Command();
cmd.addHeaderDirect(42,0,0);
cmd.opOUTPUT_POLARITY(layer,nos,pol);
cmd.addLength();
brick.send(cmd);
end
% Implemented @ MMI
function outputStepPower(brick,layer,nos,power,step1,step2,step3,brake)
% Brick.outputStepPower Output a step power
%
% Brick.outputStepPower(layer,nos,power,step1,step2,step3,brake)
% moves a motor to set position with layer, NOS, power, ramp up
% angle, constant angle, ramp down angle and brake.
%
% Notes::
% - layer is the usb chain layer (usually 0).
% - NOS is a bit field representing output 1 to 4 (0x01, 0x02, 0x04, 0x08).
% - power is the output power with [+-0..100%] range.
% - step1 is the steps used to ramp up.
% - step2 is the steps used for constant speed.
% - step3 is the steps used for ramp down.
% - brake is [0..1] (0=Coast, 1=Brake).
%
% Example::
% b.outputStepPower(0,MotorBitfield.MotorA,50,50,360,50,BrakeMode.Coast)
cmd = Command();
cmd.addHeaderDirect(42,0,0);
cmd.opOUTPUT_STEP_POWER(layer,nos,power,step1,step2,step3,brake);
cmd.addLength();
brick.send(cmd);
end
% Implemented @ MMI
function outputTimePower(brick,layer,nos,power,step1,step2,step3,brake)
% Brick.outputTimePower Output a time power
%
% Brick.outputTimePower(layer,nos,power,step1,step2,step3,brake)
% moves a motor for set time with layer, NOS, power, ramp up
% angle, constant angle, ramp down angle and brake.
%
% Notes::
% - layer is the usb chain layer (usually 0).
% - NOS is a bit field representing output 1 to 4 (0x01, 0x02, 0x04, 0x08).
% - power is the output power with [+-0..100%] range.
% - step1 is the time in ms used for ramp up.
% - step2 is the time in ms used for constant speed.
% - step3 is the time in ms used for ramp down.
% - brake is [0..1] (0=Coast, 1=Brake).
%
% Example::
% b.outputTimePower(0,MotorBitfield.MotorA,50,50,360,50,BrakeMode.Coast)
cmd = Command();
cmd.addHeaderDirect(42,0,0);
cmd.opOUTPUT_TIME_POWER(layer,nos,power,step1,step2,step3,brake);
cmd.addLength();
brick.send(cmd);
end
function outputStepSpeed(brick,layer,nos,speed,step1,step2,step3,brake)
% Brick.outputStepSpeed Output a step speed
%
% Brick.outputStepSpeed(layer,nos,speed,step1,step2,step3,brake)
% moves a motor to set position with layer, NOS, speed, ramp up
% angle, constant angle, ramp down angle and brake.
%
% Notes::
% - layer is the usb chain layer (usually 0).
% - NOS is a bit field representing output 1 to 4 (0x01, 0x02, 0x04, 0x08).
% - speed is the output speed with [+-0..100%] range.
% - step1 is the steps used to ramp up.
% - step2 is the steps used for constant speed.
% - step3 is the steps used for ramp down.
% - brake is [0..1] (0=Coast, 1=Brake).
%
% Example::
% b.outputStepSpeed(0,MotorBitfield.MotorA,50,50,360,50,BrakeMode.Coast)
cmd = Command();
cmd.addHeaderDirect(42,0,0);
cmd.opOUTPUT_STEP_SPEED(layer,nos,speed,step1,step2,step3,brake);
cmd.addLength();
brick.send(cmd);
end
% Implemented @ MMI
function outputTimeSpeed(brick,layer,nos,speed,step1,step2,step3,brake)
% Brick.outputTimeSpeed Output a time speed
%
% Brick.outputTimeSpeed(layer,nos,speed,step1,step2,step3,brake)
% moves a motor for set time with layer, NOS, speed, ramp up
% angle, constant angle, ramp down angle and brake.
%
% Notes::
% - layer is the usb chain layer (usually 0).
% - NOS is a bit field representing output 1 to 4 (0x01, 0x02, 0x04, 0x08).
% - speed is the output speed with [+-0..100%] range.
% - step1 is the time in ms used for ramp up.
% - step2 is the time in ms used for constant speed.
% - step3 is the time in ms used for ramp down.
% - brake is [0..1] (0=Coast, 1=Brake).
%
% Example::
% b.outputTimeSpeed(0,MotorBitfield.MotorA,50,50,360,50,BrakeMode.Coast)
cmd = Command();
cmd.addHeaderDirect(42,0,0);
cmd.opOUTPUT_TIME_SPEED(layer,nos,speed,step1,step2,step3,brake);
cmd.addLength();
brick.send(cmd);
end
% Implemented @ MMI
function outputStepSync(brick,layer,nos,power,turn,step,brake)
% Brick.outputStepSync Output a synced step power
%
% Brick.outputStepSync(brick,layer,nos,power,turn,step,brake)
% moves two motors synchronized to set position with layer,
% NOS, power, turn ratio, tacho limit and brake
%
% Notes::
% - layer is the usb chain layer (usually 0).
% - NOS is a bit field representing output 1 to 4 (0x01, 0x02, 0x04, 0x08).
% -> only works with output to multiple nos: e.g. 0x01+0x02
% - power is the output power with [+-0..100%] range.
% - (Excerpt of c_output.c): Turn ratio is how tight you turn and to what direction
% you turn (in [+-200]).
% -> 0 value is moving straight forward
% -> Negative values turns to the left
% -> Positive values turns to the right
% -> Value -100 stops the left motor
% -> Value +100 stops the right motor
% -> Values less than -100 makes the left motor run the opposite
% direction of the right motor (Spin)
% -> Values greater than +100 makes the right motor run the opposite
% direction of the left motor (Spin) (/end excerpt)
% - step is the tacho limit (read on 'faster' motor) 0=Inf
% - brake is [0..1] (0=Coast, 1=Brake).
%
% Example::
% b.outputStepSync(0,MotorBitfield.MotorA+MotorBitfield.MotorB,50,50,360,BrakeMode.Coast)
cmd = Command();
cmd.addHeaderDirect(42,0,0);
cmd.opOUTPUT_STEP_SYNC(layer,nos,power,turn,step,brake);
cmd.addLength();
brick.send(cmd);
end
% Implemented @ MMI
function outputTimeSync(brick,layer,nos,power,turn,time,brake)
% Brick.outputTimeSync Output a synced time power
%
% Brick.outputTimeSync(brick,layer,nos,power,turn,time,brake)
% moves two motors synchronized for set time with layer,
% NOS, power, turn ratio, time limit and brake
%
% Notes::
% - layer is the usb chain layer (usually 0).
% - NOS is a bit field representing output 1 to 4 (0x01, 0x02, 0x04, 0x08).
% -> output to multiple nos: e.g. 0x01+0x02
% - power is the output power with [+-0..100%] range.
% - (Excerpt of c_output.c): Turn ratio is how tight you turn and to what direction you turn
% -> 0 value is moving straight forward
% -> Negative values turns to the left
% -> Positive values turns to the right
% -> Value -100 stops the left motor
% -> Value +100 stops the right motor
% -> Values less than -100 makes the left motor run the opposite
% direction of the right motor (Spin)
% -> Values greater than +100 makes the right motor run the opposite
% direction of the left motor (Spin) (/end excerpt)
% - time is the time limit in milliseconds, 0=Inf
% - brake is [0..1] (0=Coast, 1=Brake).
%
% Example::
% b.outputTimeSync(0,MotorBitfield.MotorA+MotorBitfield.MotorB,50,50,360,BrakeMode.Coast)
cmd = Command();
cmd.addHeaderDirect(42,0,0);
cmd.opOUTPUT_TIME_SYNC(layer,nos,power,turn,time,brake);
cmd.addLength();
brick.send(cmd);
end
function outputClrCount(brick,layer,nos)
% Brick.outputClrCount Clear output count
%
% Brick.outputClrCount(layer,nos) clears a motor tachometer at a
% layer and NOS.
%
% Notes::
% - layer is the usb chain layer (usually 0).
% - NOS is a bit field representing output 1 to 4 (0x01, 0x02, 0x04, 0x08).
%
% Example::
% b.outputClrCount(0,MotorBitfield.MotorA)
cmd = Command();
cmd.addHeaderDirect(42,0,0);
cmd.opOUTPUT_CLR_COUNT(layer,nos);
cmd.addLength();
brick.send(cmd);
end
% Implemented @ MMI
function outputReset(brick,layer,nos)
% Brick.outputReset Resets internal tacho count
%
% Brick.outputReset(layer,nos) clears a second tachometer which is used internally
% for, e.g., stopping with a tacholimit.
%
% Notes::
% - layer is the usb chain layer (usuallly 0).
% - NOS is a bit field representing output 1 to 4 (0x01, 0x02, 0x04, 0x08).
%
% Example::
% b.outputReset(0,MotorBitfield.MotorA)
cmd = Command();
cmd.addHeaderDirect(42,0,0);
cmd.opOUTPUT_RESET(layer,nos);
cmd.addLength();
brick.send(cmd);
end
% Bugfix @ MMI
function tacho = outputGetCount(brick,layer,no)
% Brick.outputGetCount(layer,no) Get output count
%
% tacho = Brick.outputGetCount(layer,no) returns the tachometer
% at a layer and NO.
%
% Notes::
% - layer is the usb chain layer (usually 0).
% - NO is output motor number [0...3] ( != NOS)
% -> use MotorPort.MotorA
% - tacho is the returned tachometer value. (DATA32)
%
% Example::
% tacho = b.outputGetCount(0,MotorPort.MotorA)
cmd = Command();
cmd.addHeaderDirectReply(42,4,0);
cmd.opOUTPUT_GET_COUNT(layer,no,0);
cmd.addLength();
brick.send(cmd);
% receive the command
reply = brick.receive()';
msg = reply.msg;
tacho = typecast(uint8(msg(6:9)),'int32');
if brick.debug > 0
fprintf('Tacho: %d degrees\n', tacho);
end
end
% Implemented @ MMI
% Still buggy (WIP)
function [speed, tacho] = outputRead(brick,layer,no)
% Brick.outputRead(layer,no) Get tacho count and speed.
%
% [speed, tacho] = Brick.outputRead(layer,no) returns the tachometer
% and speed at a layer and NO.
%
% Notes::
% - layer is the usb chain layer (usually 0).
% - NO is output motor number [0...3] ( != NOS)
% - tacho is the returned tachometer value. (DATA32)
% - speed is the returned speed value. (DATA8)
%
% TODO::
% - returned tacho value is wrong/does not work.
% - returned speed value is OK until about speed=82
% -> calling this function while motor is faster seems to even screw the motor
% itself: it won't get any faster after current speed.
%
% Example::
% [speed,tacho] = b.outputRead(0,MotorPort.MotorA)
cmd = Command();
cmd.addHeaderDirectReply(42,5,0);
cmd.opOUTPUT_READ(layer,no,0,4); %%
cmd.addLength();
brick.send(cmd);
% receive the command
reply = brick.receive()';
msg = reply.msg;
% Current thoughts: the bug could be in the firmware (DUNDUNDUN).
% The docu states: "Offset in the response buffer (global variables) must be
% aligned (float/32bits first and 8 bits last)." [/lms2012/doc/html/directcommands.html]
%-> problem: the firmware
% implementation of this function puts speed (DATA8) first and tacho (DATA32) second.
% Furthermore, the speed is correct only if I, following the rule,
% do what I do at '%%': I tell the brick that I need a DATA32 and THEN a DATA8.
% This would fulfill the stated rule, but would only work if the
% firmware would put tacho first and speed second.
% If I tell the brick that I need a DATA8 and THEN a DATA32, ignoring the rule
% and going with the firmware version, I get an error in the response. (error flag)
%speed = msg(6);
%tacho = typecast(uint8(msg(7:10)),'int32');
tacho = typecast(uint8(msg(6:9)),'int32');
try
speed = msg(10);
catch
speed = 0; % Sometimes, the response packet lacks the 10th byte...?!
end
if brick.debug > 0
fprintf('Speed: %d\n', speed);
fprintf('buggy Tacho: %d degrees\n', tacho);
end
end
% Implemented @ MMI
function state = comTest(brick,hardware,name)
% Brick.comTest Get state of conn devices
%
% Brick.comTest(hardware,name) returns state of communication
% adapter of device.
%
% Notes::
% - hardware is the communication adapter to be tested.
% -> 1: USB, 2: BT, 3: Wifi
% - name is the name of the device ('0': own adapter) (?)
% - state is 0 when ready and 1 when busy. (DATA8)
%
% Example::
% state = b.comTest(1, '0');
cmd = Command();
cmd.addHeaderDirectReply(42,1,0);
cmd.opCOM_TEST(hardware,name,0);
cmd.addLength();
brick.send(cmd);
% receive the state
reply = brick.receive()';
msg = reply.msg;
% return the state
state = msg(end);
end
% Implemented @ MMI
function comReady(brick,hardware,name)
% Brick.comReady Wait for adapter
%
% Brick.comReady(layer,nos) halts program until
% communication adapter of device is ready.
%
% Notes::
% - hardware is the communication adapter to be tested.
% -> 1: USB, 2: BT, 3: Wifi
% - name is the name of the device ('0': own adapter) (?)
%
% Example::
% b.comReady(2, '0');
cmd = Command();
cmd.addHeaderDirectReply(42,0,0);
cmd.opCOM_READY(hardware,name);
cmd.addLength();
brick.send(cmd);
% receive reply
brick.waitForReply();
end
function name = comGetBrickName(brick)
% Brick.comGetBrickName Get brick name
%
% Brick.comGetBrickName() returns the name of the brick.
%
% Example::
% name = b.comGetBrickName()
cmd = Command();
cmd.addHeaderDirectReply(42,10,0);
cmd.opCOMGET_GET_BRICKNAME(10,0);
cmd.addLength();
brick.send(cmd);
% receive the command
reply = brick.receive()';
msg = reply.msg;
% return the brick name
name = sscanf(char(msg(6:end)),'%s');
end
function comSetBrickName(brick,name)
% Brick.comSetBrickName Set brick name
%
% Brick.comSetBrickName(name) sets the name of the brick.
%
% Example::
% b.comSetBrickName('EV3')
cmd = Command();
cmd.addHeaderDirect(42,0,0);
cmd.opCOMSET_SET_BRICKNAME(name);
cmd.addLength();
brick.send(cmd);
end
function mac = comGetMACAddress(brick)
% Brick.comGetMACAddress Get brick MAC address
%
% Brick.comGetMACAddress() returns the name of the brick.
%
% Example::
% mac = b.comGetMACAddress()
cmd = Command();
cmd.addHeaderDirectReply(42,36,0);
cmd.opCOMGET_NETWORK(3,36,0,8,20);
cmd.addLength();
brick.send(cmd);
% receive the command
reply = brick.receive()';
msg = reply.msg;
% return the brick name
mac = sscanf(char(msg(4:10)),'%s');
end
function id = comGetBTID(brick)
% Brick.comGetBTID Get brick BT address
%
% Brick.comGetBTID() returns the BT address
%
% Example::
% mac = b.comGetBTID()
cmd = Command();
cmd.addHeaderDirectReply(42,12,0);
cmd.opCOMGET_ID(2,12,0);
cmd.addLength();
brick.send(cmd);
% receive the command
reply = brick.receive()';
msg = reply.msg;
% return the brick name
id = sscanf(char(msg(6:end)),'%s');
end
function mailBoxWrite(brick,brickname,boxname,type,msg)
% Brick.mailBoxWrite Write a mailbox message
%
% Brick.mailBoxWrite(brickname,boxname,type,msg) writes a
% mailbox message from the brick to a remote device.
%
% Notes::
% - brickname is the name of the remote device.
% - boxname is the name of the receiving mailbox.
% - type is the sent message type being either 'text',
% 'numeric' or 'logic'.
% - msg is the message to be sent.
%
% Example::
% b.mailBoxWrite('T500','abc','logic',1)
% b.mailBoxWrite('T500','abc','numeric',4.24)
% b.mailBoxWrite('T500','abc','text','hello!')
cmd = Command();
cmd.addHeaderDirect(42,0,0);
cmd.opMAILBOX_WRITE(brickname,boxname,type,msg);
cmd.addLength();
brick.send(cmd);
end
function fileUpload(brick,filename,dest)
% Brick.fileUpload Upload a file to the brick
%
% Brick.fileUpload(filename,dest) upload a file from the PC to
% the brick.
%
% Notes::
% - filename is the local PC file name for upload.
% - dest is the remote destination on the brick relative to the
% '/home/root/lms2012/sys' directory. Directories are created
% in the path if they are not present.
%
% Example::
% b.fileUpload('prg.rbf','../apps/tst/tst.rbf')
fid = fopen(filename,'r');
% read in the file in and convert to uint8
input = fread(fid,inf,'uint8=>uint8');
fclose(fid);
% begin upload
cmd = Command();
cmd.addHeaderSystemReply(10);
cmd.BEGIN_DOWNLOAD(length(input),dest);
cmd.addLength();
brick.send(cmd);
% receive the sent response
reply = brick.receive()';
rmsg = reply.msg;
handle = rmsg(end);
pause(1)
% send the file
cmd.clear();
cmd.addHeaderSystemReply(11);
cmd.CONTINUE_DOWNLOAD(handle,input);
cmd.addLength();
brick.send(cmd);
% receive the sent response
reply = brick.receive()';
rmsg = reply.msg;
% print message
fprintf('%s uploaded\n',filename);
end
function fileDownload(brick,dest,filename,maxlength)
% Brick.fileDownload Download a file from the brick
%
% Brick.fileDownload(dest,filename,maxlength) downloads a file
% from the brick to the PC.
%
% Notes::
% - dest is the remote destination on the brick relative to the
% '/home/root/lms2012/sys' directory.
% - filename is the local PC file name for download e.g.
% 'prg.rbf'.
% - maxlength is the max buffer size used for download.
%
% Example::
% b.fileDownload('../apps/tst/tst.rbf','prg.rbf',59)
% begin download
cmd = Command();
cmd.addHeaderSystemReply(12);
cmd.BEGIN_UPLOAD(maxlength,dest);
cmd.addLength();
brick.send(cmd);
% receive the sent response
reply = brick.receive()';
rmsg = reply.msg;
% extract payload
payload = rmsg(13:end);
% print to file
fid = fopen(filename,'w');
% read in the file in and convert to uint8
fwrite(fid,payload,'uint8');
fclose(fid);
end
function listFiles(brick,pathname,maxlength)
% Brick.listFiles List files on the brick
%
% Brick.listFiles(brick,pathname,maxlength) list files in a
% given directory.
%
% Notes::
% - pathname is the absolute path required for file listing.
% - maxlength is the max buffer size used for file listing.
% - If it is a file:
% 32 chars (hex) of MD5SUM + space + 8 chars (hex) of filesize + space + filename + new line is returned.
% - If it is a folder:
% foldername + / + new line is returned.
%
% Example::
% b.listFiles('/home/root/lms2012/',100)
cmd = Command();
cmd.addHeaderSystemReply(13);
cmd.LIST_FILES(maxlength,pathname);
cmd.addLength();
brick.send(cmd);
reply = brick.receive()';
rmsg = reply.msg;
% print
fprintf('%s',rmsg(13:end));
end
function createDir(brick,pathname)
% Brick.createDir Create a directory on the brick
%
% Brick.createDir(brick,pathname) creates a diretory on the
% brick from the given pathname.
%
% Notes::
% - pathname is the absolute path for directory creation.
%
% Example::
% b.createDir('/home/root/lms2012/newdir')
cmd = Command();
cmd.addHeaderSystemReply(14);
cmd.CREATE_DIR(pathname);
cmd.addLength();
brick.send(cmd);
brick.waitForReply();
end
function deleteFile(brick,pathname)
% Brick.deleteFile Delete file on the brick
%
% Brick.deleteFile(brick,pathname) deletes a file from the
% brick with the given pathname.
%
% Notes::
% - pathname is the absolute file path for deletion.
% - will only delete files or empty directories.
%
% Example::
% b.deleteFile('/home/root/lms2012/newdir')
cmd = Command();
cmd.addHeaderSystemReply(15);
cmd.DELETE_FILE(pathname);
cmd.addLength();
brick.send(cmd);
brick.waitForReply();
end
function writeMailBox(brick,title,type,msg)
% Brick.writeMailBox Write a mailbox message
%
% Brick.writeMailBox(title,type,msg) writes a mailbox message to
% the connected brick.
%
% Notes::
% - title is the message title sent to the brick.
% - type is the sent message type being either 'text',
% 'numeric', or 'logic'.
% - msg is the message to be sent to the brick.
%
% Example::
% b.writeMailBox('abc','text','hello!')
cmd = Command();
cmd.addHeaderSystem(16);
cmd.WRITEMAILBOX(title,type,msg);
cmd.addLength();
brick.send(cmd);
end
function [title,msg] = readMailBox(brick,type)
% Brick.readMailBox Read a mailbox message
%
% [title,msg] = Brick.readMailBox(type) reads a mailbox
% message sent from the brick.
%
% Notes::
% - type is the sent message type being either 'text',
% 'numeric' or 'logic'.
% - title is the message title sent from the brick.
% - msg is the message sent from the brick.
%
% Example::
% [title,msg] = b.readMailBox('text')
reply = brick.receive()';
mailmsg = reply.msg;
% extract message title (starts at pos 8, pos 7 is the size)
title = char(mailmsg(8:7+mailmsg(7)));
% parse message according to type
switch type
case 'text'
msg = char(mailmsg(mailmsg(7)+10:end));
case 'numeric'
msg = typecast(uint8(mailmsg(mailmsg(7)+10:end)),'single');
case 'logic'
msg = mailmsg(mailmsg(7)+10:end);
otherwise
fprintf('Error! Type must be ''text'', ''numeric'' or ''logic''.\n');
msg = '';
end
end
%% Bytecode test
function threeToneByteCode(brick,filename)
% Brick.threeToneByteCode Create three tone byte code
%
% Brick.threeToneByteCode() generates the byte code for the
% play three tone function. This is an example of how byte code
% can be generated as an rbf file which can be uploaded to the brick.
%
% Notes::
% - filename is the name of the file to store the byte code in
% (the rbf extension is added to the filename automatically)
%
% Example::
% b.threeToneByteCode('threetone')
cmd = Command();
% program header
cmd.PROGRAMHeader(0,1,0); % VersionInfo,NumberOfObjects,GlobalBytes
cmd.VMTHREADHeader(0,0); % OffsetToInstructions,LocalBytes
% commands % VMTHREAD1{
cmd.opSOUND_TONE(5,440,500); % opSOUND
cmd.opSOUND_READY(); % opSOUND_READY
cmd.opSOUND_TONE(10,880,500); % opSOUND
cmd.opSOUND_READY(); % opSOUND_READY
cmd.opSOUND_TONE(15,1320,500); % opSOUND
cmd.opSOUND_READY(); % opSOUND_READY
cmd.opOBJECT_END; % }
% add file size in header
cmd.addFileSize;
% generate the byte code
cmd.GenerateByteCode(filename);
end
%% Utility
% Methods in this block are composed of multiple commands and more logic for convenience
function drawTest(brick)
% Brick.drawTest Draw test shapes
%
% Brick.drawTest() shows the drawing capabilities of the brick.
%
% Example::
% b.drawTest()
cmd = Command();
cmd.addHeaderDirect(42,4,1);
% save the UI screen
cmd.opUI_DRAW_STORE(0);
% change the led pattern
cmd.opUI_WRITE_LED(Device.LedGreenFlash);
% clear the screen (top line still remains with remote cmds)
cmd.opUI_DRAW_FILLWINDOW(0,0,0);
% draw four pixels
cmd.opUI_DRAW_PIXEL(vmCodes.vmFGColor,12,15);
cmd.opUI_DRAW_PIXEL(vmCodes.vmFGColor,12,20);
cmd.opUI_DRAW_PIXEL(vmCodes.vmFGColor,18,15);
cmd.opUI_DRAW_PIXEL(vmCodes.vmFGColor,18,20);
% draw line
cmd.opUI_DRAW_LINE(vmCodes.vmFGColor,0,25,vmCodes.vmLCDWidth,25);
cmd.opUI_DRAW_LINE(vmCodes.vmFGColor,15,25,15,127);
% draw circle
cmd.opUI_DRAW_CIRCLE(1,40,40,10);
% draw rectangle
cmd.opUI_DRAW_RECT(vmCodes.vmFGColor,70,30,20,20);
% draw filled cricle
cmd.opUI_DRAW_FILLCIRCLE(vmCodes.vmFGColor,40,70,10);
% draw filled rectangle
cmd.opUI_DRAW_FILLRECT(vmCodes.vmFGColor,70,60,20,20);
% draw inverse rectangle
cmd.opUI_DRAW_INVERSERECT(30,90,60,20);
% change font
cmd.opUI_DRAW_SELECT_FONT(2);
% draw text
cmd.opUI_DRAW_TEXT(vmCodes.vmFGColor,100,40,'EV3');
% change font
cmd.opUI_DRAW_SELECT_FONT(1);
% reprint
cmd.opUI_DRAW_TEXT(vmCodes.vmFGColor,100,70,'EV3');
% change font
cmd.opUI_DRAW_SELECT_FONT(0);
% reprint
cmd.opUI_DRAW_TEXT(vmCodes.vmFGColor,100,90,'EV3');
% voltage string
cmd.opUI_DRAW_TEXT(vmCodes.vmFGColor,100,110,'v =');
% store voltage
cmd.opUI_READ_GET_VBATT(0);
% print the voltage value (global)
cmd.opUI_DRAW_VALUE(vmCodes.vmFGColor,130,110,0,5,3);
% update the window
cmd.opUI_DRAW_UPDATE;
% 5 second timer (so you can see the changing LED pattern)
cmd.opTIMER_WAIT(5000,0);
% wait for timer
cmd.opTIMER_READY(0);
% reset the LED
cmd.opUI_WRITE_LED(Device.LedGreen);
% return UI screen
cmd.opUI_DRAW_RESTORE(0);
% return
cmd.opUI_DRAW_UPDATE;
cmd.addLength();
brick.send(cmd)
end
function beep(brick,volume,duration)
% Brick.beep Play a beep on the brick
%
% Brick.beep(volume,duration) plays a beep tone with volume and
% duration.
%
% Notes::
% - volume is the beep volume from 0 to 100, by default 10. (DATA8)
% - duration is the beep duration in ms, by default 100. (DATA16)
%
% Example::
% b.beep(5,500)
if nargin < 2
volume = 10;
end
if nargin < 3
duration = 100;
end
brick.soundPlayTone(volume, 1000, duration);
end
function plotSensor(brick,layer,no,mode)
% Brick.plotSensor plot the sensor output
%
% Brick.plotSensor(layer,no,mode) plots the sensor output
% to MATLAB.
%
% Notes::
% - layer is the usb chain layer (usually 0).
% - NO is the output port number from [0..3] or sensor port
% number minus 1.
% - mode is the sensor mode from types.html. (-1=don't change)
%
% Example::
% b.plotSensor(0,SensorPort.Sensor1,Device.USDistCM)
% b.plotSensor(0,SensorPort.Sensor1,Device.GyroAng)
% start timing
tic;
% create figure
hfig = figure('name','EV3 Sensor');
% init the the data
t = 0;
x = 0;
hplot = plot(t,x);
% one read to set the mode
reading = brick.inputReadSI(layer,no,mode);
% set the title
name = brick.inputDeviceGetName(layer,no);
title(['Device name: ' name]);
% set the y label
name = brick.inputDeviceSymbol(layer,no);
ylabel(['Sensor value (' name(1:end-1) ')']);
% set the x label
xlabel('Time (s)');
% set the x axis
xlim([0 10]);
% wait until the figure is closed
while(findobj('name','EV3 Sensor') == 1)
% get the reading
reading = brick.inputReadSI(layer,no,mode);
t = [t toc];
x = [x reading];
set(hplot,'Xdata',t)
set(hplot,'Ydata',x)
drawnow
% reset after 10 seconds
if (toc > 10)
% reset
t = 0;
x = x(end);
tic
end
end
end
function displayColor(brick,layer,no)
% Brick.displayColor display sensor color
%
% Brick.displayColor(layer,no) displays the color read from the
% color sensor in a MATLAB figure.
%
% Notes::
% - layer is the usb chain layer (usually 0).
% - NO is the output port number from [0..3] or sensor port
% number minus 1.
%
% Example::
% b.displayColor(0,SensorPort.Sensor1)
% create figure
hfig = figure('name','EV3 Color Sensor');
% wait until the figure is closed
while(findobj('name','EV3 Color Sensor') == 1)
% read the color sensor in color detection mode
color = brick.inputReadSI(layer,no,Device.ColColor);
% change the figure background according to the color
switch color
case Device.NoColor
set(hfig,'Color',[0.8,0.8,0.8])
case Device.BlackColor
set(hfig,'Color',[0,0,0])
case Device.BlueColor
set(hfig,'Color',[0,0,1])
case Device.GreenColor
set(hfig,'Color',[0,1,0])
case Device.YellowColor
set(hfig,'Color',[1,1,0])
case Device.RedColor
set(hfig,'Color',[1,0,0])
case Device.WhiteColor
set(hfig,'Color',[1,1,1])
case Device.BrownColor
set(hfig,'Color',[0.6,0.3,0])
otherwise
set(hfig,'Color',[0.8,0.8,0.8])
end
drawnow
end
end
end
methods (Access = private)
function send(brick, cmd)
% Brick.send Send data to the brick
%
% Brick.send(cmd) sends a command to the brick through the
% connection handle.
%
% Notes::
% - cmd is a command object.
%
% Example::
% b.send(cmd)
% Send the message through the brickIO write function
brick.conn.write(cmd.msg);
% (MMI) When spamming the brick with commands, at some point, it will start
% behaving 'strange'. Sometimes, commands will be executed only with
% a delay, some commands may even be bypassed.
% (Maybe too many commands screw up the brick's internal command queue?..)
% Temporary workaround: Wait 5ms after each sent packet.
pause(0.005);
% Verbose output
if brick.debug > 0
fprintf('sent (hex): [ ');
for ii=1:length(cmd.msg)
fprintf('%s ',dec2hex(cmd.msg(ii)))
end
fprintf(']\n');
fprintf('sent (dec): [ ');
for ii=1:length(cmd.msg)
fprintf('%d ',cmd.msg(ii))
end
fprintf(']\n');
end
end
function reply = receive(brick)
% Brick.receive Receive data from the brick
%
% rmsg = Brick.receive() receives data from the brick through
% the connection handle.
%
% Notes::
% - If received packet is corrupt, up to five new packets are read (if all are
% corrupt, an error is thrown)
%
% Example::
% rmsg = b.receive()
%
% Read the message through the brickIO read function
rmsg = brick.conn.read();
% Check if reply is corrupt or error byte is set
try
reply = Command(rmsg);
catch ME
corrupt = 1;
if ~isempty(strfind(ME.identifier, 'CorruptPacket'))
% Read packet was corrupt - retry
%id = [ID(), ':', 'CorruptPacket'];
%warning(id, 'Read corrupt packet. Retrying...');
if brick.debug
fprintf('received (corrupt) (hex): [ ');
for ii=1:length(rmsg)
fprintf('%s ',dec2hex(rmsg(ii)))
end
fprintf(']\n');
fprintf('received (corrupt) (dec): [ ');
for ii=1:length(rmsg)
fprintf('%d ',rmsg(ii))
end
fprintf(']\n');
end
retries = 5;
while corrupt && retries
rmsg = brick.conn.read();
try
reply = Command(rmsg);
corrupt = 0;
catch
retries = retries-1;
end
end
end
if corrupt
rethrow(ME);
end
end
if reply.checkForError()
msg = 'Error byte is set. The Brick couldn''t handle the last packet';
id = [ID(), ':', 'CommandError'];
warning(id, msg);
end
% Verbose output
if brick.debug > 0
fprintf('received (hex): [ ');
for ii=1:length(rmsg)
fprintf('%s ',dec2hex(rmsg(ii)))
end
fprintf(']\n');
fprintf('received (dec): [ ');
for ii=1:length(rmsg)
fprintf('%d ',rmsg(ii))
end
fprintf(']\n');
end
end
function waitForReply(brick)
oldTimeOut = brick.timeOut;
brick.timeOut = 0;
brick.receive();
brick.timeOut = oldTimeOut;
end
end
end