From 976cd5de36ea3fa52630b991e076a2208dff8c95 Mon Sep 17 00:00:00 2001
From: Tim Stadtmann <tim.stadtmann@rwth-aachen.de>
Date: Mon, 15 Aug 2016 20:18:07 +0200
Subject: [PATCH] Implement sync-functionality in Motor-class

Also, lots of code cleanup, comments, etc.
---
 source/CommunicationInterface.m |    1 +
 source/ConnectionType.m         |    2 -
 source/EV3.m                    |  142 ++--
 source/Motor.m                  | 1221 +++++++++++++++----------------
 source/MotorPort.m              |    3 +-
 source/Sensor.m                 |   80 +-
 6 files changed, 723 insertions(+), 726 deletions(-)

diff --git a/source/CommunicationInterface.m b/source/CommunicationInterface.m
index 34fcecb..18bca6c 100644
--- a/source/CommunicationInterface.m
+++ b/source/CommunicationInterface.m
@@ -220,6 +220,7 @@ classdef CommunicationInterface < handle
         
         function setProperties(brick, varargin)
             p = inputParser();
+            p.KeepUnmatched = true;
             
             % Set default values
             defaultIOType = 'usb';
diff --git a/source/ConnectionType.m b/source/ConnectionType.m
index df8a552..c474df6 100644
--- a/source/ConnectionType.m
+++ b/source/ConnectionType.m
@@ -1,7 +1,5 @@
 classdef ConnectionType < uint8
     %ConnectionType Type resp. status of connection at a certain port.
-    
-    
     enumeration
         Unknown (111)
         DaisyChain (117)
diff --git a/source/EV3.m b/source/EV3.m
index 0cbb62d..0d970ec 100644
--- a/source/EV3.m
+++ b/source/EV3.m
@@ -7,82 +7,110 @@ classdef EV3 < handle
     % 
     % Properties:
     %   Standard
-    %       motorA[,B,C,D]  - 
-    %       sensor1[,2,3,4] -
-    %       debug           - 
+    %       motorA[,B,C,D]  
+    %       sensor1[,2,3,4] 
+    %       debug           - Debug turned on or off
     %       batteryMode     - Mode for reading battery charge
     %   Dependent
     %       batteryValue    - Current battery charge level
     %   get-only
     %       isConnected     - Is virtual brick connected to physical one?
-    %       commInterface   - Brick object from sublayer class Brick -> used as interface to the physical brick.
+    %       commInterface   - Interface to communication layer
     %
     % Methods:
-    %   Standard
-    %       EV3             -
-    %       connect         - Connects EV3-object and its Motors and Sensors to physical brick via bt or usb.
-    %       disconnect      - Disconnects EV3-object and its Motors and Sensors from physical brick.
-    %       update          - Updates all Motors and Sensors
-    %       coupleMotors    - Creates and connects a SyncMotor-object using two chosen Motor-objects 
-    %       beep            - Plays a 'beep' tone on brick.
-    %       playTone        - Plays tone on brick.
-    %       stopTone        - Stops tone currently played.
-    %       tonePlayed      - Tests if a tone is currently played.
-    %       setProperties   - Set multiple EV3 properties at once using MATLAB's inputParser.
+    %   General
+    %       EV3             
+    %       connect         - Connects EV3-object and its Motors and Sensors to physical brick via bt or usb
+    %       disconnect      - Disconnects EV3-object and its Motors and Sensors from physical brick
+    %       setProperties   - Set multiple EV3 properties at once using MATLAB's inputParser
+    %   Brick functions
+    %       beep            - Plays a 'beep' tone on brick
+    %       playTone        - Plays tone on brick
+    %       stopTone        - Stops tone currently played
+    %       tonePlayed      - Tests if a tone is currently played
     %
     %
     % Notes
     %  * Creating multiple EV3 objects and connecting them to different physical bricks has not
     %    been thoroughly tested yet, but seems to work on a first glance.
     %  * When referring to an instance of this class the term 'virtual brick' is used from now
-    %    on. The LEGO brick itself is referred to as 'physical brick'.
+    %    on. The LEGO EV3 brick itself is referred to as 'physical brick'.
     %
     % Example
-    %  % This small example connects to the brick, starts motorA with power 50, reads a value
-    %  % from sensor1, brakes the motor and disconnects again.
-    %  % This should roughly demonstrate how this toolbox works.
+    %  % This small example connects to the brick, starts motorA with power 50 and time-limit
+    %  % of 5 seconds. As long as it's running, sensor 1 is read and its readings are plotted 
+    %  % the end.
     % 
-    %  brickObject = EV3();
-    %  brickObject = EV3('debug', 'on', 'batteryMode', 'Voltage');
-    %  brickObject.connect('ioType', 'bt', 'serPort', '/dev/rfcomm0');
-    %  m = brickObject.motorA;
-    %  m.power = 50;
-    %  m.start();
-    %  s = brickObject.sensor1;
-    %  s.value
-    %  m.tachoCount
-    %  m.brakeMode = 'Brake';
-    %  m.stop();
-    %  brickObject.disconnect();
-    %  delete brickObject;
-    %  delete m; delete s;
-    %
+    %%%%%%%%%% 
+    % brickObject = EV3('debug', 'on', 'batteryMode', 'Voltage');
+    % brickObject.connect('bt', 'serPort', '/dev/rfcomm0');
+    % 
+    % m = brickObject.motorA;
+    % s = brickObject.sensor1;
+    % 
+    % m.setProperties('Power', 50, 'BrakeMode', 'Brake', 'TachoLimitMode', 'Time', ...
+    %     'TachoLimit', 5000);
+    % 
+    % if s.type ~= DeviceType.Color
+    %     fprintf('Please connect EV3-color-sensor to port 1!\n');
+    % else
+    %     s.mode = DeviceMode.Color.Ambient;
+    % 
+    %     readings = [];
+    %     time = [];
+    %     
+    %     tic;
+    %     m.start();
+    %     pause(0.5);
+    %     while m.isRunning
+    %         readings = [readings, s.value];
+    %         time = [time toc];
+    %     end
+    %     
+    %     plot(time, readings);
+    % end
+    % 
+    % brickObject.disconnect();
+    % brickObject.delete();
+    % clear all
+    %%%%%%%%%%
     %
     % Signature
     %  Author: Tim Stadtmann
     %  Date: 2016/05/19
+    %  Updated: 2016/08/15
     
     properties  % Standard properties 
+        %debug -  Debug turned on or off
+        % In debug mode 1 (debug=1/'on'/true), everytime a command is passed to the sublayer 
+        % ('communication layer'), there is feedback in the console about what command has been 
+        % called. Debug mode 2 (debug=2) enables debug mode in the lower layers. Each packet
+        % sent and received is printed to the console.
+        %   -> Any valid boolean (0/1/'on'/'off'/true/false) or 2 (for enabling debugging in 
+        %      lower layers)
+        debug; 
+        
         %% Modi
         
         %batteryMode -  Mode for reading battery charge
         %   -> 'Percentage' / 'Voltage'
         % See also EV3.BATTERYVALUE
-        batteryMode = 'Percentage';
-        
-        %% Debug
-        
-        debug;
+        batteryMode;
     end
 
     properties (Dependent)  % Parameters to be read directly from physical brick
-        batteryValue;  % Current battery status (either in Percentage or Voltage)
+        %batteryValue -  Current battery charge
+        % Depending on batteryMode, the reading is either in percentage or voltage.
+        % See also EV3.BATTERYMODE
+        batteryValue; 
     end
     
     properties (SetAccess = 'private')  % Read-only properties that are set internally
-        isConnected = false;  % Is virtual brick currently connected to physical brick?
-        commInterface = 0;  % Brick object from sub-layer class Brick -> used as interface to the 
-                    % physical brick.
+        %isConnected -  Virtual brick connected to physical one?
+        isConnected = false; 
+        
+        %commInterface -  Interface to communication layer
+        commInterface = 0;
                     
         %% Motors and Sensors
         
@@ -98,13 +126,13 @@ classdef EV3 < handle
     end
     
     properties (Hidden, Access = 'private')  % Hidden properties for internal use only
-        init = 1;  % Indicates 'init-phase' (Set to 1 as long as constructor is running)
+        init = true;  % Indicates 'init-phase' (Set to 1 as long as constructor is running)
     end
     
     methods  % Standard methods
         %% Constructor
         function ev3 = EV3(varargin)
-            % Sets properties of EV3-object and creates Motor- and Sensor-objects with default
+            %EV3 Sets properties of EV3-object and creates Motor- and Sensor-objects with default
             % parameters.
             %
             % Arguments
@@ -477,14 +505,8 @@ classdef EV3 < handle
         end
         
         function set.batteryMode(ev3, batteryMode)
-            % Check if batteryMode is valid and set ev3.batteryMode if it is.
-            %
-            % Arguments
-            %  * batteryMode ('Voltage'/'Percentage'): Mode in which batteryValue will be read.
-            %
-            
             validModes = {'Voltage', 'Percentage'};
-            if ~ischar(batteryMode) || ~any(validatestring(batteryMode, validModes))
+            if ~ischar(batteryMode) || ~ismember(batteryMode, validModes)
                 error('EV3::set.batteryMode: Given parameter is not a valid battery mode.');
             else 
                 ev3.batteryMode = batteryMode;
@@ -492,12 +514,6 @@ classdef EV3 < handle
         end
         
         function set.debug(ev3, debug)
-            % Check if debug is valid and set ev3.debug if it is. 
-            %
-            % Arguments
-            %  * debug (0/1/'on'/'off'/'true'/'false'/2)
-            %
-            
             if ~isBool(debug) && debug ~= 2
                 error('EV3::set.debug: Given parameter is not a bool.');
             end
@@ -518,16 +534,18 @@ classdef EV3 < handle
             %
             % Example
             %  b = EV3(); 
-            %  b.connect('ioType', 'bt', 'serPort', '/dev/rfcomm0');
+            %  b.connect('bt', 'serPort', '/dev/rfcomm0');
             %  b.setProperties('debug', 'on', 'batteryMode', 'Voltage');
             %  % Instead of: b.debug = 'on'; b.batteryMode = 'Voltage';
             %
+            % See also EV3.DEBUG, EV3.BATTERYMODE
+            % 
             
             p = inputParser();
             
             % Set default values
             if ev3.init
-                defaultDebug = 0;
+                defaultDebug = false;
                 defaultBatteryMode = 'Percentage';
             else
                 defaultDebug = ev3.debug;
@@ -570,8 +588,8 @@ classdef EV3 < handle
     methods (Access = 'private')  % Private brick functions that are wrapped by dependent params
         function bat = getBattery(ev3)
             if ~ev3.isConnected
-               error(['EV3::getBattery: EV3-Object not connected to physical EV3. You have ',... 
-                      'to call ev3.connect(properties) first!']);
+                error(['EV3::getBattery: EV3-Object not connected to physical EV3. You have ',...
+                    'to call ev3.connect(properties) first!']);
             end
             
             if strcmpi(ev3.batteryMode, 'Percentage')
diff --git a/source/Motor.m b/source/Motor.m
index 8625762..35172e1 100644
--- a/source/Motor.m
+++ b/source/Motor.m
@@ -1,10 +1,9 @@
-classdef Motor < handle 
+classdef Motor < handle & dynamicprops
     % Motor High-level class to work with motors.
     %
     % This class is supposed to ease the use of the brick's motors. It is possible to set all
-    % kinds of parameters (even without connecting to the brick), request the current status of 
-    % the motor port and of course send commands to the brick to execute on the respective
-    % port.
+    % kinds of parameters, request the current status of the motor ports and of course send 
+    % commands to the brick to be executed on the respective port.
     %
     % Properties:
     %   Standard
@@ -13,175 +12,131 @@ classdef Motor < handle
     %       smoothStart         - Degrees/Time for how far/long the motor should smoothly start (depends on limitMode)
     %       smoothStop          - Degrees/Time for how far/long the motor should smoothly stop (depends on limitMode)
     %       limitValue          - Degrees/Time for how far/long the motor should run (depends on limitMode)
-    %       brakeMode           - Mode for braking
     %       limitMode           - Mode for motor limit
-    %       mode                - Device mode at port, used as tacho mode (format in which tachoCount should be returned)
+    %       brakeMode           - Mode for braking
     %       debug               - Debug mode turned on or off
     %   Dependent
-    %       tachoCount          - Current tacho count (either in degrees or rotations)
-    %       speed               - Current speed of motor (only valid with speedRegulation turned on)
-    %   Get-only
+    %       isRunning           - True if motor is running (currentSpeed > 0)
+    %       tachoCount          - Current tacho count 
+    %       currentSpeed        - Current speed of motor (should equal power if speedRegulation = 1)
+    %       type                - Current motor type (large or medium motor)
+    %   Other
     %       port                - Motor port
-    %       motorAtPort         - Is physical motor actually connected to port?
-    %       brick               - Brick object from sublayer class Brick -> used as interface to the physical brick.
-    %       status              - Connection status at port 
-    %       type                - Device type at port
     %
     % Methods:
     %   Standard
-    %       Motor               -
-    %       connect             - Connects Motor-object to physical brick.
-    %       disconnect          - Disconnects Motor-object from physical brick.
-    %       update              - Updates Motor-object to current status at its port.
-    %       start               - Starts the motor taking all parameters set by user into account. 
-    %       stop                - Stops the motor. :)
-    %       waitFor             - Stops execution of program as long as motor is running with tacholimit.
-    %       isRunning           - Returns whether motor is running (WITH TACHOLIMIT) or not.
+    %       Motor               
+    %       connect             - Connects Motor-object to physical brick
+    %       disconnect          - Disconnects Motor-object from physical brick
+    %       setProperties       - Sets multiple Motor properties at once using MATLAB's inputParser
+    %   Brick functions
+    %       start               - Starts the motor taking all parameters set by user into account 
+    %       stop                - Stops the motor :)
+    %       syncedStart         - Starts the motor synchronized with another
+    %       syncedStop          - Stops the motors previously started together with syncedStart
+    %       waitFor             - Stops execution of program as long as motor is running with tacholimit
     %       reset               - Resets internal tacho count
-    %       resetTachoCount     - Resets tacho count to 0 (if running without tacholimit).
-    %       togglePolarity      - Switches the direction in which the motor turns.
-    %       setProperties       - Sets multiple Motor properties at once using MATLAB's inputParser.
+    %       resetTachoCount     - Resets tacho count to 0 (if running without tacholimit)
     %       
     %
-    %
     % Notes:
     %  * You don't need to create instances of this class. The EV3-class automatically creates
     %    instances for each motor port, and you can work with them via the EV3-object. 
-    %    In fact, the connect/disconnect-methods of Motor are even written to be used via 
-    %    EV3-class mainly, so you should only work without the EV3-class if you know what you 
-    %    are doing!
-    %
-    % Example
-    %  % This small example should only roughly demonstrate how to work with motors.
-    %  % Establish connection, set properties on motorA and wait until it's connected. After
-    %  % starting, output current speed every 100ms until motor is turned off. Then output
-    %  % current tachoCount and disconnect.
-    %
-    %  b = EV3();
-    %  b = EV3('debug', 'on', 'batteryMode', 'Voltage');
-    %  b.connect('ioType', 'bt', 'serPort', '/dev/rfcomm0');
-    %  b.motorA.setProperties('Power', 50, 'speedRegulation', 'on', 'limitMode', 'Time');
-    %  b.motorA.limitValue = 1000;
-    %  b.motorA.brakeMode = 'Coast';
-    %  b.motorA.mode = DeviceMode.Motor.Rotations;
-    %  while ~b.motorA.motorAtPort  % Wait until physical motor connected to A
-    %     b.motorA.update();
-    %     pause(0.5);
-    %  end
-    %  b.motorA.start(); % Motor on portA runs with power 50 for 1000ms and then coasts to a
-    %                    % stop
-    %  while ~b.motorA.isRunning()
-    %     b.motorA.speed
-    %     pause(0.1);
-    %  end
-    %  b.motorA.tachoCount
-    %  b.disconnect();
-    %  b.delete()
     %
     %
     % Signature
     %  Author: Tim Stadtmann
     %  Date: 2016/05/19
+    %  Updated: 2016/08/15
     
     properties  % Standard properties to be set by user
         %power -  Power level of motor in percent
-        %   -> Any integer or double in [-100, 100] 
+        %   -> Any numeric in [-100, 100] 
         power;
         
         %speedRegulation  -  Speed regulation turned on or off
-        % Turning speed regulation on enables Motor.isRunning(), Motor.waitFor() and correctly
-        % reading current speed with Motor.speed.
-        %   -> Any valid boolean (0/1/'on'/'off'/'true'/'false')
+        %   -> Any valid boolean (0/1/'on'/'off'/true/false)
         speedRegulation;
         
-        %smoothStart -  Degrees/Time for how far/long the motor should smoothly start (depends on limitMode)
-        %   -> Any integer or double in [0, tachoLimit/2] 
+        %smoothStart -  Degrees/Time for how far/long the motor should smoothly start (depends on tachoLimitMode)
+        %   -> Any numeric in [0, tachoLimit] 
         smoothStart;
         
-        %smoothStop -  Degrees/Time for how far/long the motor should smoothly stop (depends on limitMode)
-        %   -> Any integer or double in [0, tachoLimit/2] 
+        %smoothStop -  Degrees/Time for how far/long the motor should smoothly stop (depends on tachoLimitMode)
+        %   -> Any numeric in [0, tachoLimit] 
         smoothStop;
         
-        %limitValue -  Degrees/Time for how far/long the motor should run (depends on limitMode)
-        %   -> Any integer or double >= 0 (in ms, if limitMode = 'Time')
-        limitValue;  
+        %tachoLimit -  Degrees/Time for how far/long the motor should run (depends on tachoLimitMode)
+        %   -> Any numeric >= 0 (in ms, if tachoLimitMode = 'Time')
+        tachoLimit;  
         
-        %brakeMode -  Mode for braking
-        %   -> 'Brake' / 'Coast'
-        brakeMode;  % Mode for braking: 'Brake' or 'Coast'
-        
-        %limitMode -  Mode for motor limit
+        %tachoLimitMode -  Mode for motor limit
         %   -> 'Tacho' / 'Time'
-        limitMode;
+        tachoLimitMode;
         
-        %mode -  Device mode at port, used as tacho mode (i.e. what tachoCount should return)
-        %   -> DeviceMode.Motor.Degrees / DeviceMode.Motor.Rotations 
-        %     (DeviceMode.Motor.Speed is also defined, but this is only used internally.)
-        mode;
+        %brakeMode -  Mode for braking
+        %   -> 'Brake' / 'Coast'
+        brakeMode;
         
         %debug -  Debug turned on or off
         % In debug mode, everytime a command is passed to the sublayer ('communication layer'),
         % there is feedback in the console about what command has been called, etc.
-        %   -> Any valid boolean (0/1/'on'/'off'/'true'/'false')
+        %   -> Any valid boolean (0/1/'on'/'off'/true/false) 
         debug;
     end
     
-    properties (Dependent)  % Parameters to be read directly from physical brick
-        tachoCount;  % Current tacho count (either in Degrees or Rotations)
-        speed;  % Current speed of motor (only valid with speedRegulation turned on)
-    end
-    
-    properties (SetAccess = 'protected')  % Read-only properties that are set internally or in init-phase      
-        %motorAtPort -  Is physical motor actually connected to port?
-        % This property will be changed by Motor.update() if changes have happened on the
-        % physical brick, depending on status, type and mode values.
-        % See also STATUS, TYPE, MODE, UPDATE
-        motorAtPort = 0;
-        
-        %brick -  Brick object from sublayer class Brick -> used as interface to the physical brick.
-        % See also BRICK
-        brick = 0;
-        
+    properties (SetAccess = 'private')
         %port -  Motor port
         % This is only the string representation of the motor port to work with.
         % Internally, either MotorPort-, MotorBitfield- or MotorInput-member will be used.
         %   -> 'A' / 'B' / 'C' / 'D'
-        port;
-        
-        %status -  Connection status at port
-        % This property will be changed by Motor.update() if changes have happened on the
-        % physical brick.
-        % See also CONNECTIONTYPE, UPDATE
-        status = DeviceMode.Error.Undefined;  
-        
-        %type -  Device type at port
-        % This property will be changed by Motor.update() if changes have happened on the
-        % physical brick.
-        % See also DEVICEMODE.ERROR, UPDATE
-        type = DeviceMode.Error.Undefined; 
+        port; 
     end
     
-    properties (Hidden, Access = 'protected')  % Hidden properties for internal use only 
-        init = 1;  % Indicates 'init-phase' (Set to 1 as long as constructor is running)
-        isConnected = 0;  % Does virtual motor-object have a valid brick-handle?
+    properties (Dependent)  % Read-only parameters to be read directly from physical brick
+        %isRunning -  True if motor is running (speed > 0)
+        isRunning; 
         
-        %% Equivalents for Motor.port and Motor.brakeMode in enumerations
-        % Port (obviously) & brakeMode are actual parameters on the brick. To avoid using string
-        % comparisons each time they are used, the corresponding values to the given strings
-        % are saved (hidden from the user).
-        port_;
-        brakeMode_; 
+        %tachoCount -  Current tacho count
+        tachoCount;
         
-        %% Indicator for changes which will be needed later on
-        changed = 0;  % Saves whether power and/or speed reg have been changed virtually without
-                      % updating the physical brick.
-        limitSetToZero = 0;  % See motor.start (2nd note) for more info.
+        %currentSpeed -  Current speed of motor (equals power if speedRegulation = true)
+        currentSpeed;
         
+        %type -  Type of connected device if any
+        % See also DEVICETYPE
+        type;
     end
     
-    properties (Hidden, Dependent, Access = 'protected')  % Hidden, dependent properties for internal use only
+    properties (Hidden, Access = 'private')  % Hidden properties for internal use only 
+        commInterface;  % Communication interface
+        
+        %% Hidden brick parameters
+        
+        % brakeMode is an actual parameter on the brick. To avoid inconsistencies with other
+        % modi and to prettify the output, a string representing it is saved. In order to avoid
+        % using string comparisons each time it is used, the corresponding value, that is going 
+        % to be sent, is saved (hidden from the user).
+        brakeMode_;
+        
+        %% Miscallenous flags
+        
+        connectedToBrick = false;  % Connection to physical Brick?
+        sendPowerOnNextStart = false;  % Indicates whether current power parameter should be sent 
+                                       % to the Brick right before starting it next time
+        sendPowerOnSet = true;  % Indicates whether power parameter should be sent to the Brick 
+                                % immediately after setting it
+        limitSetToZero = false;  % Indicates whether tachoLimit has been set to zero 
+                                 % (workaround for a bug, see motor.start, Note 2)
+        init = true;  % Indicates 'init-phase' (True as long as constructor is running)
+    end
+    
+    properties (Hidden, Dependent, Access = 'private')  % Hidden, dependent properties for internal use only
         portNo;  % Port number
         portInput;  % Port number for input functions
+        
+        isSynced;  % Is motor running in synced mode?
+        physicalMotorConnected;  % Physical motor connected to this port?
     end
     
     methods  % Standard methods
@@ -194,133 +149,7 @@ classdef Motor < handle
             %
             
             motor.setProperties(varargin{:});
-            motor.init = 0;
-        end
-
-        %% Connection
-        function connect(motor,brick)
-            %connect Connects Motor-object to physical brick.
-            %
-            % Notes:
-            %  * This method actually only saves a handle to a Brick-object which has been
-            %    created beforehand (probably by an EV3-object).
-            %
-            % Arguments
-            %  * brick: instance of Brick-class
-            %
-            % Examples (for use without EV3-class)
-            %  m = Motor();
-            %  brickInterface = Brick('ioType', 'usb');
-            %  m.connect(brickInterface);
-            %  % do stuff
-            %
-            
-            if motor.isConnected
-                if isBrickValid(motor.brick)
-                    error('Motor::connect: Motor-Object already has a brick handle.');
-                else
-                    warning(['Motor::connect: Motor.isConnected is set to ''True'', but ',...
-                             'brick handle is invalid. Deleting invalid handle and ' ,...
-                             'resetting Motor.isConnected now...']);
-                         
-                    motor.brick = 0;
-                    motor.isConnected = 0;
-                    
-                    error('Motor::connect: Disconnected due to internal error.');
-                end
-            end
-            
-            motor.brick = brick;
-            motor.isConnected = 1;
-            
-            if motor.debug
-               fprintf('(DEBUG) Motor-Object connected to brick handle.\n'); 
-            end
-            
-            motor.update();
-        end
-        
-        function disconnect(motor)
-            %disconnect Disconnects Motor-object from physical brick.
-            %
-            % Notes:
-            %  * As with Motor::connect, this method actually only sets the property, in which 
-            %    the handle to the Brick-class was stored, to 0.
-            %
-            % Examples (for use without EV3-class)
-            %  m = Motor();
-            %  brickInterface = Brick('ioType', 'usb');
-            %  m.connect(brickInterface);
-            %  % do stuff
-            %  m.disconnect();
-            %  brickInterface.delete(); % Actual disconnecting!!!
-            % 
-            
-%             if ~motor.isConnected
-%                 error('Motor::disconnect: No brick connected.');
-%             end
-            
-            motor.brick = 0; % Note: actual deleting is done in EV3::disconnect.
-            motor.isConnected = 0;
-            motor.motorAtPort = 0;
-            
-            motor.status = DeviceMode.Error.Undefined;
-            motor.type = DeviceMode.Error.Undefined;
-        end
-        
-        function update(motor)
-            %update Updates motor-object to current status at its port.
-            % The parameters type, status and mode, which fully represent any device that can
-            % be connected to the brick, will be updated by this method. Furthermore, update()
-            % concludes from these parameters if there is a physical motor currently connected
-            % to the port (Motor.motorAtPort).
-            %
-            % Examples
-            %  b = EV3(); 
-            %  b.connect('ioType', 'bt', 'serPort', '/dev/rfcomm0');
-            %  % Connect motor to port A (in 'real life')
-            %  b.motorA.power = 50;
-            %  b.motorA.start(); -> error, because virtual brick does not know about new motor
-            %  b.motorA.type -> outputs DeviceType.Error
-            %  b.motorA.update(); 
-            %  b.motorA.start(); -> no error
-            %  b.motorA.type -> output DeviceType.LargeMotor/DeviceType.MediumMotor
-            %  
-            if ~motor.isConnected
-                error(['Motor::update: Motor-Object not connected to brick handle.',...
-                    'You have to call motor.connect(brick) first!']);
-            end
-            
-            % Get current status at both ports
-            status = motor.getStatus();
-            [type, mode] = motor.getTypeMode();
-            
-            % Conclude if both physical motors are connected
-            motor.motorAtPort = 0;
-            if uint8(status) >= uint8(ConnectionType.OutputDumb) && ...
-                    uint8(status) <= uint8(ConnectionType.OutputTacho)  % Is status of motor valid?
-                if (type == DeviceType.MediumMotor || type == DeviceType.LargeMotor) % Is type of motor valid?
-                    if strcmp(class(mode), 'DeviceMode.Motor')  % Is mode of motor valid?
-                        motor.motorAtPort = 1;
-                    end
-                end
-            end
-                
-            % Set parameter
-            motor.status = status;
-            motor.type = type;
-            
-            if motor.mode ~= mode && strcmp(class(mode), 'DeviceMode.Motor')
-                if mode == DeviceMode.Motor.Speed
-                    mode = motor.mode;  % This trick prevents set.mode from throwing an error if
-                    % the physical motor's mode has internally been set to
-                    % DeviceMode.Motor.Speed
-                else
-                    warning(['Motor::update: Physical motor''s mode was not ',...
-                        'the specified one. Changing...']);
-                end
-            end
-            motor.mode = mode;
+            motor.init = false;
         end
         
         %% Brick functions
@@ -343,101 +172,260 @@ classdef Motor < handle
             %    However, this does not even work all the time. If motor does not
             %    start, call stop() and setPower() manually. :/
             % 
-            
-            if ~motor.isConnected
-                error(['Motor::start: Motor-Object not connected to brick handle.',...
-                       'You have to call motor.connect(brick) first!']);
-            elseif ~motor.motorAtPort
+            if ~motor.connectedToBrick
+                error(['Motor::start: Motor-Object not connected to comm handle.',...
+                       'You have to call motor.connect(commInterface) first!']);
+            elseif ~motor.physicalMotorConnected
                 error('Motor::start: No physical motor connected to Port %s',...
-                       motor.port);
+                       port2str('Motor', motor.port));
+            elseif motor.isRunning
+                error('Motor::start: Motor is already runnning!');
+            end
+            
+            if motor.isSynced
+                delete(motor.findprop('syncCache')); 
             end
             
             if motor.power == 0
                warning('Motor::start: Motor starting with power=0.'); 
             end
             
-            if motor.limitValue==0
-                if motor.changed || motor.limitSetToZero
-                    % See 2nd note
-                    motor.stop();
+            if motor.tachoLimit==0
+                if motor.sendPowerOnNextStart
+                    if motor.limitSetToZero
+                        motor.stop();
+                        motor.limitSetToZero = false;
+                    end
                     motor.setPower(motor.power);
-                    motor.limitSetToZero = 0;
                 end
                 
-                motor.brick.outputStart(0, motor.port_);
+                motor.commInterface.outputStart(0, motor.port);
                 
                 if motor.debug
-                    fprintf('(DEBUG) Motor::start: Called outputStart on Port %s\n', motor.port);
+                    fprintf('(DEBUG) Motor::start: Called outputStart on Port %s\n', port2str('Motor', motor.port));
                 end
             else
-                if motor.isRunning()
-                    error('Motor::start: Motor is already running.'); 
-                end
-                
-                if strcmpi(motor.limitMode, 'Tacho')
+                if strcmpi(motor.tachoLimitMode, 'Tacho')
                     if motor.speedRegulation
-                        motor.brick.outputStepSpeed(0, motor.port_, motor.power,...
-                            motor.smoothStart, motor.limitValue, motor.smoothStop,...
+                        motor.commInterface.outputStepSpeed(0, motor.port, motor.power,...
+                            motor.smoothStart, motor.tachoLimit, motor.smoothStop,...
                             motor.brakeMode_);
                         
                         if motor.debug
                             fprintf('(DEBUG) Motor::start: Called outputStepSpeed on Port %s\n',...
-                                    motor.port);
+                                    port2str('Motor', motor.port));
                         end
                     else
-                        motor.brick.outputStepPower(0, motor.port_, motor.power,...
-                            motor.smoothStart, motor.limitValue, motor.smoothStop,...
+                        motor.commInterface.outputStepPower(0, motor.port, motor.power,...
+                            motor.smoothStart, motor.tachoLimit, motor.smoothStop,...
                             motor.brakeMode_);
                         
                         if motor.debug
                             fprintf('(DEBUG) Motor::start: Called outputStepPower on Port %s\n',...
-                                    motor.port);
+                                    port2str('Motor', motor.port));
                         end
                     end
-                elseif strcmpi(motor.limitMode, 'Time')
+                elseif strcmpi(motor.tachoLimitMode, 'Time')
                     if motor.speedRegulation
-                        motor.brick.outputTimeSpeed(0, motor.port_, motor.power,...
-                            motor.smoothStart, motor.limitValue, motor.smoothStop,...
+                        motor.commInterface.outputTimeSpeed(0, motor.port, motor.power,...
+                            motor.smoothStart, motor.tachoLimit, motor.smoothStop,...
                             motor.brakeMode_);
                         
                         if motor.debug
                             fprintf('(DEBUG) Motor::start: Called outputTimeSpeed on Port %s\n',...
-                                    motor.port);
+                                    port2str('Motor', motor.port));
                         end
                     else
-                        motor.brick.outputTimePower(0, motor.port_, motor.power,...
-                            motor.smoothStart, motor.limitValue, motor.smoothStop,...
+                        motor.commInterface.outputTimePower(0, motor.port, motor.power,...
+                            motor.smoothStart, motor.tachoLimit, motor.smoothStop,...
                             motor.brakeMode_);
                         
                         if motor.debug
                             fprintf('(DEBUG) Motor::start: Called outputTimePower on Port %s\n',...
-                                    motor.port);
+                                    port2str('Motor', motor.port));
                         end
                     end
-                else
-                    % Note: After all the input parsing done in setProperties and set.limitMode
-                    %       this REALLY should not happen..
-                    error('Motor::start: Limit Mode not valid.');
                 end
-                
             end
         end
         
         function stop(motor)
             %stop Stops the motor. :)
             
-            if ~motor.isConnected
-                error(['Motor::stop: Motor-Object not connected to brick handle.',...
-                       'You have to call motor.connect(brick) first!']);
-            elseif ~motor.motorAtPort
+            if ~motor.connectedToBrick
+                error(['Motor::stop: Motor-Object not connected to comm handle.',...
+                       'You have to call motor.connect(commInterface) first!']);
+            elseif ~motor.physicalMotorConnected
                 error('Motor::stop: No physical motor connected to Port %s',...
-                       motor.port);
+                       port2str('Motor', motor.port));
+            elseif motor.isSynced && motor.isRunning
+                error(['Motor::stop: Motor is running synchronized with another motor. ' ,...
+                       'Use ''syncedStop'' on the ''master''-motor.']);
             end
             
-            motor.brick.outputStop(0, motor.port_, motor.brakeMode_);
+            motor.commInterface.outputStop(0, motor.port, motor.brakeMode_);
+            
+            if motor.debug
+                fprintf('(DEBUG) Motor::stop: Called outputStop on Port %s\n', port2str('Motor', motor.port));
+            end
+        end
+        
+        function syncedStart(motor, syncMotor, varargin)
+            %syncedStart Starts this motor synchronized with another
+            % This motor acts as a 'master', meaning that the synchronized control is done via
+            % it. When syncedStart is called, the master sets the slave's (syncMotor)
+            % properties to keep it consistent with the last parameters sent to the physical
+            % brick. So, for example, changing the power on the master motor will take effect
+            % on the slave as soon as this method is called. 
+            % The following parameters will be affected on the slave: power, brakeMode,
+            % tachoLimit, speedRegulation
+            %
+            % Arguments
+            %  * syncMotor (the other motor object to sync with)
+            %  * 'turnRatio', numeric in [-200,200]
+            %
+            % Notes
+            %  * Description of turn_ratio (Excerpt of Firmware-comments, in c_output.c): 
+            %    "Turn ratio is how tight you turn and to what direction you turn.
+            %     -> 0 value is moving straight forward
+            %     -> Negative values turn to the left
+            %     -> Positive values turn 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)"
+            %  * This is right now a pretty 'heavy' function, as it tests if both motors are
+            %    connected AND aren't running, wasting four commands, so keep that in mind
+            %
+            % Example
+            %   b = EV3(); b.connect('usb');
+            %   m = b.motorA;
+            %   m.power = 50;
+            %   m.syncedStart(b.motorB);
+            %   % Do stuff
+            %   m.syncedStop();
+            %
+            
+            turnRatio = 0;
+            
+            % Check parameters
+            if ~isDeviceValid('Motor', syncMotor)
+                error('Motor::syncedStart: Given motor to sync with is not a valid motor object.');
+            elseif ~isempty(varargin)
+                if length(varargin)~=2
+                    error(['Motor::syncedStart: Wrong number of input arguments. ' ,...
+                           'Possible input: ''turnRatio'', value (with value in [-200,200])']); 
+                end
+                parameter = varargin{1};
+                turnRatio = varargin{2};
+                if ~strcmpi(parameter, 'turnRatio') || ~isnumeric(turnRatio) || ...
+                        turnRatio<-200 || turnRatio > 200
+                    error(['Motor::syncedStart: Wrong format of input arguments. Possible ',...
+                           'input: ''turnRatio'', value (with value in [-200,200])']); 
+                end
+            end
+            
+            % Check connection and motor parameter
+            if ~motor.connectedToBrick || ~syncMotor.connectedToBrick
+                error(['Motor::syncedStart: Motor-Object not connected to comm handle.',...
+                    'You have to call motor.connect(commInterface) first!']);
+            elseif ~motor.physicalMotorConnected || ~syncMotor.physicalMotorConnected
+                error('Motor::syncedStart: No physical motor connected to Port %s or %s.',...
+                    port2str('Motor', motor.port), port2str('Motor', syncMotor.port));
+            elseif motor.speedRegulation
+                error(['Motor::syncedStart: Cannot run motors synchronized if ',...
+                    'speedRegulation is turned on.']);
+            elseif motor.isRunning || syncMotor.isRunning
+                error('Motor::syncedStart: One of the motors is already running!');
+            end
+            
+            if motor.power == 0
+                warning('Motor::syncedStart: Synchronized motors starting with power=0.');
+            end
+          
+            % Cache old values to make it possible to reset them on stopSynced
+            % Note: the existence of 'syncCache' is also used to determine whether motor is 
+            %       running synchronized or not, see get.isSynced()
+            if motor.isSynced
+                meta = motor.findprop('syncCache');
+            else
+                meta = motor.addprop('syncCache');
+                meta.Hidden = true;
+                meta.Access = 'private';
+            end
+
+            motor.syncCache.master_oldSendPowerOnSet = motor.sendPowerOnSet;
+            motor.syncCache.slave_oldSendPowerOnSet = syncMotor.sendPowerOnSet;
+            motor.syncCache.slave = syncMotor;
+            
+            % Disable immediate sending of new power values
+            motor.sendPowerOnSet = false;
+            syncMotor.sendPowerOnSet = false;
+            
+            % Keep 'slave'-motor synchronized
+            syncMotor.speedRegulation = false;
+        	syncMotor.tachoLimit = motor.tachoLimit;
+            syncMotor.brakeMode = motor.brakeMode;
+            syncMotor.power = motor.power;
+            
+            if strcmpi(motor.tachoLimitMode, 'Tacho')
+               motor.commInterface.outputStepSync(0, motor.port+syncMotor.port, ...
+                                              motor.power, turnRatio, ...
+                                              motor.tachoLimit, motor.brakeMode_);
+               if motor.debug
+                   fprintf(['(DEBUG) SyncMotor::syncedStart: Called outputStepSync on ' ,...
+                           'Ports %s and %s.\n'], port2str('Motor', motor.port), port2str('Motor', syncMotor.port));
+               end
+            elseif strcmpi(motor.tachoLimitMode, 'Time')
+                motor.commInterface.outputTimeSync(0, motor.port+syncMotor.port, ...
+                                              motor.power, turnRatio, ...
+                                              motor.tachoLimit, motor.brakeMode_); 
+               if motor.debug
+                   fprintf('(DEBUG) SyncMotor::start: Called outputStepSync on Ports %s and %s.\n',...
+                         port2str('Motor', motor.port), port2str('Motor', syncMotor.port));
+               end
+            end
+        end
+        
+        function syncedStop(motor)
+            %syncedStop Stops both motors previously started with syncedStart
+            % Obviously, if motors have not been started synchronized, this throws an error.
+            %
+            % See also MOTOR.SYNCEDSTART
+            %
+            
+            if ~motor.isSynced
+                error('Motor::syncedStop: Motor has not been started synchronized with another.');
+            end 
+            
+            % Retrieve synced motor from cache
+            syncMotor = motor.syncCache.slave;
+            
+            if ~motor.connectedToBrick || ~syncMotor.connectedToBrick
+                error(['Motor::syncedStop: Motor-Object not connected to comm handle.',...
+                    'You have to call motor.connect(commInterface) first!']);
+            elseif ~motor.physicalMotorConnected || ~syncMotor.physicalMotorConnected
+                error('Motor::syncedStop: No physical motor connected to either Port %s or %s.',...
+                    port2str('Motor', motor.port), port2str('Motor', syncMotor.port));
+            end
+            
+            % Retrieve other values from cache and delete it 
+            motor.sendPowerOnSet = motor.syncCache.master_oldSendPowerOnSet;
+            syncMotor.sendPowerOnSet = motor.syncCache.slave_oldSendPowerOnSet;
+            delete(motor.findprop('syncCache'));
+            
+            % Synced stopping
+            motor.commInterface.outputStop(0, motor.port+syncMotor.port, motor.brakeMode_);
+            
+            % On next start, both motors have to send power-opcode again
+            motor.sendPowerOnNextStart = true;
+            syncMotor.sendPowerOnNextStart = true;
             
             if motor.debug
-                fprintf('(DEBUG) Motor::stop: Called outputStop on Port %s\n', motor.port);
+                fprintf('(DEBUG) Motor::stop: Called outputStop on Ports %s and %s\n.', ...
+                    port2str('Motor', motor.port), port2str('Motor', syncMotor.port));
             end
         end
         
@@ -457,67 +445,46 @@ classdef Motor < handle
             %    long as not both OutputTest and OutputReady are buggy).
             %
             
-            if ~motor.isConnected
-                error(['Motor::waitFor: Motor-Object not connected to brick handle.',...
-                       'You have to call motor.connect(brick) first!']);
-            elseif ~motor.motorAtPort
+            if ~motor.connectedToBrick
+                error(['Motor::waitFor: Motor-Object not connected to comm handle.',...
+                       'You have to call motor.connect(commInterface) first!']);
+            elseif ~motor.physicalMotorConnected
                 error('Motor::waitFor: No physical motor connected to Port %s',...
-                       motor.port);
-            elseif ~motor.limitValue
-                error(['Motor::waitFor: Motor has no tacho limit. ' ,...
-                         'Can''t reliably determine whether it is running or not.']);
+                       port2str('Motor', motor.port));
             end
             
-            tic;
-            while 1
-                try
-                    warning('off','all');
-                    
-                    motor.brick.outputReady(0, motor.port_);
-                    t = toc;
-                    
-                    if t < 1
-                        while motor.isRunning()  % If outputReady correctly returned in less 
-                                                 % than a second, isRunning should instantly send 0.
-                        end
-                    end
-                    
-                    warning('on','all');
-                    break;
-                catch  % TO DO: Catch only timeout exception, otherwise death and destruction possible (aka infinite loop)
-                    continue;
-                end
-            end
-            
-            if motor.debug
-                fprintf('(DEBUG) Motor::waitFor: Called outputReady on Port %s\n', motor.port);
-            end
-        end
-        
-        function running = isRunning(motor)
-            %isRunning Returns whether motor is running (WITH TACHOLIMIT) or not.
-            %
-            % Notes:
-            %  * This *mostly* works. Sometimes this falsely returns 0 if isRunning() gets 
-            %    called immediately after starting the motor.
-            %
-            
-            if ~motor.isConnected
-                error(['Motor::isRunning: Motor-Object not connected to brick handle.',...
-                       'You have to call motor.connect(brick) first!']);
-            elseif ~motor.motorAtPort
-                error('Motor::isRunning: No physical motor connected to Port %s',...
-                       motor.port);
-            elseif ~motor.limitValue
-                warning(['Motor::isRunning: Motor has no tacho limit. ' ,...
-                         'Can''t reliably determine whether it is running or not.']);
-            end
-            
-            running = motor.brick.outputTest(0, motor.port_);
-            
-            if motor.debug
-                fprintf('(DEBUG) Motor::isRunning: Called outputReady on Port %s\n', motor.port);
+            while motor.isRunning
+                 pause(0.5);
             end
+%             elseif ~motor.tachoLimit
+%                 error(['Motor::waitFor: Motor has no tacho limit. ' ,...
+%                          'Can''t reliably determine whether it is running or not.']);
+%             end
+%             
+%             tic;
+%             while 1
+%                 try
+%                     warning('off','all');
+%                     
+%                     motor.commInterface.outputReady(0, motor.port);
+%                     t = toc;
+%                     
+%                     if t < 1
+%                         while motor.isRunning()  % If outputReady correctly returned in less 
+%                                                  % than a second, isRunning should instantly send 0.
+%                         end
+%                     end
+%                     
+%                     warning('on','all');
+%                     break;
+%                 catch  % TO DO: Catch only timeout exception, otherwise death and destruction possible (aka infinite loop)
+%                     continue;
+%                 end
+%             end
+%             
+%             if motor.debug
+%                 fprintf('(DEBUG) Motor::waitFor: Called outputReady on Port %s\n', motor.port);
+%             end
         end
 		
         function reset(motor)
@@ -528,100 +495,61 @@ classdef Motor < handle
             % physically change the motor's position.
             % See also MOTOR.RESETTACHOCOUNT
             
-            if ~motor.isConnected
+            if ~motor.connectedToBrick
                 error(['Motor::reset: Motor-Object not connected to brick handle.',...
                        'You have to call motor.connect(brick) first!']);
-            elseif ~motor.motorAtPort
+            elseif ~motor.physicalMotorConnected
                 error('Motor::reset: No physical motor connected to Port %s',...
-                       motor.port);
+                       port2str('Motor', motor.port));
             end
             
-            motor.brick.outputReset(0, motor.port_);
+            motor.commInterface.outputReset(0, motor.port);
             
             if motor.debug
                 fprintf('(DEBUG) Motor::reset: Called outputReset on Port %s\n',...
-                          motor.port);
+                          port2str('Motor', motor.port));
             end
         end
         
-        function togglePolarity(motor)
-            %togglePolarity Switches the direction in which the motor turns.
-            if ~motor.isConnected
-                error(['Motor::togglePolarity: Motor-Object not connected to brick handle.',...
-                       'You have to call motor.connect(brick) first!']);
-            elseif ~motor.motorAtPort
-                error('Motor::togglePolarity: No physical motor connected to Port %s',...
-                       motor.port);
+        function resetTachoCount(motor)
+            %resetTachoCount Resets tacho count to 0 if running without tacholimit
+            % Compared to motor.reset, this resets the 'sensor mode' tacho count, a second 
+            % tacho counter. This counter is used for reading the tacho count with inputRead 
+            % and outputGetCount (via motor.tachoCount).
+            % See also MOTOR.RESET
+            
+            if ~motor.connectedToBrick
+                error(['Motor::resetTachoCount: Motor-Object not connected to comm handle.',...
+                       'You have to call motor.connect(commInterface) first!']);
+            elseif ~motor.physicalMotorConnected
+                error('Motor::resetTachoCount: No physical motor connected to Port %s',...
+                       port2str('Motor', motor.port));
             end
             
-            motor.brick.outputPolarity(0, motor.port_, 0);
+            motor.commInterface.outputClrCount(0, motor.port);
+            
             if motor.debug
-                fprintf('(DEBUG) Motor::togglePolarity: Called outputPolarity on Port %s\n', motor.port);
+                fprintf('(DEBUG) Motor::resetTachoCount: Called outputClrCount on Port %s\n',...
+                          port2str('Motor', motor.port));
             end
         end
         
         %% Setter
-        function set.port(motor, port)
-            if ~isPortValid(class(motor),port)
-                error('Motor::set.port: Given port is not a valid port.');
-            end
-            
-            if ischar(port)
-                motor.port = port;
-                [motor.port_, ~, ~] = str2PortParam(class(motor), port);
-            else
-                error('Motor::set.port: Port has to be a string.');
-            end
-        end
-        
         function set.power(motor, power)
             if ~isnumeric(power)
                 error('Motor::set.power: Given parameter is not a numeric.');
             elseif power<-100 || power>100
                 warning('Motor::set.power: Motor power has to be an element of [-100,100]!');
                 error('Motor::set.power: Given motor power is out of bounds.');
-            elseif power == 0
-                if ~motor.init
-                    warning('Motor::set.power: Setting power to zero...');
-                end
-            elseif power == motor.power
-                warning('Motor::set.power: Motor power already is %d',power);
             end
             
             motor.power = power;  % Set power parameter.
-            motor.changed = 1;  % Indicate that virtual and physical brick have different power
+            motor.sendPowerOnNextStart = true;  % Indicate that virtual and physical brick have different power
                                 % parameters right now. See 'setPower' for more info.
-            motor.setPower(power); % Update physical brick's power parameter.
-        end
-        
-        function set.mode(motor, mode)
-            % Convert given mode to DeviceMode if necessary
-            if strcmp(class(mode), 'uint8') || strcmp(class(mode), 'double')
-                mode = DeviceMode(motor.type, uint8(mode));
-            end
             
-            if isModeValid(DeviceType.LargeMotor, mode)
-                if mode == DeviceMode.Motor.Speed
-                    error(['Motor::update: Physical motor''s mode has to be either ' ,...
-                        'DeviceMode.Motor.Degrees or DeviceMode.Motor.Rotations. ' ,...
-                        '(DeviceMode.Motor.Speed is for internal use only.']);
-                end
-                
-                % At this point, mode is a valid DeviceMode for Motor-objects.
-                
-                % If motor is currently not connected, allow changes
-                if strcmp(class(mode),'DeviceMode.Error') && ~motor.motorAtPort
-                    motor.mode = mode;
-                    return;
-                end
-                motor.mode = mode;
-                
-                if motor.isConnected && motor.motorAtPort
-                    motor.setMode(mode);
-                end
-            else
-                error(['Motor::update: Physical motor''s mode has to be either ' ,...
-                    'DeviceMode.Motor.Degrees or DeviceMode.Motor.Rotations.']);
+            if motor.sendPowerOnSet && motor.connectedToBrick && ... 
+                    motor.physicalMotorConnected
+                motor.setPower(power);  % Update physical brick's power parameter.
             end
         end
         
@@ -630,12 +558,8 @@ classdef Motor < handle
                 error('Motor::set.speedRegulation: Given parameter is not a bool.');
             end
             
-            if ischar(speedRegulation)
-                motor.speedRegulation = str2bool(speedRegulation);
-            else
-                motor.speedRegulation = speedRegulation;
-            end
-            motor.changed = 1;
+            motor.speedRegulation = str2bool(speedRegulation);
+            motor.sendPowerOnNextStart = true;
         end
         
         function set.smoothStart(motor, steps)
@@ -644,13 +568,11 @@ classdef Motor < handle
             elseif steps<0
                 warning('Motor::set.smoothStart: Smooth start steps have to be positive.');
                 error('Motor::set.smoothStart: Smooth start steps are out of bounds.');
-            elseif isempty(motor.limitValue)
-                warning(['Motor::set.smoothStart: Smooth start steps should be set after ',...
-                    'setting motor.limitValue. Setting smooth start steps to zero...']);
-                steps = 0;
-            elseif steps>motor.limitValue
-                error(['Motor::set.smoothStart: Smooth start steps are greater than ',...
-                    'actual limitValue.']);
+            end
+            
+            if ~isempty(motor.tachoLimit) && steps>motor.tachoLimit
+                warning(['Motor::set.smoothStart: Smooth start steps are greater than ',...
+                    'tachoLimit.']);
             end
             
             motor.smoothStart = steps;
@@ -662,33 +584,19 @@ classdef Motor < handle
             elseif steps<0
                 warning('Motor::set.smoothStop: Smooth stop steps have to be positive.');
                 error('Motor::set.smoothStop: Smooth stop steps are out of bounds.');
-            elseif isempty(motor.limitValue)
-                warning(['Motor::set.smoothStop: Smooth stop steps should be set after ',...
-                    'setting motor.limitValue. Setting smooth stop steps to zero...']);
-                steps = 0;
-            elseif steps>motor.limitValue
-                error(['Motor::set.smoothStop: Smooth stop steps (%d) are greater than ',...
-                    'actual limitValue (%d).'], steps, motor.limitValue);
             end
             
-            motor.smoothStop = steps;
-        end
-        
-        function set.debug(motor, debug)
-            if ~isBool(debug)
-                error('Motor::set.debug: Given parameter is not a bool.');
+            if ~isempty(motor.tachoLimit) && steps>motor.tachoLimit
+                error(['Motor::set.smoothStop: Smooth stop steps are greater than ',...
+                    'tachoLimit.']);
             end
             
-            if ischar(debug)
-                motor.debug = str2bool(debug);
-            else
-                motor.debug = debug;
-            end
+            motor.smoothStop = steps;
         end
     	
         function set.brakeMode(motor, brakeMode)
             validModes = {'Coast', 'Brake'};
-            if ~ischar(brakeMode) || ~any(validatestring(brakeMode, validModes))
+            if ~ischar(brakeMode) || ~ismember(brakeMode, validModes)
                 error('Motor::set.brakeMode: Given parameter is not a valid brake mode.');
             else 
                 motor.brakeMode = brakeMode;
@@ -696,127 +604,117 @@ classdef Motor < handle
             end
         end
         
-        function set.limitMode(motor, limitMode)
+        function set.tachoLimitMode(motor, tachoLimitMode)
             validModes = {'Time', 'Tacho'};
-            if ~ischar(limitMode) || ~any(validatestring(limitMode, validModes))
-                error('Motor::set.limitMode: Given parameter is not a valid limit mode.');
+            if ~ischar(tachoLimitMode) || ~ismember(tachoLimitMode, validModes)
+                error('Motor::set.tachoLimitMode: Given parameter is not a valid limit mode.');
             else 
-                motor.limitMode = limitMode;
+                motor.tachoLimitMode = tachoLimitMode;
+            end
+        end
+        
+        function set.tachoLimit(motor, tachoLimit)
+            if ~isnumeric(tachoLimit)
+                error('Motor::set.tachoLimit: Given parameter is not a numeric.');
+            elseif tachoLimit<0
+                warning('Motor::set.tachoLimit: tachoLimit has to be positive!');
+                error('Motor::set.tachoLimit: Given tachoLimit is out of bounds.');
+            elseif any(motor.tachoLimit) 
+                if tachoLimit==0 && motor.tachoLimit~=0
+                    motor.sendPowerOnNextStart = true;
+                    motor.limitSetToZero = true;
+                    motor.sendPowerOnSet = true;
+                elseif tachoLimit~=0 && motor.tachoLimit==0
+                    motor.sendPowerOnSet = false;
+                end
             end
+            
+            motor.tachoLimit = tachoLimit;
         end
         
-        function set.limitValue(motor, limitValue)
-            if ~isnumeric(limitValue)
-                error('Motor::set.limitValue: Given parameter is not a numeric.');
-            elseif limitValue<0
-                warning('Motor::set.limitValue: limitValue has to be positive!');
-                error('Motor::set.limitValue: Given limitValue is out of bounds.');
-            elseif any(motor.limitValue) 
-                if motor.limitValue~=0 && limitValue==0
-                    motor.limitSetToZero = 1;
-                end
+        function set.port(motor, port)
+            if ~isPortStrValid(class(motor), port)
+                error('Motor::set.port: Given parameter is not a valid port string.');
+            else 
+                motor.port = str2PortParam(class(motor), port);
             end
-            motor.limitValue = limitValue;
         end
         
-        function set.brick(motor, brick)
-            if ~isBrickValid(brick)
-                error('Motor::set.brick: Handle to brick not valid.');
+        function set.commInterface(motor, comm)
+            if ~isCommInterfaceValid(comm)
+                error('Motor::set.commInterface: Handle to commInterface not valid.');
             else
-                motor.brick = brick;
+                motor.commInterface = comm;
             end
         end
         
-        function set.tachoCount(motor, tachoCount)
-             if tachoCount~=0
-                 error('Motor::set.tachoCount: Cannot set the tachoCount to a value ~= 0.'); 
-             end
-             
-             motor.resetTachoCount();
+        function set.debug(motor, debug)
+            if ~isBool(debug)
+                error('Motor::set.debug: Given parameter is not a bool.');
+            end
+            
+            motor.debug = str2bool(debug);
         end
         
         function setProperties(motor, varargin)
             %setProperties Sets multiple Motor properties at once using MATLAB's inputParser.
             %
             % Arguments
-            %  * 'debug', 0/1/'on'/'off'/'true'/'false'
-            %  * 'smoothStart', integer or double in [0, tachoLimit/2] 
-            %  * 'smoothStop', integer or double in [0, tachoLimit/2] 
-            %  * 'speedRegulation', 0/1/'on'/'off'/'true'/'false'
+            %  * 'debug', bool
+            %  * 'smoothStart', numeric in [0, tachoLimit] 
+            %  * 'smoothStop', numeric in [0, tachoLimit] 
+            %  * 'speedRegulation', bool
             %  * 'brakeMode', 'Coast'/'Brake'
-            %  * 'limitMode', 'Time'/'Tacho'
-            %  * 'limit', integer or double > 0
-            %  * 'power', integer or double in [-100,100]
-            %  * 'mode', DeviceMode.Motor.Degrees/DeviceMode.Motor.Rotations
+            %  * 'tachoLimitMode', 'Time'/'Tacho'
+            %  * 'limit', numeric > 0
+            %  * 'power', numeric in  [-100,100]
             %  * 'batteryMode', 'Voltage'/'Percentage'
             %
             % Example
             %  b = EV3(); 
-            %  b.connect('ioType', 'bt', 'serPort', '/dev/rfcomm0');
+            %  b.connect('bt', 'serPort', '/dev/rfcomm0');
             %  b.motorA.setProperties('debug', 'on', 'power', 50, 'limit', 720, 'speedRegulation', 'on');
             %  % Instead of: b.motorA.debug = 'on'; 
             %  %             b.motorA.power = 50;
             %  %             b.motorA.limit = 720;
             %  %             b.motorA.speedRegulation = 'on';
             %
-            
             p = inputParser();
-            p.KeepUnmatched = 1;  % For possible use in SyncMotor::setProperties
+            p.KeepUnmatched = 1;
             
             % Set default values
             if motor.init
-                defaultSmoothStart = 0;
-                defaultSmoothStop = 0;
                 defaultDebug = 0;
                 defaultSpeedReg = 0;
                 defaultBrakeMode = 'Coast';
                 defaultLimitMode = 'Tacho';
                 defaultLimit = 0;
                 defaultPower = 0;
-                defaultMode = DeviceMode.Motor.Degrees;
+                defaultSmoothStart = 0;
+                defaultSmoothStop = 0;
             else
-                defaultSmoothStart = motor.smoothStart;
-                defaultSmoothStop = motor.smoothStop;
                 defaultDebug = motor.debug;
                 defaultSpeedReg = motor.speedRegulation;
                 defaultBrakeMode = motor.brakeMode;
-                defaultLimitMode = motor.limitMode;
-                defaultLimit = motor.limitValue;
+                defaultLimitMode = motor.tachoLimitMode;
+                defaultLimit = motor.tachoLimit;
                 defaultPower = motor.power;
-                defaultMode = motor.mode;
+                defaultSmoothStart = motor.smoothStart;
+                defaultSmoothStop = motor.smoothStop;
             end
             
-            % set valid values and save them in a cell array
-%             validBools = {num2str(0), num2str(1), 'off', 'on'};
-%             validBrakeModes = {num2str(BrakeMode.Coast), num2str(BrakeMode.Brake), 'Coast', 'Brake'};
-%             validPorts = {num2str(MotorBitfield.MotorA), num2str(MotorBitfield.MotorB),...
-%                           num2str(MotorBitfield.MotorC), num2str(MotorBitfield.MotorD),...
-%                           num2str(Device.MotorSync),...
-%                           'A', 'B', 'C', 'D'};
-%             validLimitModes = {'Time', 'Tacho'};
-            
-            % define anonymous functions that will return whether given value in varargin is 
-            % valid
-%             checkBools = @(x) any(validatestring(num2str(x),validBools));
-%             checkBrakeMode = @(x) any(validatestring(num2str(x),validBrakeModes));
-%             checkLimitMode = @(x) any(validatestring(x, validLimitModes));
-%             checkPorts = @(x) any(validatestring(num2str(x),validPorts));
-%             checkLimit = @(x) x>=0;
-%             checkPower = @(x) isnumeric(x) && x>=-100 && x<=100;
-            
             % Add parameter
             if motor.init
-                p.addRequired('port');%, checkPorts);
+                p.addRequired('port');
             end
-            p.addOptional('smoothStart', defaultSmoothStart);%, checkBools);
-            p.addOptional('smoothStop', defaultSmoothStop);%, checkBools);
-            p.addOptional('debug', defaultDebug);%, checkBools);
-            p.addOptional('speedRegulation', defaultSpeedReg);%, checkBools);
-            p.addOptional('brakeMode', defaultBrakeMode);%, checkBrakeMode);
-            p.addOptional('limitMode', defaultLimitMode);%, checkLimitMode);
-            p.addOptional('limitValue', defaultLimit);%, checkLimit);
-            p.addOptional('power', defaultPower);%, checkPower);
-            p.addOptional('mode', defaultMode);
+            p.addOptional('debug', defaultDebug);
+            p.addOptional('speedRegulation', defaultSpeedReg);
+            p.addOptional('brakeMode', defaultBrakeMode)
+            p.addOptional('tachoLimitMode', defaultLimitMode);
+            p.addOptional('tachoLimit', defaultLimit);
+            p.addOptional('power', defaultPower);
+            p.addOptional('smoothStart', defaultSmoothStart);
+            p.addOptional('smoothStop', defaultSmoothStop);
             
             % Parse...
             p.parse(varargin{:});
@@ -825,51 +723,70 @@ classdef Motor < handle
             if motor.init
                motor.port = p.Results.port; 
             end
-            motor.limitValue = p.Results.limitValue;
-            motor.limitMode = p.Results.limitMode;
-%             if ~motor.init && motor.power ~= p.Results.power  % To avoid unnecessary communication with physical brick
-%                 motor.power = p.Results.power;
-%             end
+            motor.tachoLimit = p.Results.tachoLimit;
+            motor.tachoLimitMode = p.Results.tachoLimitMode;
             motor.power = p.Results.power;
             motor.brakeMode = p.Results.brakeMode;
-            motor.smoothStart = p.Results.smoothStart;
-            motor.smoothStop = p.Results.smoothStop;
             motor.debug = p.Results.debug;
             motor.speedRegulation = p.Results.speedRegulation;
-            motor.mode = p.Results.mode;
+            motor.smoothStart = p.Results.smoothStart;
+            motor.smoothStop = p.Results.smoothStop;
         end
         
         %% Getter
         function portNo = get.portNo(motor)
-            portNo = motor.getPortNo();
+            portNo = bitfield2port(motor.port);
         end
         
         function portInput = get.portInput(motor)
-            portInput = motor.getPortInput();
+            portInput = bitfield2input(motor.port);
         end
         
         function cnt = get.tachoCount(motor)
-            if ~motor.isConnected || ~motor.motorAtPort
-                warning('Motor::get.tachoCount: Could not detect motor at port %s.', ...
-                         motor.port);
-                
-                cnt = 0;
-                return;
+            cnt = 0;
+            if motor.connectedToBrick
+                try
+                    cnt = motor.getTachoCount();
+                catch
+                    warning('Motor::get.tachoCount: Could not detect motor at port %s.', ...
+                        port2str('Motor', motor.port));
+                    return;
+                end
             end
-            
-            cnt = motor.getTachoCount();
         end
         
-        function speed = get.speed(motor)
-            if ~motor.isConnected || ~motor.motorAtPort
-                warning('Motor::get.tachoCount: Could not detect motor at port %s.', ...
-                         motor.port);
-                
-                speed = 0;
-                return;
+        function speed = get.currentSpeed(motor)
+            speed = 0;
+            if motor.connectedToBrick
+                try
+                    speed = motor.getSpeed();
+                catch
+                    warning('Motor::get.tachoCount: Could not detect motor at port %s.', ...
+                        port2str('Motor', motor.port));
+                    return;
+                end
             end
-            
-            speed = motor.getSpeed();
+        end
+        
+        function running = get.isRunning(motor)
+            running = motor.currentSpeed>0;
+        end
+        
+        function synced = get.isSynced(motor)
+            synced = (length(findprop(motor, 'syncCache'))==1); 
+        end
+        
+        function motorType = get.type(motor)
+            if motor.connectedToBrick
+                [motorType, ~] = motor.getTypeMode();
+            else
+                motorType = DeviceType.Unknown;
+            end
+        end
+        
+        function conn = get.physicalMotorConnected(motor)
+            currentType = motor.type;
+            conn = (currentType==DeviceType.MediumMotor || currentType==DeviceType.LargeMotor);
         end
         
         %% Display
@@ -880,9 +797,35 @@ classdef Motor < handle
         end
     end
     
-    methods (Access = 'protected')  % Private brick functions that are wrapped by dependent params
+    methods (Access = 'private')  % Private brick functions that are wrapped by dependent params
+        function running = getMotorStatus(motor)
+            %isRunning Returns whether motor is running (WITH TACHOLIMIT) or not.
+            %
+            % Notes:
+            %  * This *mostly* works. Sometimes this falsely returns 0 if isRunning() gets 
+            %    called immediately after starting the motor.
+            %
+            
+            if ~motor.connectedToBrick
+                error(['Motor::isRunning: Motor-Object not connected to comm handle.',...
+                       'You have to call motor.connect(commInterface) first!']);
+%             elseif ~motor.physicalMotorConnected
+%                 error('Motor::isRunning: No physical motor connected to Port %s',...
+%                        port2str('Motor', motor.port));
+            elseif ~motor.tachoLimit
+                warning(['Motor::isRunning: Motor has no tacho limit. ' ,...
+                         'Can''t reliably determine whether it is running or not.']);
+            end
+            
+            running = motor.commInterface.outputTest(0, motor.port);
+            
+            if motor.debug
+                fprintf('(DEBUG) Motor::isRunning: Called outputReady on Port %s\n', port2str('Motor', motor.port));
+            end
+        end
+        
         function setPower(motor, power)
-            %setPower Sets given power value on the physical brick.
+            %setPower Sets given power value on the physical Brick.
             %
             % Notes:
             %  * If motor is running with a limit, calling outputSpeed/outputPower, to
@@ -891,160 +834,176 @@ classdef Motor < handle
             %    with the new value instantly. However, this sometimes leads to unexpected behaviour.
             %    Therefore, if motor is running with a limit, setPower aborts with a warning.
             %
-            
-            if ~motor.isConnected || ~motor.motorAtPort
-                return;
+            if ~motor.connectedToBrick
+                error(['Motor::getTachoCount: Motor-Object not connected to comm handle.',...
+                       'You have to call motor.connect(commInterface) first!']);
+%             elseif ~motor.physicalMotorConnected
+%                 error('Motor::getTachoCount: No physical motor connected to Port %s',...
+%                        port2str('Motor', motor.port));
             end
             
-            if motor.limitValue~=0 && motor.isRunning()
+            if motor.tachoLimit~=0 && motor.isRunning
                 warning(['Motor::setPower: Can''t set power if motor is running with a ',...
                          'tacholimit. This would mess up the internal tacho state.']);
                 return;
             else
                 if motor.speedRegulation
-                    motor.brick.outputSpeed(0, motor.port_, power);
+                    motor.commInterface.outputSpeed(0, motor.port, power);
                     
                     if motor.debug
-                        fprintf('(DEBUG) Motor::setPower: Called outputSpeed on Port %s\n', motor.port);
+                        fprintf('(DEBUG) Motor::setPower: Called outputSpeed on Port %s\n', port2str('Motor', motor.port));
                     end
                 else
-                    motor.brick.outputPower(0, motor.port_, power);
+                    motor.commInterface.outputPower(0, motor.port, power);
                     
                     if motor.debug
-                        fprintf('(DEBUG) Motor::setPower: Called outputPower on Port %s\n', motor.port);
+                        fprintf('(DEBUG) Motor::setPower: Called outputPower on Port %s\n', port2str('Motor', motor.port));
                     end
                 end
             end
-            motor.changed = 0;
+            motor.sendPowerOnNextStart = false;
         end 
         
         function setMode(motor, mode)
-            if ~motor.isConnected || ~motor.motorAtPort
-                return;
+            if ~motor.connectedToBrick
+                error(['Motor::getTachoCount: Motor-Object not connected to comm handle.',...
+                       'You have to call motor.connect(commInterface) first!']);
+%             elseif ~motor.physicalMotorConnected
+%                 error('Motor::getTachoCount: No physical motor connected to Port %s',...
+%                        port2str('Motor', motor.port));
             end
             
-            motor.brick.inputReadSI(0, motor.portInput, mode);  % Reading a value implicitly 
+            motor.commInterface.inputReadSI(0, motor.portInput, mode);  % Reading a value implicitly 
                                                                    % sets the mode.
 
             if motor.debug
-                fprintf('(DEBUG) Motor::setMode: Called inputReadSI on input port %d\n',...
-                         uint8(motor.portInput));
+                fprintf('(DEBUG) Motor::setMode: Called inputReadSI on Port %s\n',...
+                         port2str('Motor', motor.port));
             end        
         end
         
-        function resetTachoCount(motor)
-            %resetTachoCount Resets tacho count to 0 if running without tacholimit
-            % Compared to motor.reset, this resets the 'sensor mode' tacho count, a second 
-            % tacho counter. This counter is used for reading the tacho count with inputRead 
-            % and outputGetCount (via motor.tachoCount).
-            % See also MOTOR.RESET
-            
-            if ~motor.isConnected || ~motor.motorAtPort
-                return;
-            end
-            
-            motor.brick.outputClrCount(0, motor.port_);
-            
-            if motor.debug
-                fprintf('(DEBUG) Motor::resetTachoCount: Called outputClrCount on Port %s\n',...
-                          motor.port);
-            end
-        end
-        
         function [type,mode] = getTypeMode(motor)
-            if ~motor.isConnected
-                error(['Motor::getTypeMode: Motor-Object not connected to brick handle.',...
-                       'You have to call motor.connect(brick) first!']);
+            if ~motor.connectedToBrick
+                error(['Motor::getTypeMode: Motor-Object not connected to comm handle.',...
+                       'You have to call motor.connect(commInterface) first!']);
             end
             
-            [typeNo,modeNo] = motor.brick.inputDeviceGetTypeMode(0, motor.portInput);
+            [typeNo,modeNo] = motor.commInterface.inputDeviceGetTypeMode(0, motor.portInput);
             type = DeviceType(typeNo);
             mode = DeviceMode(type,modeNo);
             
             if motor.debug
                 fprintf('(DEBUG) Motor::getTypeMode: Called inputDeviceGetTypeMode on Port %s\n',...
-                         motor.port);
+                         port2str('Motor', motor.port));
             end
         end
         
         function status = getStatus(motor)
-            if ~motor.isConnected
-                error(['Motor::getStatus: Motor-Object not connected to brick handle.',...
-                       'You have to call motor.connect(brick) first!']);
+            if ~motor.connectedToBrick
+                error(['Motor::getStatus: Motor-Object not connected to comm handle.',...
+                       'You have to call motor.connect(commInterface) first!']);
             end
             
-            statusNo = motor.brick.inputDeviceGetConnection(0, motor.portInput);
+            statusNo = motor.commInterface.inputDeviceGetConnection(0, motor.portInput);
             status = ConnectionType(statusNo);
             
             if motor.debug
                 fprintf('(DEBUG) Motor::getStatus: Called inputDeviceGetConnection on Port %s\n',...
-                         motor.port);
+                         port2str('Motor', motor.port));
             end
         end
         
         function cnt = getTachoCount(motor)
-            if ~motor.isConnected
-                error(['Motor::getTachoCount: Motor-Object not connected to brick handle.',...
-                       'You have to call motor.connect(brick) first!']);
-            elseif ~motor.motorAtPort
-                error('Motor::getTachoCount: No physical motor connected to Port %s',...
-                       motor.port);
+            if ~motor.connectedToBrick
+                error(['Motor::getTachoCount: Motor-Object not connected to comm handle.',...
+                       'You have to call motor.connect(commInterface) first!']);
+%             elseif ~motor.physicalMotorConnected
+%                 error('Motor::getTachoCount: No physical motor connected to Port %s',...
+%                        port2str('Motor', motor.port));
             end
             
-            if motor.mode == DeviceMode.Motor.Degrees
-                cnt = motor.brick.outputGetCount(0, motor.portNo);
-                if motor.debug
-                    fprintf('(DEBUG) Motor::getTachoCount: Called outputGetCount on Port %s\n', motor.port);
-                end
-            elseif motor.mode == DeviceMode.Motor.Rotations
-                cnt = motor.brick.inputReadSI(0, motor.portInput, motor.mode);
-                if motor.debug
-                    fprintf('(DEBUG) Motor::getTachoCount: Called inputReadSI on Port %s\n', motor.port);
-                end
-            else
-                error('Motor::getTachoCount: Motor mode not valid!');
+            cnt = motor.commInterface.outputGetCount(0, motor.portNo);
+            if motor.debug
+                fprintf('(DEBUG) Motor::getTachoCount: Called outputGetCount on Port %s\n', port2str('Motor', motor.port));
             end
         end
         
         function speed = getSpeed(motor)
-            if ~motor.isConnected
-                error(['Motor::getSpeed: Motor-Object not connected to brick handle.',...
-                       'You have to call motor.connect(brick) first!']);
-            elseif ~motor.motorAtPort
-                error('Motor::getSpeed: No physical motor connected to Port %s',...
-                       motor.port);
+            if ~motor.connectedToBrick
+                error(['Motor::getSpeed: Motor-Object not connected to comm handle.',...
+                       'You have to call motor.connect(commInterface) first!']);
+%             elseif ~motor.physicalMotorConnected
+%                 error('Motor::getSpeed: No physical motor connected to Port %s',...
+%                        port2str('Motor', motor.port));
             end
             
-            if ~motor.speedRegulation
-                warning('Motor::getSpeed: Speed only valid with speed regulation turned on.');
-            end
-            speed = motor.brick.inputReadSI(0, motor.portInput, DeviceMode.Motor.Speed);
+            speed = motor.commInterface.inputReadSI(0, motor.portInput, DeviceMode.Motor.Speed);
             
             if motor.debug
-                fprintf('(DEBUG) Motor::getSpeed: Called inputReadSI on Port %s\n', motor.port);
+                fprintf('(DEBUG) Motor::getSpeed: Called inputReadSI on Port %s\n', port2str('Motor', motor.port));
             end
         end
     end
     
-    methods (Hidden, Access = 'protected')  % Wrapper for utility functions, hidden from user
-        % These are overridden in SyncMotor so the 'right' utility function
-        % will always be called.
-        function portNo = getPortNo(motor)
-            if isempty(motor.port_)
-                error(['Motor::portNo: This method should only be called AFTER ',...
-                    'setting motor.port.']);
+    methods (Access = {?EV3})
+        function connect(motor,commInterface)
+            %connect Connects Motor-object to physical brick.
+            %
+            % Notes:
+            %  * This method actually only saves a handle to a Brick-object which has been
+            %    created beforehand (probably by an EV3-object).
+            %
+            % Arguments
+            %  * commInterface: instance of Brick-class
+            %
+            % Examples (for use without EV3-class)
+            %  m = Motor();
+            %  brickInterface = Brick('usb');
+            %  m.connect(brickInterface);
+            %  % do stuff
+            %
+            
+            if motor.connectedToBrick
+                if isCommInterfaceValid(motor.commInterface)
+                    error('Motor::connect: Motor-Object already has a comm handle.');
+                else
+                    warning(['Motor::connect: Motor.connectedToBrick is set to ''True'', but ',...
+                             'comm handle is invalid. Deleting invalid handle and ' ,...
+                             'resetting Motor.connectedToBrick now...']);
+                         
+                    motor.commInterface = 0;
+                    motor.connectedToBrick = false;
+                    
+                    error('Motor::connect: Disconnected due to internal error.');
+                end
             end
             
-            portNo = bitfield2port(motor.port_);
+            motor.commInterface = commInterface;
+            motor.connectedToBrick = true;
+            
+            if motor.debug
+               fprintf('(DEBUG) Motor-Object connected to comm handle.\n'); 
+            end
         end
         
-        function portInput = getPortInput(motor)
-            if isempty(motor.port_)
-               error(['Motor::portInput: This method should only be called AFTER ',... 
-                      'setting motor.port.']);
-            end
+        function disconnect(motor)
+            %disconnect Disconnects Motor-object from physical brick.
+            %
+            % Notes:
+            %  * As with Motor::connect, this method actually only sets the property, in which 
+            %    the handle to the Brick-class was stored, to 0.
+            %
+            % Examples (for use without EV3-class)
+            %  m = Motor();
+            %  brickInterface = Brick('usb');
+            %  m.connect(brickInterface);
+            %  % do stuff
+            %  m.disconnect();
+            %  brickInterface.delete(); % Actual disconnecting!!!
+            %   
             
-            portInput = port2input(motor.portNo);
+            motor.commInterface = 0; % Note: actual deleting is done in EV3::disconnect.
+            motor.connectedToBrick = false;
         end
     end
 end
diff --git a/source/MotorPort.m b/source/MotorPort.m
index c4e5386..a25cf54 100644
--- a/source/MotorPort.m
+++ b/source/MotorPort.m
@@ -5,5 +5,4 @@ classdef MotorPort < uint8
         MotorC (2)
         MotorD (3)
     end
-end
-
+end
\ No newline at end of file
diff --git a/source/Sensor.m b/source/Sensor.m
index fe0c983..33a531b 100644
--- a/source/Sensor.m
+++ b/source/Sensor.m
@@ -4,21 +4,18 @@ classdef Sensor < handle
     % Properties:
     %   Standard
     %       debug           - Debug mode turned on or off
-    %       mode            - Sensor mode in which the value will be read
+    %       mode            - Sensor mode in which the values will be read
     %   Dependent
     %       value           - Value read from sensor
-    %   get-only
-    %       isConnected     - Is virtual brick connected to physical one?
-    %       brick           - Brick object from sublayer class Brick -> used as interface to the physical brick.
+    %       type            - Type of connected sensor if any
     %
     % Methods:
     %   Standard
-    %       EV3             -
-    %       connect         - Connects Sensor-object to physical brick.
-    %       disconnect      - Disconnects Sensor-object from physical brick.
-    %       update          - Updates Sensor-object to current status at its port.
+    %       EV3             
+    %       connect         - Connects Sensor-object to physical brick
+    %       disconnect      - Disconnects Sensor-object from physical brick
     %       reset           - Resets value on sensor
-    %       setProperties   - Sets multiple Sensor properties at once using MATLAB's inputParser.
+    %       setProperties   - Sets multiple Sensor properties at once using MATLAB's inputParser
     %
     % Example
     %  % This small example should only roughly demonstrate how to work with sensors.
@@ -177,7 +174,7 @@ classdef Sensor < handle
             % Set default values
             if sensor.init
                 defaultDebug = 0;
-                defaultMode = DeviceMode.Error.Undefined;
+                defaultMode = DeviceMode.Default.Undefined;
             else
                 defaultDebug = sensor.debug;
                 defaultMode = sensor.mode;
@@ -203,15 +200,36 @@ classdef Sensor < handle
         
         %% Getter
         function value = get.value(sensor)
-            if ~sensor.isConnected || ~sensor.sensorAtPort
-                warning('Sensor::get.value: Could not detect sensor at port %s.', ...
-                         sensor.port);
-                
-                value = 0;
+            value = 0;
+            if strcmp(class(sensor.mode), 'DeviceMode.Default') || ... 
+                    ~isModeValid(sensor.mode, sensor.type)
+                warning('Sensor::get.value: Cannot read sensor values in current mode.'); 
                 return;
             end
             
-            value = sensor.getValue();
+            if sensor.connectedToBrick
+                try
+                    value = sensor.getValue();
+                catch
+                    warning('Sensor::get.value: Could not detect sensor at port %d.', ...
+                        sensor.port+1);
+                    return;
+                end
+            end
+        end
+        
+        function conn = get.physicalSensorConnected(sensor)
+            currentType = sensor.type;
+            conn = (currentType<DeviceType.Unknown && ... 
+                (currentType~=DeviceType.MediumMotor && currentType~=DeviceType.LargeMotor));
+        end
+        
+        function sensorType = get.type(sensor)
+            if sensor.connectedToBrick
+                [sensorType, ~] = sensor.getTypeMode(); 
+            else
+                sensorType = DeviceType.Unknown;
+            end
         end
         
         %% Display
@@ -224,16 +242,20 @@ classdef Sensor < handle
     
     methods (Access = 'private')  % Private brick functions that are wrapped by dependent params
         function setMode(sensor, mode)
-            if ~sensor.isConnected || ~sensor.sensorAtPort
-                return
+            if ~sensor.connectedToBrick
+                error(['Sensor::getTachoCount: Sensor-Object not connected to comm handle.',...
+                       'You have to call sensor.connect(commInterface) first!']);
+%             elseif ~sensor.physicalSensorConnected
+%                 error('Sensor::getTachoCount: No physical sensor connected to Port %d',...
+%                        sensor.port+1);
             end
             
-            sensor.brick.inputReadSI(0, sensor.port_, mode);  % Reading a value implicitly
-                                                              % sets the mode.
+            sensor.commInterface.inputReadSI(0, sensor.port, mode);  % Reading a value implicitly
+                                                             % sets the mode.
             
             if sensor.debug
-                fprintf('(DEBUG) Sensor::setMode: Called inputReadSI on Port %s\n',...
-                    sensor.port);
+                fprintf('(DEBUG) Sensor::setMode: Called inputReadSI on Port %d.\n',...
+                    sensor.port+1);
             end
         end
         
@@ -245,15 +267,15 @@ classdef Sensor < handle
             %    this case, the inputReadSI-opCode is sent again to get the correct value.
             %
             
-            if ~sensor.isConnected
-                error(['Sensor::getValue: Sensor-Object not connected to brick handle.',...
-                       'You have to call sensor.connect(brick) first!']);
-            elseif ~sensor.sensorAtPort
-                error('Sensor::getValue: No physical sensor connected to Port %d.',...
-                       sensor.port);
+            if ~sensor.connectedToBrick
+                error(['Sensor::getValue: Sensor-Object not connected to comm handle.',...
+                       'You have to call sensor.connect(commInterface) first!']);
+%             elseif ~sensor.physicalSensorConnected
+%                 error('Sensor::getValue: No physical sensor connected to Port %d.',...
+%                        sensor.port+1);
             end
             
-            val = sensor.brick.inputReadSI(0, sensor.port_, sensor.mode);
+            val = sensor.commInterface.inputReadSI(0, sensor.port, sensor.mode);
             
             if strcmp(class(sensor.mode), 'DeviceMode.Color')
                 if sensor.mode == DeviceMode.Color.Col
-- 
GitLab