www.gusucode.com > Arduino_Engineering_Kit_Hardware_Support_18b 工具箱matlab源码程序 > Arduino_Engineering_Kit_Hardware_Support_18b/matlab/MATLABAddon/+arduinoioaddons/+arduino/MKRDCMotor.m
classdef MKRDCMotor < arduinoio.MotorBase & matlab.mixin.CustomDisplay %MKRDCMotor Create a MKR DC motor device object. % Copyright 2018 The MathWorks, Inc. properties DutyCycle = 0 end properties(Hidden) PWMFrequency = 100 end properties (Dependent = true, Access = private) ConvertedDutyCycle end properties (SetAccess = private) IsRunning = false; end properties(Access = private) ResourceOwner = 'MKRMotorCarrier\DCMotor'; MinPWMFrequency = 100 MaxPWMFrequency = 10000 end properties(Access = private, Constant = true) % MATLAB defined command IDs CREATE_DC_MOTOR = hex2dec('02') START_DC_MOTOR = hex2dec('03') STOP_DC_MOTOR = hex2dec('04') SET_DUTYCYCLE_DC_MOTOR = hex2dec('05') SET_DCM_VELOCITY = hex2dec('13') SET_DCM_POSITION = hex2dec('14') end properties(Access = private, Constant = true) ROTATE_FORWARD = 1 ROTATE_BACKWARD = 2 end properties(Access = private, Constant = true) MaxDCMotors = 4 ResourceMode = 'MKRMotorCarrier\DCMotor'; end %% Constructor methods(Hidden, Access = public) function obj = MKRDCMotor(parentObj, motorNumber, varargin) obj.Pins = []; obj.Parent = parentObj; arduinoObj = parentObj.Parent; try if (nargin < 2) obj.localizedError('MATLAB:minrhs'); end catch e throwAsCaller(e); end motorNumber = arduinoio.internal.validateIntParameterRanged(... [obj.ResourceOwner 'MotorNumber'], ... motorNumber, ... 1, ... obj.MaxDCMotors); try dcmotors = getSharedResourceProperty(arduinoObj, obj.ResourceOwner, 'dcmotors'); catch locDC = 1; %#ok<NASGU> dcmotors = [parentObj.I2CAddress zeros(1, obj.MaxDCMotors)]; end carrierDCAddresses = dcmotors(:, 1); [~, locDC] = ismember(parentObj.I2CAddress, carrierDCAddresses); if locDC == 0 dcmotors = [dcmotors; parentObj.I2CAddress zeros(1, obj.MaxDCMotors)]; locDC = size(dcmotors, 1); end % Check for resource conflict with DC Motors if dcmotors(locDC, motorNumber+1) error('Arduino:MKRMotorCarrier:conflictDCMotorMKR', 'ArduinoMKRMotorCarrier\\\\DCMotor ''M%d'' is already in use', motorNumber); end dcmotors(locDC, motorNumber+1) = 1; setSharedResourceProperty(arduinoObj, obj.ResourceOwner, 'dcmotors', dcmotors); obj.MotorNumber = motorNumber; try p = inputParser; addParameter(p, 'DutyCycle', 0); addParameter(p, 'PWMFrequency', 100); parse(p, varargin{:}); catch obj.localizedError('MATLAB:arduinoio:general:invalidNVPropertyName',... obj.ResourceOwner, ... arduinoio.internal.renderCellArrayOfCharVectorsToCharVector(p.Parameters, ', ')); end obj.DutyCycle = p.Results.DutyCycle; obj.PWMFrequency = p.Results.PWMFrequency; obj.PWMFrequency = arduinoio.internal.validateDoubleParameterRanged(... 'ArduinoMKRMotorCarrier\DCMotor PWMFrequency', obj.PWMFrequency, 100, 10000); createDCMotor(obj); end end %% methods function start(obj) % Start the DC motor. % % Syntax: % start(dev) % % Description: % Start the DC motor so that it can rotate if DutyCycle is non-zero % % Example: % a = arduino('COM7', 'Uno', 'Libraries', 'Arduino/MKRMotorCarrier'); % mcObj = addon(a, 'Arduino/MKRMotorCarrier'); % dcm = dcmotor(mcObj,1,'DutyCycle',0.3); % start(dcm); % % Input Arguments: % dcm - DC motor device % % See also stop try if obj.IsRunning == false if obj.DutyCycle ~= 0 startDCMotor(obj); end obj.IsRunning = true; else obj.localizedWarning('MATLAB:arduinoio:general:dcmotorAlreadyRunning', num2str(obj.MotorNumber)); end catch e throwAsCaller(e); end end function stop(obj) % Stop the DC motor. % % Syntax: % stop(dev) % % Description: % Stop the DC motor if it has been started % % Example: % a = arduino('COM7', 'Uno', 'Libraries', 'Arduino/MKRMotorCarrier'); % mcObj = addon(a, 'Arduino/MKRMotorCarrier'); % dcm = dcmotor(mcObj,1,'DutyCycle',0.3); % start(dcm); % stop(dcm); % % Input Arguments: % dcm - DC motor device % % See also start try if obj.IsRunning == true stopDCMotor(obj); obj.IsRunning = false; end catch e throwAsCaller(e); end end function set.DutyCycle(obj, DutyCycle) % Valid DutyCycle range is -1 to 1 try if (nargin < 2) obj.localizedError('MATLAB:minrhs'); end DutyCycle = arduinoio.internal.validateDoubleParameterRanged(... 'ArduinoMKRMotorCarrier\DCMotor DutyCycle', DutyCycle, -1, 1); if DutyCycle == -0 DutyCycle = 0; end if obj.IsRunning == true %#ok<MCSUP> convertedDutyCycle = round(DutyCycle*100); setDutyCycleDCMotor(obj, convertedDutyCycle); end obj.DutyCycle = DutyCycle; catch e throwAsCaller(e); end end function setPosition(obj, position) try if (obj.MotorNumber > 2) error('Arduino:MKRMotorCarrier:InvalidPIDMotor', 'Invalid motor ''M%d'' for PID control. Valid motors are M1 and M2', obj.MotorNumber); end if(obj.Parent.EncoderExists(obj.MotorNumber)) if (nargin < 2) obj.localizedError('MATLAB:minrhs'); end position = arduinoio.internal.validateIntParameterRanged(... 'ArduinoMKRMotorCarrier\DCMotor Position', position, -2^15,2^15-1); if obj.IsRunning == true if obj.DutyCycle ~= 0 obj.DutyCycle = 0; sWarningBacktrace = warning('off', 'backtrace'); warning('Arduino:MKRMotorCarrier:DutyCycleUpdated', 'ArduinoMKRMotorCarrier\\\\ ''M%d'' DutyCycle set to 0', obj.MotorNumber); warning(sWarningBacktrace.state, 'backtrace'); end setPositionDCMotor(obj, position); end else error('Arduino:MKRMotorCarrier:EncoderObjectAbsent', 'Create ArduinoMKRMotorCarrier\\\\ ''Encoder%d'' object to run DCMotor ''M%d'' in PID control mode', obj.MotorNumber, obj.MotorNumber); end catch e throwAsCaller(e); end end function setSpeed(obj, speed) try if (obj.MotorNumber > 2) error('Arduino:MKRMotorCarrier:InvalidPIDMotor', 'Invalid motor ''M%d'' for PID control. Valid motors are M1 and M2', obj.MotorNumber); end if(obj.Parent.EncoderExists(obj.MotorNumber)) if (nargin < 2) obj.localizedError('MATLAB:minrhs'); end speed = arduinoio.internal.validateIntParameterRanged(... 'ArduinoMKRMotorCarrier\DCMotor Velocity', speed, -250,250); % raw values supported only between -50 - 50 speed = (speed * 1200)/(100 * 60); % convert RPM to counts per centisecond. 1200 is the pulse per rev of the encoder shaft if obj.IsRunning == true if obj.DutyCycle ~= 0 obj.DutyCycle = 0; sWarningBacktrace = warning('off', 'backtrace'); warning('Arduino:MKRMotorCarrier:DutyCycleUpdated', 'ArduinoMKRMotorCarrier\\\\ ''M%d'' DutyCycle set to 0', obj.MotorNumber); warning(sWarningBacktrace.state, 'backtrace'); end setSpeedDCMotor(obj,speed); end else error('Arduino:MKRMotorCarrier:EncoderObjectAbsent', 'Create ArduinoMKRMotorCarrier\\\\ ''Encoder%d'' object to run DCMotor ''M%d'' in PID control mode', obj.MotorNumber, obj.MotorNumber); end catch e throwAsCaller(e); end end function out = get.ConvertedDutyCycle(obj) % Convert DutyCycle from range [-1, 1] to [-100 100] as required by motorCarrier out = round(obj.DutyCycle * 100); end end %% Destructor methods (Access=protected) function delete(obj) originalState = warning('off','MATLAB:class:DestructorError'); try parentObj = obj.Parent; arduinoObj = parentObj.Parent; % Clear the DC Motor if ~isempty(obj.MotorNumber) stopDCMotor(obj); end dcmotors = getSharedResourceProperty(arduinoObj, obj.ResourceOwner, 'dcmotors'); carrierDCAddresses = dcmotors(:, 1); [~, locDC] = ismember(parentObj.I2CAddress, carrierDCAddresses); dcmotors(locDC, obj.MotorNumber+1) = 0; setSharedResourceProperty(arduinoObj, obj.ResourceOwner, 'dcmotors', dcmotors); catch % Do not throw errors on destroy. % This may result from an incomplete construction. end warning(originalState.state, 'MATLAB:class:DestructorError'); end end %% Private methods methods (Access = private) function createDCMotor(obj) commandID = obj.CREATE_DC_MOTOR; params = [obj.PWMFrequency]; sendCommand(obj, commandID, params); end function startDCMotor(obj) commandID = obj.START_DC_MOTOR; dutycycle = (obj.ConvertedDutyCycle); params = typecast(int16(dutycycle),'uint8'); sendCommand(obj, commandID, params'); end function stopDCMotor(obj) commandID = obj.STOP_DC_MOTOR; params = []; sendCommand(obj, commandID, params); end function setDutyCycleDCMotor(obj, DutyCycle) commandID = obj.SET_DUTYCYCLE_DC_MOTOR; params = typecast(int16(DutyCycle),'uint8'); sendCommand(obj, commandID, params'); end function setSpeedDCMotor(obj, speed) commandID = obj.SET_DCM_VELOCITY; params = typecast(int16(speed),'uint8'); sendCommand(obj, commandID, params'); end function setPositionDCMotor(obj, position) commandID = obj.SET_DCM_POSITION; params = typecast(int16(position),'uint8'); sendCommand(obj, commandID, params'); end end %% Protected methods methods(Access = protected) function output = sendCommand(obj, commandID, params) params = [obj.MotorNumber - 1; params]; output = sendCarrierCommand(obj.Parent, commandID, params); end end %% Protected methods methods (Access = protected) function displayScalarObject(obj) header = getHeader(obj); disp(header); % Display main options fprintf(' MotorNumber: %d (M%d)\n', obj.MotorNumber, obj.MotorNumber); fprintf(' DutyCycle: %-15.2f\n', obj.DutyCycle); fprintf(' IsRunning: %-15d\n', obj.IsRunning); fprintf('\n'); % Allow for the possibility of a footer. footer = getFooter(obj); if ~isempty(footer) disp(footer); end end end end